amertkara
amertkara

Reputation: 1379

DNS rdata parsing with Python

I want to extend the code below by parsing TXT field data aswell. I simply added the check for TXT field and start parsing the data. However the rdata field comes in little endian format. I was going to use regex to strip out the garbage came with Base64 encoded string, I thought there would be a better way of doing this.

Original Code

#!/usr/bin/env python

import dpkt, socket, sys

if len(sys.argv) < 2 or len(sys.argv) > 2:
 print "Usage:\n", sys.argv[0], "filename.pcap"
 sys.exit()

f = open(sys.argv[1])
pcap = dpkt.pcap.Reader(f)

for ts, buf in pcap:
 # make sure we are dealing with IP traffic
 # ref: http://www.iana.org/assignments/ethernet-numbers
 try: eth = dpkt.ethernet.Ethernet(buf)
 except: continue
 if eth.type != 2048: continue
 # make sure we are dealing with UDP
 # ref: http://www.iana.org/assignments/protocol-numbers/
 try: ip = eth.data
 except: continue
 if ip.p != 17: continue
 # filter on UDP assigned ports for DNS
 # ref: http://www.iana.org/assignments/port-numbers
 try: udp = ip.data
 except: continue
 if udp.sport != 53 and udp.dport != 53: continue
 # make the dns object out of the udp data and check for it being a RR (answer)
 # and for opcode QUERY (I know, counter-intuitive)
 try: dns = dpkt.dns.DNS(udp.data)
 except: continue
 if dns.qr != dpkt.dns.DNS_R: continue
 if dns.opcode != dpkt.dns.DNS_QUERY: continue
 if dns.rcode != dpkt.dns.DNS_RCODE_NOERR: continue
 if len(dns.an) < 1: continue
 # now we're going to process and spit out responses based on record type
 # ref: http://en.wikipedia.org/wiki/List_of_DNS_record_types
 for answer in dns.an:
   if answer.type == 5:
     print "CNAME request", answer.name, "\tresponse", answer.cname
   elif answer.type == 1:
     print "A request", answer.name, "\tresponse", socket.inet_ntoa(answer.rdata)
   elif answer.type == 12:
     print "PTR request", answer.name, "\tresponse", answer.ptrname

I added

elif answer.type == 16:
     print "TXT request", repr(answer.name), "\tresponse", repr(answer.rdata)

Output

Cr\xe0ax\xdac`\xe0`p\xe5`0\xf9\x9b\xe3\xc0\xe0\xc0\xf6\xf5\xd7\x81\x15\xc9\x8c@\xcc\xc4 \xb6\xfd\x98\xa7\x8dA\xd9\xf9\nI\xf7\x06\x01\xc6\xf9\x06\xb7\x19\x18\x18\x199\xb8\x18\x98_81\xc8\xfc\xb2\x05\x00\xef|\x115

Upvotes: 4

Views: 5870

Answers (1)

Pedro Romano
Pedro Romano

Reputation: 11213

The package dnslib has functionality for encoding/decoding DNS wire-format packets.

Upvotes: 6

Related Questions