def test_unpackMultiplePackets(self): sequencenum = 1011 TESTDATA_FILENAME = os.path.join(os.path.dirname(__file__), 'inetx_test.pcap') mypcap = pcap.Pcap(TESTDATA_FILENAME) mypcap.readGlobalHeader() while True: # Loop through the pcap file reading one packet at a time try: mypcaprecord = mypcap.readAPacket() except IOError: # End of file reached break ethpacket = SimpleEthernet.Ethernet() # Create an Ethernet object ethpacket.unpack(mypcaprecord.packet) # Unpack the pcap record into the eth object ippacket = SimpleEthernet.IP() # Create an IP packet ippacket.unpack(ethpacket.payload) # Unpack the ethernet payload into the IP packet udppacket = SimpleEthernet.UDP() # Create a UDP packet udppacket.unpack(ippacket.payload) # Unpack the IP payload into the UDP packet inetxpacket = inetx.iNetX() # Create an iNetx object inetxpacket.unpack(udppacket.payload) # Unpack the UDP payload into this iNetX object #print "INETX: StreamID ={:08X} Sequence = {:8d} PTP Seconds = {}".format(inetxpacket.streamid,inetxpacket.sequence,inetxpacket.ptptimeseconds) self.assertEqual(inetxpacket.sequence,sequencenum) sequencenum += 1 mypcap.close()
def _readNextUDPPacket(self): """This method will read the next UDP packet in the pcap file one by one and returns the udp,eth and ip packets""" # already at the end of the file if self.bytesread >= self.filesize: raise IOError # otherwise pull our the PCAP header size. Should really push headersize to the object self headersize = struct.calcsize(Pcap.RECORD_HEADER_FORMAT) pcapheader = self.fopen.read(headersize) self.bytesread += headersize (sec, usec, incl_len, orig_len) = struct.unpack(Pcap.RECORD_HEADER_FORMAT, pcapheader) # now we have a packet then lets deconstruct it. first read in the packet eth_pkt = SimpleEthernet.Ethernet(self.fopen.read(orig_len)) self.bytesread += orig_len # This is the most portable but as a quick hack I'm going # to ignore smoe packets. All non-IP packets for starter if eth_pkt.type != 2048: raise NotImplementedError # pull apart the other headers. Again I'm assuming all the IP packets # are udp packets ip_pkt = SimpleEthernet.IP(eth_pkt.payload) # Only parse udp if ip_pkt.protocol != SimpleEthernet.IP.PROTOCOLS['UDP']: raise NotImplementedError udp_pkt = SimpleEthernet.UDP(ip_pkt.payload) # return the interesting packet headers, the packet time and the temperature if it exists return (eth_pkt, ip_pkt, udp_pkt)
def test_unpackIEANFromPcap(self): '''Read all the IENA packets in a pcap file and check each field''' p = pcap.Pcap("iena_test.pcap") p.readGlobalHeader() sequencenum = 195 exptime = 0x1d102f800 while True: # Loop through the pcap file reading one packet at a time try: mypcaprecord = p.readAPacket() except IOError: # End of file reached break e = SimpleEthernet.Ethernet() e.unpack(mypcaprecord.packet) ip = SimpleEthernet.IP() ip.unpack(e.payload) u = SimpleEthernet.UDP() u.unpack(ip.payload) # Now I have a payload that will be an iena packet i = iena.IENA() i.unpack(u.payload) self.assertEquals(i.key, 0x1a) self.assertEquals(i.size, 24) self.assertEquals(i.status, 0) self.assertEquals(i.keystatus, 0) self.assertEquals(i.sequence, sequencenum) sequencenum += 1 self.assertEqual(i.timeusec, exptime) exptime += 0x186a0 # The timestamp increments by a fixed number of microseconds self.assertEquals(i.endfield, 0xdead)
def _readNextiNetXPacket(self): """This method will read the next iNetX packet one by one. It will raise an IOError when it hits the end of the file and n NoImplementedError when it hits packets that are not iNetx. It returns the ip, udp and inetx packets""" # already at the end of the file if self.bytesread >= self.filesize: raise IOError # otherwise pull our the PCAP header size. Should really push headersize to the object self pcapheader = self.fopen.read(Pcap.RECORD_HEADER_SIZE) (sec, usec, incl_len, orig_len) = struct.unpack(Pcap.RECORD_HEADER_FORMAT, pcapheader) # now we have a packet then lets deconstruct it. first read in the ethernet header and unpack it eth_header = SimpleEthernet.Ethernet( self.fopen.read(SimpleEthernet.Ethernet.HEADERLEN)) # This is the most portable but as a quick hack I'm going # to ignore smoe packets. All non-IP packets for starter if eth_header.type != 2048: throwaway = self.fopen.read(orig_len - SimpleEthernet.Ethernet.HEADERLEN) self.bytesread += (orig_len + Pcap.RECORD_HEADER_SIZE) raise NotImplementedError # pull apart the other headers. Again I'm assuming all the IP packets # are udp packets ip_header = SimpleEthernet.IP( self.fopen.read(SimpleEthernet.IP.HEADERLEN)) udp_header = SimpleEthernet.UDP( self.fopen.read(SimpleEthernet.UDP.HEADERLEN)) # Lets create an iNetx packet then test if we are really dealing with an # inetx packet. Do this by testing the first 4 bytes which should be the control word CONTROLWORD_LEN = 4 CONTROLWORD_STRING = struct.pack('>I', 0x11000000) inetx_packet = iNetX.iNetX() inetx_packet.packet = self.fopen.read(CONTROLWORD_LEN) # So are the first 4 bytes the control word if inetx_packet.packet != CONTROLWORD_STRING: # throw away the rest of the packet and bail out with an exception throwaway = self.fopen.read(orig_len - SimpleEthernet.Ethernet.HEADERLEN - SimpleEthernet.IP.HEADERLEN - SimpleEthernet.UDP.HEADERLEN - CONTROLWORD_LEN) self.bytesread += (orig_len + headersize) raise NotImplementedError # So we have an inetx packet, read in the rest of the pcap packet and unpack it as an inetX packet inetx_packet.packet += self.fopen.read( orig_len - SimpleEthernet.Ethernet.HEADERLEN - SimpleEthernet.IP.HEADERLEN - SimpleEthernet.UDP.HEADERLEN - CONTROLWORD_LEN) inetx_packet.unpack(inetx_packet.packet) self.bytesread += (headersize + orig_len) # return the interesting packet headers, the packet time and the temperature if it exists return (inetx_packet, ip_header, udp_header, sec, bcu_temperature)
def test_readAllMPEGTS(self): ''' Reads the same mpeg ts file as previously but reads all the data in the file and checks for any continuity errors :return: ''' p = pcap.Pcap("mpegts_input.pcap") p.readGlobalHeader() while True: # Loop through the pcap file reading one packet at a time try: mypcaprecord = p.readAPacket() except IOError: # End of file reached break ethpacket = SimpleEthernet.Ethernet() # Create an Ethernet object ethpacket.unpack(mypcaprecord.packet) # Unpack the pcap record into the eth object ippacket = SimpleEthernet.IP() # Create an IP packet ippacket.unpack(ethpacket.payload) # Unpack the ethernet payload into the IP packet udppacket = SimpleEthernet.UDP() # Create a UDP packet udppacket.unpack(ippacket.payload) # Unpack the IP payload into the UDP packet inetxpacket = inetx.iNetX() # Create an iNetx object inetxpacket.unpack(udppacket.payload) # Unpack the UDP payload into this iNetX object mpegts = MPEGTS.MPEGTS() mpegts.unpack(inetxpacket.payload) self.assertEqual(mpegts.NumberOfBlocks(),7) self.assertFalse(mpegts.contunityerror) p.close()
def test_readFirstMPEGTS(self): ''' Very simple test that reads a pcap file with mpegts packets. Takes the first packet in there and decoms the mpegts blocks Verifies each block in that first packet ''' p = pcap.Pcap("mpegts_input.pcap") p.readGlobalHeader() mypcaprecord = p.readAPacket() ethpacket = SimpleEthernet.Ethernet() # Create an Ethernet object ethpacket.unpack(mypcaprecord.packet) # Unpack the pcap record into the eth object ippacket = SimpleEthernet.IP() # Create an IP packet ippacket.unpack(ethpacket.payload) # Unpack the ethernet payload into the IP packet udppacket = SimpleEthernet.UDP() # Create a UDP packet udppacket.unpack(ippacket.payload) # Unpack the IP payload into the UDP packet inetxpacket = inetx.iNetX() # Create an iNetx object inetxpacket.unpack(udppacket.payload) # Unpack the UDP payload into this iNetX object mpegts = MPEGTS.MPEGTS() mpegts.unpack(inetxpacket.payload) self.assertEqual(mpegts.NumberOfBlocks(),7) self.assertFalse(mpegts.contunityerror) for packet_index in (range(7)): if packet_index == 0: self.assertEqual(mpegts.blocks[packet_index].pid,0) self.assertEqual(mpegts.blocks[packet_index].syncbyte,0x47) elif packet_index == 1: self.assertEqual(mpegts.blocks[packet_index].pid,4096) self.assertEqual(mpegts.blocks[packet_index].syncbyte,0x47) else: self.assertEqual(mpegts.blocks[packet_index].pid,256) self.assertEqual(mpegts.blocks[packet_index].syncbyte,0x47) p.close()
def test_basicUDP(self): u = SimpleEthernet.UDP() u.dstport = 5500 u.srcport = 4400 u.payload = struct.pack('B', 0x5) mypacket = u.pack() self.assertEqual(mypacket, struct.pack('>HHHHB', 4400, 5500, 9, 0, 0x5))
def test_unpackiNetFromPcap(self): p = pcap.Pcap("inetx_test.pcap") p.readGlobalHeader() mypcaprecord = p.readAPacket() e = SimpleEthernet.Ethernet() e.unpack(mypcaprecord.packet) ip = SimpleEthernet.IP() ip.unpack(e.payload) u = SimpleEthernet.UDP() u.unpack(ip.payload) # Now I have a payload that will be an inetx packet i = inetx.iNetX() i.unpack(u.payload) self.assertEquals(i.inetxcontrol, 0x11000000) self.assertEquals(i.streamid, 0xca) self.assertEquals(i.sequence, 1011) self.assertEquals(i.packetlen, 72) self.assertEquals(i.ptptimeseconds, 0x2f3) self.assertEquals(i.ptptimenanoseconds, 0x2cb4158c) self.assertEquals(i.pif, 0)
def test_unpackiNetFromPcap(self): TESTDATA_FILENAME = os.path.join(os.path.dirname(__file__), 'inetx_test.pcap') p = pcap.Pcap(TESTDATA_FILENAME) p.readGlobalHeader() mypcaprecord = p.readAPacket() e = SimpleEthernet.Ethernet() e.unpack(mypcaprecord.packet) ip = SimpleEthernet.IP() ip.unpack(e.payload) u = SimpleEthernet.UDP() u.unpack(ip.payload) # Now I have a payload that will be an inetx packet i = inetx.iNetX() i.unpack(u.payload) self.assertEqual(i.inetxcontrol,0x11000000) self.assertEqual(i.streamid,0xca) self.assertEqual(i.sequence,1011) self.assertEqual(i.packetlen,72) self.assertEqual(i.ptptimeseconds,0x2f3) self.assertEqual(i.ptptimenanoseconds,0x2cb4158c) self.assertEqual(i.pif,0) p.close()
PCAP_FNAME = "output_test.pcap" PACKETS_TO_WRITE = 50000 PAYLOAD_SIZE = 1300 # size of the payload in bytes HEADER_SIZE = {'udp': 58, 'inetx': 86, 'iena': 74} # Write out a pcapfile with each inetx and iena packet generated mypcap = pcap.Pcap(PCAP_FNAME, forreading=False) mypcap.writeGlobalHeader() ethernet_packet = SimpleEthernet.Ethernet() ethernet_packet.srcmac = 0x001122334455 ethernet_packet.dstmac = 0x554433221100 ethernet_packet.type = SimpleEthernet.Ethernet.TYPE_IP ip_packet = SimpleEthernet.IP() ip_packet.dstip = "235.0.0.2" ip_packet.srcip = "127.0.0.1" udp_packet = SimpleEthernet.UDP() udp_packet.dstport = 4422 # Fixed payload for both payload = (struct.pack(">B", 5) * PAYLOAD_SIZE) if args.type == "inetx": # Create an inetx packet avionics_packet = inetx.iNetX() avionics_packet.inetxcontrol = inetx.iNetX.DEF_CONTROL_WORD avionics_packet.pif = 0 avionics_packet.streamid = 0xdc avionics_packet.sequence = 0 avionics_packet.payload = payload elif args.type == "iena": # Create an iena packet
def main(): try: pcapfile = pcap.Pcap("SSR_ABM_102_capture_example1.pcap") except IOError: print "ERROR: Could not find input file SSR_ABM_102_capture_example1.pcap" exit() # Keep a running count of the packets packet_count = 1 # Keep a count of previous sequence number to detect a dropped packets PreviousSeqNum = dict() while True: # while we are not at the end of the file try: # So we loop through the file one packet at a time. This will eventually return an # exception at the end of file so handle that when it occurs pcaprecord = pcapfile.readAPacket() eth = SimpleEthernet.Ethernet() eth.unpack(pcaprecord.packet) ip = SimpleEthernet.IP() ip.unpack(eth.payload) udp_packet = SimpleEthernet.UDP() udp_packet.unpack(ip.payload) (ctrl_word,) = struct.unpack('>I',udp_packet.payload[:4]) if ctrl_word == 0x11000000: # This is a rough guess assuming the control word is 0x11000000 inetx_packet = inetx.iNetX() inetx_packet.unpack(udp_packet.payload) #---------------------------- # Check for dropped packet #---------------------------- if inetx_packet.streamid not in PreviousSeqNum: PreviousSeqNum[inetx_packet.streamid] = inetx_packet.sequence else: if PreviousSeqNum[inetx_packet.streamid]+1 != inetx_packet.sequence: print "ERROR: Dropped {} packets on streamid={:#x} at packet count={}".format(inetx_packet.sequence - PreviousSeqNum[inetx_packet.streamid] + 1,inetx_packet.streamid,packet_count) PreviousSeqNum[inetx_packet.streamid] = inetx_packet.sequence print "----- StreamID={:#10x} SourceIP= {:10s} -----".format(inetx_packet.streamid,ip_packet.srcip) #-------------------------------------------------------------------------------- # Packets on stream id 0x11121314 is a parser aligned block so lets look at this #-------------------------------------------------------------------------------- if inetx_packet.streamid == 0x11121314: parser_aligned_packet = ParserAligned.ParserAlignedPacket() # unpack the payload as the parser data parser_aligned_packet.unpack(inetx_packet.payload) # Loop through all the blocks in the packet and spit them out for pblock in parser_aligned_packet.parserblocks: (payload_data,) =struct.unpack('>I',pblock.payload) print "Sequence Number = {:8} Quadbyes={:5} Msgcnt={:5} BusId={:4} Elapsed={:20} ".format(inetx_packet.sequence, pblock.quadbytes,pblock.messagecount,pblock.busid,pblock.elapsedtime,payload_data) packet_count += 1 except NotImplementedError: # We received a packet that we don't care about. So skip silently packet_count += 1 pass except IOError: # We are at the end of the file so lets jump to the next file print ( "End of file reached") exit()
def test_unpackUDPShort(self): u = SimpleEthernet.UDP() dymmypayload = struct.pack('H', 0xa5) self.assertRaises(ValueError, lambda: u.unpack(dymmypayload))
def test_defaultUDP(self): u = SimpleEthernet.UDP() self.assertRaises(ValueError, lambda: u.pack())
def main(): #---------------------------------- # Setup the command line parser #---------------------------------- parser = argparse.ArgumentParser( description= 'Dump out the payload of iNetX packets as ASCII representations') parser.add_argument('--pcap', required=True, action='append', help='The input pcap file(s)') parser.add_argument( '--hex', required=False, action='store_true', default=False, help='Print the hex representation not the ASCII coded version') parser.add_argument('--outdir', required=False, default="out", help='Name of output directory. Default is out') args = parser.parse_args() #------------------------------------------------------------ # Now read the input. #------------------------------------------------------------ # The input will take multiple pcap files and loop through each # Keep a track of the position in the line for each streamID output_byte_count = {} for pcapfilename in args.pcap: try: pcapfile = pcap.Pcap(pcapfilename) except IOError: print "ERROR: File {} not found".format(pcapfilename) exit() if not os.path.exists(args.outdir): os.mkdir(args.outdir) pcapfile.readGlobalHeader() while True: try: # So we loop through the file one packet at a time. This will eventually return an # exception at the end of file so handle that when it occurs pcaprecord = pcapfile.readAPacket() eth = SimpleEthernet.Ethernet() eth.unpack(pcaprecord.packet) ip = SimpleEthernet.IP() ip.unpack(eth.payload) udp_packet = SimpleEthernet.UDP() udp_packet.unpack(ip.payload) (ctrl_word, ) = struct.unpack('>I', udp_packet.payload[:4]) if ctrl_word == 0x11000000: inetx_packet = inetx.iNetX() # Unpack the udp payload as an iNetx packet inetx_packet.unpack(udp_packet.payload) # Do we want to dump out an ascii or hex output if args.hex == True: prefix = "hex" else: prefix = "ascii" # Create an output file per streamID and open it output_file_name = "{}/{}_{:08X}.txt".format( args.outdir, prefix, inetx_packet.streamid) # NB: We are appending to the file here so if you have existing files in the directory then it will be appended output_file = open(output_file_name, 'a') # Start the byte count per streamID if not output_byte_count.has_key(inetx_packet.streamid): output_byte_count[inetx_packet.streamid] = 1 # Go thorough each byte in the payload. Not particularly efficient for byte in inetx_packet.payload: # Unpack the payload as an unsigned integer (byte_in_ascii, ) = struct.unpack('B', byte) # Write the output depending on what you want if args.hex == True: output_file.write("{:02X} ".format(byte_in_ascii)) else: # Only some ASCII codes are printable so don't print out # the non printable ones. Emulate the wireshark method of printing a period if byte_in_ascii < 31 or byte_in_ascii > 126: printable_string = "." else: printable_string = chr(byte_in_ascii) output_file.write("{}".format(printable_string)) # Create a new line after 16 bytes for readability if (output_byte_count[inetx_packet.streamid] % 16 == 0): output_file.write('\n') output_byte_count[inetx_packet.streamid] += 1 except NotImplementedError: # We received a packet that we don't care about. So skip silently pass except IOError: # We are at the end of the file so lets jump to the next file print("End of {} reached.".format(pcapfilename)) break print "Output files created in {} directory".format(args.outdir)