From c83a345a7ee1ad7f54328f41bc9a770bc4c2df14 Mon Sep 17 00:00:00 2001 From: Jan Kadlec <jan@hp4-jankadlec.(none)> Date: Tue, 1 Feb 2011 17:28:27 +0100 Subject: [PATCH] Added script for parsing pcap dumps. Refs #233 --- scripts/parse_dump.py | 136 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100755 scripts/parse_dump.py diff --git a/scripts/parse_dump.py b/scripts/parse_dump.py new file mode 100755 index 0000000000..b64b404297 --- /dev/null +++ b/scripts/parse_dump.py @@ -0,0 +1,136 @@ +#!/usr/bin/python +from scapy.all import * +from binascii import * +import base64 +import sys +import dns.rdata +import dns.rrset +from struct import * + +fr = open(sys.argv[1] + ".raw_data", 'wb') +fp = open(sys.argv[1] + ".parsed_data", 'wb') + +def chop_and_write_rr_query(rr): + name = dns.name.from_text(rr.qname) + print rr.qname + + wire = name.to_wire() + fp.write(pack('B', len(wire))) + print len(wire) + fp.write(wire) + fp.write(pack('H', rr.qtype)) + fp.write(pack('H', rr.qclass)) + +def chop_and_write_rr_response(rr): + name = dns.name.from_text(rr.rrname) + print rr.rrname + + wire = name.to_wire() + fp.write(pack('B', len(wire))) + fp.write(wire) + fp.write(pack('H', rr.type)) + fp.write(pack('H', rr.rclass)) + fp.write(pack('L', rr.ttl)) + + try: + rdata = dns.rdata.from_wire(rr.rclass, rr.type, rr.rdata, 0, len(rr.rdata)) + fp.write(pack('B', len(rr.rdata))) + rdata.to_wire(fp) + except: + + try: + if rr.rdata[0] != '\#': + rdata = dns.rdata.from_text(rr.rclass, rr.type, rr.rdata) + try: + fp.write(pack('B', len(rdata))) + except: + # no length - no way to know wire length + try: + if rr.type == 2: + fp.seek(1, 1) + old = fp.tell() + rdata.to_wire(fp) + size = fp.tell() - old + fp.seek(-(size + 1), 1) + fp.write(pack('B', size)) + fp.seek(0, 2) + else: + rdata.to_wire(fp) + except Exception as e: + print 'Error, exiting: ', e + sys.exit(-1) + except: + print 'could not parse rdata type: ', rr.type + print 'dumping directly (hopefully it is SOA)' + fp.write(pack('B', len(rr.rdata))) + fp.write(rr.rdata) + + + if rr.type == 50: + f = open('nsec3debug', 'wb') + rdata.to_wire(f) + f.close() + +def chop_and_write_section_response(section): + if section == None: + return + i = 0 + rr = section.getlayer(i); + while rr != None: + chop_and_write_rr_response(rr) + i += 1 + rr = section.getlayer(i) + +def chop_and_write_section_query(section): + if section == None: + return + i = 0 + rr = section.getlayer(i); + while rr != None: + chop_and_write_rr_query(rr) + i += 1 + rr = section.getlayer(i) + +def chop_and_write_packet(packet): + fp.write(pack('H', packet.id)) +# fp.write(pack('H', packet.qr)) +# fp.write(pack('H', packet.opcode)) +# fp.write(pack('H', packet.aa)) #TODO these are not uint16_t +# fp.write(pack('H', packet.rcode)) + fp.write(pack('H', packet.qdcount)) + fp.write(pack('H', packet.ancount)) + fp.write(pack('H', packet.nscount)) + fp.write(pack('H', packet.arcount)) + + chop_and_write_section_query(packet.qd) + chop_and_write_section_response(packet.an) + chop_and_write_section_response(packet.ns) + chop_and_write_section_response(packet.ar) + +packets = rdpcap(sys.argv[1]) + +total_length = len(packets) + +fr.write(pack('L', total_length)) +fp.write(pack('L', total_length)) + +for packet in packets: + try: + data = a2b_hex(str(packet['DNS']).encode('hex')) + fr.write(pack('H', len(data))) + fr.write(data) + chop_and_write_packet(packet['DNS']) + except IndexError: + print 'non-DNS packet' + total_length -= 1 + +fr.seek(0) +fp.seek(0) + +fr.write(pack('L', total_length)) +fp.write(pack('L', total_length)) + +print 'written ', total_length, 'packets' + +fr.close() +fp.close() -- GitLab