So one of the things that I enjoy doing from time to time is playing with network packets. In that light dpkt has been an excellent tool. The only issue with it is that the documentation doesn't extend much more than the pydoc. Luckily it's not that hard to use
As an example here's a program that generates random UDP packets and then sends them via raw sockets.
#!/usr/bin/env python2.4
import dpkt
import optparse
import random
import socket
import struct
import sys
def createUDPPackets(options):
"""create packets to send"""
udp = dpkt.udp.UDP()
if options.sport:
udp.sport = options.sport
else:
#pick a random sport
udp.sport = random.sample(xrange(65536),1)[0]
if options.dport:
udp.dport = options.dport
else:
udp.dport = random.sample(xrange(65536),1)[0]
if options.checksum:
udp.checksum = options.checksum
if options.length:
udp.ulen = int(options.length)
else:
# take into account MTU - space for a large IP Header
udp.ulen = random.sample(xrange(1340),1)[0]
if options.data:
udp.data = data
else:
udp.data = ""
for i in xrange(udp.ulen):
udp.data += struct.pack("B",random.sample(xrange(255),1)[0])
return udp.pack()
def createRawIPSocket():
""" """
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW,
socket.IPPROTO_UDP)
#sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
return sock
def parseArgs():
"""parse command line arguments"""
usage = """%s: [-s|--sport sport][-d | --dport dport][-x|--data data] target IP""" % sys.argv[0]
op = optparse.OptionParser(usage)
op.add_option('-s','--sport', dest='sport',type='int',
help='set source port')
op.add_option('-d','--dport', dest='dport',type='int',
help='destination port')
op.add_option('-c','--checksum', dest='checksum', action='store',
help='UDP checksum')
op.add_option('-l','--length',dest='length', action='store',
help='length of packet')
op.add_option('-x','--data', dest='data',action='store',
help='set a value for the data field')
return op.parse_args()
def main():
options, args = parseArgs()
sock = createRawIPSocket()
while 1:
msg = createUDPPackets(options)
sock.sendto(msg, (args[0], int(options.dport))
if __name__ == "__main__":
main()
# vim: set ts=2 et sw=2:
What's wrong with this script? It generates random data but not in a repeatable way. If I find a crash I have to replay the stream that I generated and not just rerun the script with a given seed. Additionally, I kinda fudged the MTU stuff but with this you should get an idea of how to use dpkt.