ref: 16d016b87e7783cecedb1078c1327fa1244da4d7
dir: /dnsparser.c/
/* * program to parse dns packets, * it assumes packets are not sent over qinq or vxlan or jumbo frames * or avian carriers */ #include <stdio.h> #include <pcap.h> #include <stdint.h> #include <string.h> #include "common.h" struct bpf_program dnsfilter; char errbuf[PCAP_ERRBUF_SIZE]; int debug; void dnsReader(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) { static int packets = 1; Ether e; Pkt p; Udp udp; Tcp tcp; Dns dns; pos = 0; parseEther(pkt, &e); parsePkt(pkt, &p); if(p.proto == IPPROTO_UDP) { parseUdp(pkt, &udp); } else if(p.proto == IPPROTO_TCP) { parseTcp(pkt, &tcp); /* reduce the noise */ if(tcp.flags & (TCP_FLAG_FIN|TCP_FLAG_SYN|TCP_FLAG_ACK) && !(tcp.flags & TCP_FLAG_PSH)) { // printf("skipped noise\n"); return; } pos += 2; /* there is a dns-over-tcp len field we ignore */ } else err(1, "dnsReader(): unknown proto: %#x (%d)", p.proto); if(debug) { fprintf(stderr, "DEBUG: "); for(int i = 0 ; i < header->caplen ; i++) fprintf(stderr, "%d: 0x%x\t", i, pkt[i]); fprintf(stderr, "\n"); } parseDns(pkt, &dns); printf("\n==================%3d ==================\n", packets++); printf("frame info:\n" "\tlen: %d\tcaplen: %d\n" "\ttimeval.tv_sec: %ld\ttimeval.tv_usec: %ld\n", header->len, header->caplen, header->ts.tv_sec, header->ts.tv_usec); printEther(e); printPkt(p); if(p.proto == IPPROTO_UDP) printUdp(udp); else if(p.proto == IPPROTO_TCP) printTcp(tcp); printDns(dns); } int main(int argc, char **argv) { pcap_t *handle; if(argc != 2) err(1, "%s: usage: %s file.pcap", argv[0], argv[0]); pcap_init(PCAP_CHAR_ENC_LOCAL, errbuf); handle = pcap_open_offline(argv[1], errbuf); if(handle == NULL) err(1, "%s: unable to open: %s", argv[0], argv[1]); if (pcap_compile(handle, &dnsfilter, "src port 53", 0, PCAP_NETMASK_UNKNOWN) == -1) err(1, "%s: failed to compile the expr: %s\n", argv[0], pcap_geterr(handle)); if (pcap_setfilter(handle, &dnsfilter) == -1) err(1, "%s: failed to install filter: %s\n", argv[0], pcap_geterr(handle)); pcap_loop(handle, -1, dnsReader, NULL); pcap_freecode(&dnsfilter); pcap_close(handle); return 0; }