ungureanuvladvictor

Untitled

Feb 19th, 2014
223
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.55 KB | None | 0 0
  1. #include "../includes/dns.h"
  2.  
  3. u_char* ReadName(unsigned char* reader,unsigned char* buffer,int* count)
  4. {
  5. unsigned char *name;
  6. unsigned int p=0,jumped=0,offset;
  7. int i , j;
  8.  
  9. *count = 1;
  10. name = (unsigned char*)malloc(256);
  11.  
  12. name[0]='\0';
  13.  
  14. //read the names in 3www6google3com format
  15. while(*reader!=0)
  16. {
  17. if(*reader>=192)
  18. {
  19. offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 ;)
  20. reader = buffer + offset - 1;
  21. jumped = 1; //we have jumped to another location so counting wont go up!
  22. }
  23. else
  24. {
  25. name[p++]=*reader;
  26. }
  27.  
  28. reader = reader+1;
  29.  
  30. if(jumped==0)
  31. {
  32. *count = *count + 1; //if we havent jumped to another location then we can count up
  33. }
  34. }
  35.  
  36. name[p]='\0'; //string complete
  37. if(jumped==1)
  38. {
  39. *count = *count + 1; //number of steps we actually moved forward in the packet
  40. }
  41.  
  42. //now convert 3www6google3com0 to www.google.com
  43. for(i=0;i<(int)strlen((const char*)name);i++)
  44. {
  45. p=name[i];
  46. for(j=0;j<(int)p;j++)
  47. {
  48. name[i]=name[i+1];
  49. i=i+1;
  50. }
  51. name[i]='.';
  52. }
  53. name[i-1]='\0'; //remove the last dot
  54. return name;
  55. }
  56.  
  57. void parse_dns_header(struct DNS_HEADER *dns) {
  58. printf("\nDNS HEADER:\n");
  59. printf("id: %d\n \
  60. rd: %d\n \
  61. tc: %d\n \
  62. aa: %d\n \
  63. opcode: %d\n \
  64. qr: %d\n \
  65. rcode: %d\n \
  66. cd: %d\n \
  67. ad: %d\n \
  68. z: %d\n \
  69. ra: %d\n \
  70. q_count: %d\n \
  71. ans_count: %d\n \
  72. auth_count: %d\n \
  73. add_count: %d\n", ntohs(dns->id), ntohs(dns->rd), ntohs(dns->tc),
  74. ntohs(dns->aa), ntohs(dns->opcode), ntohs(dns->qr),
  75. ntohs(dns->rcode), ntohs(dns->cd), ntohs(dns->ad),
  76. ntohs(dns->z), ntohs(dns->ra), ntohs(dns->q_count),
  77. ntohs(dns->ans_count), ntohs(dns->auth_count),
  78. ntohs(dns->add_count));
  79. }
  80.  
  81. char *parse_query(char *q) {
  82. //char *location = q;
  83. char *name = NULL;
  84. int l = 0;
  85. int i, j;
  86.  
  87. name = (char*)calloc(512, sizeof(char));
  88. if (name == NULL) {
  89. exit(1);
  90. }
  91.  
  92. while(*q != 0) {
  93. name[l] = *q;
  94. l++;
  95. q++;
  96. }
  97. q++;
  98.  
  99. for(i = 0; i < l; i++) {
  100. int p = name[i];
  101. for(j = 0; j < (int)p; j++) {
  102. name[i] = name[i + 1];
  103. i++;
  104. }
  105. name[i] = '.';
  106. }
  107. name[i - 1] = '\0';
  108.  
  109.  
  110. struct QUESTION *qinfo = (struct QUESTION*)q;
  111. hexDump("Q", qinfo, sizeof(struct QUESTION));
  112. int type = ntohs(qinfo->qtype);
  113. int class = ntohs(qinfo->qclass);
  114. printf("Query name: %s\n", name);
  115. printf("Query type: %d\n", type);
  116. printf("Query class: %d\n\n", class);
  117.  
  118. free(name);
  119.  
  120. q += 4;
  121.  
  122. return q;
  123. }
  124.  
  125. char *parse_rr(struct RES_RECORD* rr) {
  126. char *name = NULL;
  127. char *data = NULL;
  128. char *location = (char*)rr;
  129. char *loc = location;
  130. int l = 0;
  131. int i, j;
  132. int data_len, rr_type;
  133.  
  134. name = (char*)calloc(512, sizeof(char));
  135. if (name == NULL) {
  136. exit(1);
  137. }
  138.  
  139. while(*location != 0) {
  140. name[l] = *location;
  141. l++;
  142. location++;
  143. }
  144. location++;
  145.  
  146. for(i = 0; i < l; i++) {
  147. int p = name[i];
  148. for(j = 0; j < (int)p; j++) {
  149. name[i] = name[i + 1];
  150. i++;
  151. }
  152. name[i] = '.';
  153. }
  154. name[i - 1] = '\0';
  155.  
  156. printf("Name of record: %s\n", name);
  157.  
  158. free(name);
  159.  
  160. struct R_DATA *rdata = (struct R_DATA*)location;
  161.  
  162. printf("type: %d\n", ntohs(rdata->type));
  163. printf("_class: %d\n", ntohs(rdata->_class));
  164. printf("ttl: %d\n", ntohl(rdata->ttl));
  165. printf("rdata_len: %d\n", ntohs(rdata->data_len));
  166.  
  167. data_len = ntohs(rdata->data_len);
  168. rr_type = ntohs(rdata->type);
  169.  
  170. location += sizeof(struct R_DATA);
  171. //location -= 1;
  172.  
  173. struct sockaddr_in ipv4;
  174. struct sockaddr_in6 ipv6;
  175. long *p;
  176. switch (rr_type) {
  177. case A:
  178. p = (long*)location;
  179. ipv4.sin_addr.s_addr = (*p);
  180. printf("has IPv4 address : %s", inet_ntoa(ipv4.sin_addr));
  181. break;
  182. case AAAA:
  183. /*p = (long*)data;
  184. ipv6.sin6_addr.s6_addr = (*p);
  185. printf("has IPv6 address : %s", inet_ntop(ipv6.sin6_addr));*/
  186. hexDump("ipv6", location, 16);
  187. break;
  188. case PTR:
  189. printf("PTR\n");
  190. break;
  191. case TXT:
  192. printf("TXT\n");
  193. break;
  194. case SRV:
  195. break;
  196. case ANY:
  197. break;
  198. case OTP:
  199. printf("It's an OTP rr!\n");
  200. break;
  201. default:
  202. break;
  203. }
  204. location += data_len;
  205. return location;
  206. }
  207.  
  208. /*u_char* ReadName(char* reader, char* buffer, int* count) {
  209. unsigned char *name;
  210. unsigned int p = 0, jumped = 0;
  211. int i , j;
  212.  
  213. *count = 1;
  214. name = (unsigned char*)malloc(256);
  215.  
  216. name[0]='\0';
  217.  
  218. //read the names in 3www6google3com format
  219. while(*reader!=0) {
  220. name[p++]=*reader;
  221. reader = reader+1;
  222.  
  223. if(jumped == 0) {
  224. *count = *count + 1; //if we havent jumped to another location then we can count up
  225. }
  226. }
  227.  
  228. name[p]='\0'; //string complete
  229. if(jumped==1) {
  230. *count = *count + 1; //number of steps we actually moved forward in the packet
  231. }
  232.  
  233. //now convert 3www6google3com0 to www.google.com
  234. for(i = 0; i < (int)strlen((const char*)name); i++) {
  235. p=name[i];
  236. for(j = 0; j < (int)p; j++) {
  237. name[i] = name[i+1];
  238. i = i+1;
  239. }
  240. name[i] = '.';
  241. }
  242. name[i - 1] = '\0'; //remove the last dot
  243. return name;
  244. }*/
  245.  
  246. void parse(char *buf, int len) {
  247. unsigned char buf[65536],*qname,*reader;
  248.     int i , j , stop , s;
  249.  
  250.     struct sockaddr_in a;
  251.  
  252.     struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
  253.     struct sockaddr_in dest;
  254.  
  255.     struct DNS_HEADER *dns = NULL;
  256.     struct QUESTION *qinfo = NULL;
  257.  
  258.     printf("Resolving %s" , host);
  259.     stop=0;
  260.     
  261.     dns = (struct DNS_HEADER *)&buf;
  262.  
  263.     qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];
  264.  
  265.     dns = (struct DNS_HEADER*) buf;
  266.  
  267.     //move ahead of the dns header and the query field
  268.     reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];
  269.  
  270.     printf("\nThe response contains : ");
  271.     printf("\n %d Questions.",ntohs(dns->q_count));
  272.     printf("\n %d Answers.",ntohs(dns->ans_count));
  273.     printf("\n %d Authoritative Servers.",ntohs(dns->auth_count));
  274.     printf("\n %d Additional records.\n\n",ntohs(dns->add_count));
  275.  
  276.     //Start reading answers
  277.     
  278.  
  279.     for(i=0;i<ntohs(dns->ans_count);i++)
  280.     {
  281.         answers[i].name=ReadName(reader,buf,&stop);
  282.         reader = reader + stop;
  283.  
  284.         answers[i].resource = (struct R_DATA*)(reader);
  285.         reader = reader + sizeof(struct R_DATA);
  286.  
  287.         if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
  288.         {
  289.             answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));
  290.  
  291.             for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++)
  292.             {
  293.                 answers[i].rdata[j]=reader[j];
  294.             }
  295.  
  296.             answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
  297.  
  298.             reader = reader + ntohs(answers[i].resource->data_len);
  299.         }
  300.         else
  301.         {
  302.             answers[i].rdata = ReadName(reader,buf,&stop);
  303.             reader = reader + stop;
  304.         }
  305.     }
  306.  
  307.     //read authorities
  308.     for(i=0;i<ntohs(dns->auth_count);i++)
  309.     {
  310.         auth[i].name=ReadName(reader,buf,&stop);
  311.         reader+=stop;
  312.  
  313.         auth[i].resource=(struct R_DATA*)(reader);
  314.         reader+=sizeof(struct R_DATA);
  315.  
  316.         auth[i].rdata=ReadName(reader,buf,&stop);
  317.         reader+=stop;
  318.     }
  319.  
  320.     //read additional
  321.     for(i=0;i<ntohs(dns->add_count);i++)
  322.     {
  323.         addit[i].name=ReadName(reader,buf,&stop);
  324.         reader+=stop;
  325.  
  326.         addit[i].resource=(struct R_DATA*)(reader);
  327.         reader+=sizeof(struct R_DATA);
  328.  
  329.         if(ntohs(addit[i].resource->type)==1)
  330.         {
  331.             addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len));
  332.             for(j=0;j<ntohs(addit[i].resource->data_len);j++)
  333.             addit[i].rdata[j]=reader[j];
  334.  
  335.             addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0';
  336.             reader+=ntohs(addit[i].resource->data_len);
  337.         }
  338.         else
  339.         {
  340.             addit[i].rdata=ReadName(reader,buf,&stop);
  341.             reader+=stop;
  342.         }
  343.     }
  344. }
  345.  
  346. void parse_dns(char *buf, int len) {
  347. struct DNS_HEADER *dns = NULL;
  348. int i;
  349. int questions, answers, authorities, additional;
  350.  
  351. dns = (struct DNS_HEADER*) buf;
  352.  
  353. questions = ntohs(dns->q_count);
  354. answers = ntohs(dns->ans_count);
  355. authorities = ntohs(dns->auth_count);
  356. additional = ntohs(dns->add_count);
  357.  
  358. hexDump("Received", buf, len);
  359.  
  360. printf("\n%d Questions.", questions);
  361. printf("\n%d Answers.", answers);
  362. printf("\n%d Authoritative Servers.", authorities);
  363. printf("\n%d Additional records.\n\n", additional);
  364.  
  365. //in the RFC about DNS is said that QDCOUNT is usally set to 1 but not specified that it is 1. I googled a bit and found http://maradns.samiam.org/multiple.qdcount.html . I will print all questions but need to take care that they have same type.
  366.  
  367.  
  368. char *location = &buf[sizeof(struct DNS_HEADER)];
  369.  
  370. if (questions)
  371. printf("\n\nQuestion records:\n");
  372.  
  373. for(i = 0; i < questions; ++i) {
  374. char *l = parse_query(location);
  375. location = l;
  376. }
  377. /*
  378. if (answers)
  379. printf("\n\nAnswer records:\n");
  380.  
  381. for(i = 0; i < answers; ++i) {
  382. location = parse_rr((struct RES_RECORD*)location);
  383. }
  384.  
  385. if (authorities)
  386. printf("\n\nAuthoritative Servers:\n");
  387.  
  388. for (i = 0; i < authorities; ++i) {
  389. location = parse_rr((struct RES_RECORD*)location);
  390. }
  391.  
  392. if (additional)
  393. printf("\n\nAdditional records:\n");
  394.  
  395. for (i = 0; i < additional; ++i) {
  396. location = parse_rr((struct RES_RECORD*)location);
  397. }*/
  398.  
  399. }
  400.  
  401. void hexDump(char *desc, void *addr, int len) {
  402. int i;
  403. unsigned char buff[17];
  404. unsigned char *pc = addr;
  405.  
  406. if(desc != NULL)
  407. printf("%s:\n", desc);
  408.  
  409. for(i=0; i<len; i++) {
  410. if(i!=0 && i%8==0)printf(" ");
  411. if((i % 16) == 0) {
  412. if(i != 0)
  413. printf(" %s\n", buff);
  414.  
  415. printf(" %04x ", i);
  416. }
  417.  
  418. printf(" %02x", pc[i]);
  419.  
  420. if((pc[i] < 0x20) || (pc[i] > 0x7e))
  421. buff[i % 16] = '.';
  422. else
  423. buff[i % 16] = pc[i];
  424. buff[(i % 16) + 1] = '\0';
  425. }
  426.  
  427. while((i % 16) != 0) {
  428. printf(" ");
  429. i++;
  430. }
  431.  
  432. printf(" %s\n", buff);
  433. }
Advertisement
Add Comment
Please, Sign In to add comment