title: DNS rdata parsing with Python
body: <p>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.</p>
  
  <p><a href="https://mmishou.wordpress.com/2010/04/13/passive-dns-mining-from-pcap-with-dpkt-python/" rel="nofollow">Original Code</a></p>
  
  <pre><code>#!/usr/bin/env python
  
  import dpkt, socket, sys
  
  if len(sys.argv) &lt; 2 or len(sys.argv) &gt; 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) &lt; 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
  </code></pre>
  
  <p>I added</p>
  
  <pre><code>elif answer.type == 16:
       print "TXT request", repr(answer.name), "\tresponse", repr(answer.rdata)
  </code></pre>
  
  <p>Output </p>
  
  <pre><code>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
  </code></pre>