Package killerbee :: Module pcapdump
[hide private]
[frames] | no frames]

Source Code for Module killerbee.pcapdump

  1  import struct 
  2  import time 
  3   
  4  PCAPH_MAGIC_NUM = 0xa1b2c3d4 
  5  PCAPH_VER_MAJOR = 2 
  6  PCAPH_VER_MINOR = 4 
  7  PCAPH_THISZONE = 0 
  8  PCAPH_SIGFIGS = 0 
  9  PCAPH_SNAPLEN = 65535 
 10   
11 -class PcapReader:
12
13 - def __init__(self, savefile):
14 ''' 15 Opens the specified file, validates a libpcap header is present. 16 @type savefile: String 17 @param savefile: Input libpcap filename to open 18 @rtype: None 19 ''' 20 PCAPH_LEN = 24 21 self.__fh = open(savefile, mode='rb') 22 self._pcaphsnaplen = 0 23 header = self.__fh.read(PCAPH_LEN) 24 25 # Read the first 4 bytes for the magic number, determine endianness 26 magicnum = struct.unpack("I", header[0:4])[0] 27 if magicnum != 0xd4c3b2a1: 28 # Little endian 29 self.__endflag = "<" 30 elif magicnum == 0xa1b2c3d4: 31 # Big endign 32 self.__endflag = ">" 33 else: 34 raise Exception('Specified file is not a libpcap capture') 35 36 pcaph = struct.unpack("%sIHHIIII"%self.__endflag, header) 37 if pcaph[1] != PCAPH_VER_MAJOR and pcaph[2] != PCAPH_VER_MINOR \ 38 and pcaph[3] != PCAPH_THISZONE and pcaph[4] != PCAPH_SIGFIGS \ 39 and pcaph[5] != PCAPH_SNAPLEN: 40 raise Exception('Unsupported pcap header format or version') 41 42 self._pcaphsnaplen = pcaph[5] 43 self._datalink = pcaph[6]
44 51
52 - def close(self):
53 ''' 54 Closes the output packet capture; wrapper for pcap_close(). 55 @rtype: None 56 ''' 57 self.pcap_close()
58
59 - def pcap_close(self):
60 ''' 61 Closes the output packet capture. 62 @rtype: None 63 ''' 64 self.__fh.close()
65
66 - def pnext(self):
67 ''' 68 Wrapper for pcap_next to mimic method for Daintree SNA. See pcap_next() 69 ''' 70 return self.pcap_next()
71
72 - def pcap_next(self):
73 ''' 74 Retrieves the next packet from the capture file. Returns a list of 75 [Hdr, packet] where Hdr is a list of [timestamp, snaplen, plen] and 76 packet is a string of the payload content. Returns None at the end 77 of the packet capture. 78 @rtype: List 79 ''' 80 # Read the next header block 81 PCAPH_RECLEN = 16 82 rechdrdata = self.__fh.read(PCAPH_RECLEN) 83 84 try: 85 rechdrtmp = struct.unpack("%sIIII"%self.__endflag, rechdrdata) 86 except struct.error: 87 return [None,None] 88 89 rechdr = [ 90 float("%s.%s"%(rechdrtmp[0],rechdrtmp[1])), 91 rechdrtmp[2], 92 rechdrtmp[3] 93 ] 94 if rechdr[1] > rechdr[2] or rechdr[1] > self._pcaphsnaplen or rechdr[2] > self._pcaphsnaplen: 95 raise Exception('Corrupted or invalid libpcap record header (included length exceeds actual length)') 96 97 # Read the included packet length 98 frame = self.__fh.read(rechdr[1]) 99 return [rechdr, frame]
100 101
102 -class PcapDumper:
103
104 - def __init__(self, datalink, savefile):
105 ''' 106 Creates a libpcap file using the specified datalink type. 107 @type datalink: Integer 108 @param datalink: Datalink type, one of DLT_* defined in pcap-bpf.h 109 @type savefile: String 110 @param savefile: Output libpcap filename to open 111 @rtype: None 112 ''' 113 self.__fh = open(savefile, mode='wb') 114 self.__fh.write(''.join([ 115 struct.pack("I", PCAPH_MAGIC_NUM), 116 struct.pack("H", PCAPH_VER_MAJOR), 117 struct.pack("H", PCAPH_VER_MINOR), 118 struct.pack("I", PCAPH_THISZONE), 119 struct.pack("I", PCAPH_SIGFIGS), 120 struct.pack("I", PCAPH_SNAPLEN), 121 struct.pack("I", datalink) 122 ]))
123
124 - def pcap_dump(self, packet, ts_sec=None, ts_usec=None, orig_len=None):
125 ''' 126 Appends a new packet to the libpcap file. Optionally specify ts_sec 127 and tv_usec for timestamp information, otherwise the current time is 128 used. Specify orig_len if your snaplen is smaller than the entire 129 packet contents. 130 @type ts_sec: Integer 131 @param ts_sec: Timestamp, number of seconds since Unix epoch. Default 132 is the current timestamp. 133 @type ts_usec: Integer 134 @param ts_usec: Timestamp microseconds. Defaults to current timestamp. 135 @type orig_len: Integer 136 @param orig_len: Length of the original packet, used if the packet you 137 are writing is smaller than the original packet. Defaults to the 138 specified packet's length. 139 @type packet: String 140 @param packet: Packet contents 141 @rtype: None 142 ''' 143 144 if ts_sec == None or ts_usec == None: 145 # There must be a better way here that I don't know -JW 146 s_sec, s_usec = str(time.time()).split(".") 147 ts_sec = int(s_sec) 148 ts_usec = int(s_usec) 149 150 if orig_len == None: 151 orig_len = len(packet) 152 153 plen = len(packet) 154 155 self.__fh.write(''.join([ 156 struct.pack("I", ts_sec), 157 struct.pack("I", ts_usec), 158 struct.pack("I", orig_len), 159 struct.pack("I", plen), 160 packet 161 ])) 162 163 return
164 165
166 - def close(self):
167 ''' 168 Closes the output packet capture; wrapper for pcap_close(). 169 @rtype: None 170 ''' 171 self.pcap_close()
172
173 - def pcap_close(self):
174 ''' 175 Closed the output packet capture. 176 @rtype: None 177 ''' 178 self.__fh.close()
179