📄 dns.c
字号:
/**************************************************************************** ** File: dns.c**** Author: Mike Borella**** Comments: Dump DNS header information**** $Log: dns.c,v $** Revision 1.2 2000/10/27 00:11:16 qweaver****** Rolled back to the pristine ipgrab-0.8.2 source.**** Revision 1.2 1998/06/12 21:00:59 mborella** Added log tag*******************************************************************************/#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <arpa/inet.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include "config.h"#include "dns.h"extern u_char *packet_end;/*----------------------------------------------------------------------------**** dump_dns()**** Parse DNS packet and dump fields****----------------------------------------------------------------------------*/void dump_dns(u_char *bp, int length){ u_char *ep = bp + length; u_char *p; DNSHdr dns_fixed; int i, t; u_int16_t qt, qc; char *dns_query_type(u_int16_t); u_char *dump_rr(u_char *, u_char *, u_char *); u_char *parse_labels(u_char *, u_char *, u_char *);#ifdef DEBUG void dump_ascii(u_char *, u_char *);#endif /* * Make sure we don't run off the end of the packet */ if (ep > packet_end) ep = packet_end; /* * Overlay the first 12 bytes, which are fixed */ memcpy((void *) &dns_fixed, bp, sizeof(dns_fixed)); /* * Print it */ printf("-----------------------------------------------------------------\n"); printf(" DNS Packet\n"); printf("-----------------------------------------------------------------\n"); printf("Identification: %d\n", ntohs(dns_fixed.dns_id)); printf("Flags: query/response: %d ", dns_fixed.dns_fl_qr); if (dns_fixed.dns_fl_qr == 0) printf("(query)\n"); else printf("(response)\n"); printf(" opcode %d ", dns_fixed.dns_fl_opcode); switch(dns_fixed.dns_fl_opcode) { case 0: printf("(standard)\n"); break; case 1: printf("(inverse)\n"); break; case 2: printf("(server status)\n"); break; } printf(" auth answer %d\n", dns_fixed.dns_fl_aa); printf(" truncated %d\n", dns_fixed.dns_fl_tc); printf(" recursion req %d\n", dns_fixed.dns_fl_rd); printf(" recursion avail %d\n", dns_fixed.dns_fl_ra); printf(" zero %d\n", dns_fixed.dns_fl_zero); printf(" return code %d ", dns_fixed.dns_fl_rcode); switch(dns_fixed.dns_fl_rcode) { case 0: printf("(no error)\n"); break; case 1: printf("(format error)\n"); break; case 2: printf("(server error)\n"); break; case 3: printf("(name error)\n"); break; case 4: printf("(not implemented)\n"); break; case 5: printf("(service refused)\n"); break; } printf("# of questions %d\n", ntohs(dns_fixed.dns_num_q)); printf("# of answer RRs %d\n", ntohs(dns_fixed.dns_num_ans)); printf("# of authorization RRs %d\n", ntohs(dns_fixed.dns_num_auth)); printf("# of additional RRs %d\n", ntohs(dns_fixed.dns_num_add)); /* * Do the question part of the packet. */ p = bp + sizeof(DNSHdr); i = ntohs(dns_fixed.dns_num_q); while (i > 0) { printf("Question: query name "); p = parse_labels(p, bp, ep); memcpy((void *) &qt, p, sizeof(qt)); p = p + sizeof(qt); memcpy((void *) &qc, p, sizeof(qc)); p = p + sizeof(qc); printf(" query type %d %s\n", ntohs(qt), dns_query_type(ntohs(qt))); printf(" query class %d", ntohs(qc)); if (ntohs(qc) == 1) printf(" (Internet)"); printf("\n"); i--; } /* * dump the resource records for the answers */ i = ntohs(dns_fixed.dns_num_ans); t = i; while (i > 0) { printf("Answer %d: ", t-i+1); p = dump_rr(p, bp, ep); i--; } /* * dump the resource records for the authoritative answers */ i = ntohs(dns_fixed.dns_num_auth); t = i; while (i > 0) { printf("Auth %d: ", t-i+1); p = dump_rr(p, bp, ep); i--; } /* * dump the resource records for the additional info */ i = ntohs(dns_fixed.dns_num_add); t = i; while (i > 0) { printf("Adtnl %d: ", t-i+1);#ifdef DEBUG dump_ascii(p, ep);#endif p = dump_rr(p, bp, ep); i--; } }/*----------------------------------------------------------------------------**** dns_query_type()**** Return a string describing the numeric value of a DNS query type****----------------------------------------------------------------------------*/char *dns_query_type(u_int16_t t){ static char answer[32]; switch(t) { case 1: strncpy(answer, "(IP address)", 32); break; case 2: strncpy(answer, "(name server)", 32); break; case 5: strncpy(answer, "(canonical name)", 32); break; case 12: strncpy(answer, "(pointer record)", 32); break; case 13: strncpy(answer, "(host info)", 32); break; case 15: strncpy(answer, "(MX record)", 32); break; case 252: strncpy(answer, "(request zone transfer)", 32); break; case 255: strncpy(answer, "(request all records)", 32); break; default: answer[0] = '\0'; break; } return answer;}/*----------------------------------------------------------------------------**** dump_rr()**** Print the contents of a resource record****----------------------------------------------------------------------------*/u_char *dump_rr(u_char *p, u_char *bp, u_char *ep){ int i; u_int16_t qt, qc; u_int32_t ttl; u_int16_t reslen; struct in_addr ipaddr; u_char *parse_labels(u_char *, u_char *, u_char *); printf("server name "); p = parse_labels(p, bp, ep); /* * Do type and class */ memcpy((void *) &qt, p, sizeof(qt)); p = p + sizeof(qt); memcpy((void *) &qc, p, sizeof(qc)); p = p + sizeof(qc); printf(" type %d %s\n", ntohs(qt), dns_query_type(ntohs(qt))); printf(" class %d", ntohs(qc)); if (ntohs(qc) == 1) printf(" (Internet)"); printf("\n"); /* * Do TTL */ memcpy((void *) &ttl, p, sizeof(ttl)); p = p + sizeof(ttl); printf(" ttl %d seconds\n", ntohs(ttl)); /* * Do resource length */ memcpy((void *) &reslen, p, sizeof(reslen)); p = p + sizeof(reslen); printf(" length %d\n", ntohs(reslen)); /* * Do resource data. */ switch(ntohs(qt)) { case 1: for (i=1; i<= ntohs(reslen); i += 4) { memcpy((void *) &ipaddr, p, sizeof(ipaddr)); p = p + sizeof(ipaddr); printf(" IP address %s\n", inet_ntoa(ipaddr)); } break; case 2: printf(" auth host "); p = parse_labels(p, bp, ep); break; case 5: printf(" canon host "); p = parse_labels(p, bp, ep); break; default: p = p + ntohs(reslen); } return p;}/*----------------------------------------------------------------------------**** parse_labels()**** Recursively parse a label entry in a DNS packet****----------------------------------------------------------------------------*/u_char *parse_labels(u_char *p, u_char *bp, u_char *ep){ u_int8_t count; u_int16_t offset; while(1) { count = (u_int8_t) *p; if (count >= 192) { /* * There's a pointer in this label. Sigh. Let's grab the * 14 low-order bits and run with them... */ p++; offset = count - 192; offset = offset << 8; offset = offset + *p; p++; parse_labels(bp+offset, bp, ep); return p; } else p++; if (count == 0) break; while (count > 0) { if (p <= ep) printf("%c", *p); else { printf("\nPacket length exceeded\n"); return p; } p++; count--; } printf("."); } printf("\n"); return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -