Search code examples
pythondnspcap

Python library to parse DNS from Wireshark capture file pcap


I'm beginning with Python. I have a .pcap file captured by Wireshark, that contains a DNS query and response. I need to open this file and extract the requested hostname and returned record types and IP addresses. I've found several libraries capable of reading a pcap files, but i have no idea, which one will be most suitable for this. Can you please recommend something?


Solution

  • Scapy is a good one.

    from scapy.all import *
    from scapy.layers.dns import DNS, DNSQR
    
    types = {0: 'ANY', 255: 'ALL',1: 'A', 2: 'NS', 3: 'MD', 4: 'MD', 5: 'CNAME',
             6: 'SOA', 7:  'MB',8: 'MG',9: 'MR',10: 'NULL',11: 'WKS',12: 'PTR',
             13: 'HINFO',14: 'MINFO',15: 'MX',16: 'TXT',17: 'RP',18: 'AFSDB',
             28: 'AAAA', 33: 'SRV',38: 'A6',39: 'DNAME'}
    
    dns_packets = rdpcap('file.pcap')
    for packet in dns_packets:
        if packet.haslayer(DNS):
            print(packet.show())
            dst = packet[IP].dst
            rec_type = packet[DNSQR].qtype
            print(dst, types[rec_type])
    

    Example of output:

    ###[ Ethernet ]###
      dst       = 00:16:e3:19:27:15
      src       = 00:04:76:96:7b:da
      type      = 0x800
    ###[ IP ]###
         version   = 4L
         ihl       = 5L
         tos       = 0x0
         len       = 70
         id        = 0
         flags     = DF
         frag      = 0L
         ttl       = 64
         proto     = udp
         chksum    = 0xb753
         src       = 192.168.1.2
         dst       = 192.168.1.1
         \options   \
    ###[ UDP ]###
            sport     = 2128
            dport     = domain
            len       = 50
            chksum    = 0x8397
    ###[ DNS ]###
               id        = 12575
               qr        = 0L
               opcode    = QUERY
               aa        = 0L
               tc        = 0L
               rd        = 1L
               ra        = 0L
               z         = 0L
               ad        = 0L
               cd        = 0L
               rcode     = ok
               qdcount   = 1
               ancount   = 0
               nscount   = 0
               arcount   = 0
               \qd        \
                |###[ DNS Question Record ]###
                |  qname     = '2.1.168.192.in-addr.arpa.'
                |  qtype     = PTR
                |  qclass    = IN
               an        = None
               ns        = None
               ar        = None
    
    ('192.168.1.1', 'PTR')
    

    The last line is the outgoing IP address and the record type. There is a bunch of data, just select what you need.