Wednesday, December 6, 2006

Repost: dpkt notes

If you've ever found yourself using python's struct module to extract network data from network traffic captured with one of the pcap bindings stop now. dpkt is a packet parsing / creation library. Really this means that it's a collection of classes that have already done the struct module packing and unpacking for you. This includes turning fields into native python types, meaning that things like tcp destination ports are a native integer type rather than a string or byte field that you have to manipulate. In a twisted sort of way it can be thought of as like an ORM for the layers of the stack.

As an added benefit, dpkt works recursively meaning that when you capture a frame and parse it with dpkt the data field of the ethernet object is already parsed into an IP object and the data of the IP packet is parsed as well. This unfortunately does not work endlessly (for obvious reasons) and stops at the application layer. So everything up to and including the transport layer is automagically parsed into easy to use objects for you. To get at data in the application layer dpkt also contains numerous classes for application protocols that can be used manually.

So enough chatter attached is a simple example




import dpkt
import pcap
from socket import inet_ntoa
if __name__ == '__main__":
pc = pcap.pcap()
for timestamp, packet in pc:
eth = dpkt.ethernet.Ethernet(pkt)
#skip the frame if it doesn't contain IPv4 traffic
if eth.type != 2048:
continue
ip = eth.data
#let's only deal with udp
if ip.p != 17:
continue
print "SRC IP: %s DST IP: %s" \
% (inet_ntoa(ip.src), inet_ntoa(ip.dst))
udp = ip.data
#here I'm only looking for DNS so I choose
#to discard any udp packet that's not going to port 53
if udp.dport != 53:
continue
dns = dpkt.dns.DNS(udp.data)
#for those of you who don't remember what ` does in
#python it calls the __repr__ method of the class to
#get a string representation
print `dns`


Happy hacking!

0 comments: