def test_blocks_lst(): blk_lst = [ # SHB must be 1st block block.SectionHeaderBlock([ option.ShbHardware("Dell"), option.ShbOs("Ubuntu"), option.ShbUserAppl("IntelliJ Idea") ]), block.InterfaceDescBlock(linktype.LINKTYPE_ETHERNET, [ option.IdbName("Carrier Pigeon"), option.IdbDescription("Something profound here..."), option.IdbIpv4Addr([192, 168, 13, 7], [255, 255, 255, 0]), option.IdbOs('Ubuntu Xenial 16.04.1 LTS') ]), block.SimplePacketBlock('abc'), block.EnhancedPacketBlock(0, "<<<Stand-in for actual packet data>>>"), block.CustomBlockCopyable(pen.BROCADE_PEN, 'User-defined custom data'), ] packed_bytes = block.pack_all(blk_lst) if False: pcap_fp = open('block_list.pcapng', 'wb') pcap_fp.write(packed_bytes) pcap_fp.close() util.assert_block32_length(packed_bytes) blk_lst_unpacked = block.unpack_all(packed_bytes) assert blk_lst == blk_lst_unpacked
def strip_header(packed_bytes): #todo use for all unpack() "Utility function to strip Option type_code & length from packed bytes, returning all three." util.assert_block32_length(packed_bytes) (type_code, content_len) = struct.unpack('=HH', packed_bytes[:4]) content_pad = packed_bytes[4:] assert content_len <= len(content_pad) content = content_pad[:content_len] return (type_code, content_len, content)
def unpack(packed_bytes): "Deserialize from packed bytes" util.assert_block32_length(packed_bytes) #todo add to all assert len(packed_bytes) == 12 #todo check everywhere (type_code, content_len, content) = strip_header(packed_bytes) assert type_code == IdbEuiAddr.SPEC_CODE #todo check everywhere assert content_len == 8 #todo check everywhere addr_val = util.bytes_to_uint8_list(content) result = IdbEuiAddr(addr_val) return result
def unpack(packed_bytes): "Deserialize from packed bytes" util.assert_block32_length(packed_bytes) #todo add to all assert len(packed_bytes) == 12 #todo check everywhere (type_code, content_len) = struct.unpack('=HH', packed_bytes[:4]) assert type_code == IdbMacAddr.SPEC_CODE #todo check everywhere assert content_len == 6 #todo check everywhere addr_val = util.bytes_to_uint8_list(packed_bytes[4:10]) result = IdbMacAddr(addr_val) return result
def pack(self): #todo needs test "Serialize to packed bytes" content = to_bytes(self.addr_bytes) content_len = len(content) assert content_len == 6 content_pad = util.block32_pad_bytes(content) packed_bytes = struct.pack('=HH', self.type_code, content_len) + content_pad util.assert_block32_length(packed_bytes) #todo add to all return packed_bytes
def strip_header(packed_bytes): #todo use for all unpack() "Utility function to strip Block type_code & total_len from packed bytes, returning all three. " util.assert_block32_length(packed_bytes) (type_code, total_len, byte_order_magic_found) = struct.unpack('=LLL', packed_bytes[:12]) #todo if SHB: #todo parse BOM-found; set global endian; re-parse fields, verify OK assert total_len <= len(packed_bytes) stripped_bytes = packed_bytes[8:] return (type_code, total_len, stripped_bytes)
def unpack(packed_bytes): "Deserialize from packed bytes" util.assert_block32_length(packed_bytes) #todo add to all assert len(packed_bytes) == 24 #todo check everywhere (type_code, content_len) = struct.unpack('=HH', packed_bytes[:4]) assert type_code == IdbIpv6Addr.SPEC_CODE #todo check everywhere assert content_len == 17 #todo check everywhere addr_val = util.bytes_to_uint8_list(packed_bytes[4:20]) (prefix_len, ) = util.bytes_to_uint8_list(packed_bytes[20:21]) result = IdbIpv6Addr(addr_val, prefix_len) return result
def segment_all(raw_bytes): """Given the packed bytes for multiple options, returns a list of packed bytes for the individual options.""" util.assert_type_bytes(raw_bytes) util.assert_block32_length(raw_bytes) segments = [] while (0 < len(raw_bytes)): (segment, raw_bytes_remaining) = segment_rolling(raw_bytes) segments.append(segment) raw_bytes = raw_bytes_remaining return segments
def segment_all(raw_bytes): """Given concatenated packed bytes for PCAPNG blocks, returns a list of packed bytes for individual block segments""" util.assert_type_bytes(raw_bytes) util.assert_block32_length(raw_bytes) blk_segments = [] while (0 < len(raw_bytes)): assert 8 <= len(raw_bytes) (blk_type, blk_total_len, unused) = strip_header(raw_bytes) assert blk_total_len <= len(raw_bytes) blk_bytes = raw_bytes[:blk_total_len] raw_bytes_remaining = raw_bytes[blk_total_len:] blk_segments.append(blk_bytes) raw_bytes = raw_bytes_remaining return blk_segments
def pack(self): "Serialize a IDB object into packed bytes" options_bytes = option.pack_all(self.options_lst) util.assert_type_bytes(options_bytes) util.assert_block32_length(options_bytes) block_total_len = ( 4 + # block type 4 + # block total length 2 + 2 + # linktype + reserved 4 + # snaplen len(options_bytes) + 4) # block total length packed_bytes = (struct.pack( self.block_head_encoding, self.SPEC_CODE, block_total_len, self.link_type, self.reserved, self.snaplen) + options_bytes + struct.pack(self.block_tail_encoding, block_total_len)) return packed_bytes
def test_pad_to_block32(): assert to_bytes([]) == util.block32_pad_bytes([]) assert to_bytes([1, 0, 0, 0]) == util.block32_pad_bytes([1]) assert to_bytes([1, 2, 0, 0]) == util.block32_pad_bytes([1, 2]) assert to_bytes([1, 2, 3, 0]) == util.block32_pad_bytes([1, 2, 3]) assert to_bytes([1, 2, 3, 4]) == util.block32_pad_bytes([1, 2, 3, 4]) assert to_bytes([1, 2, 3, 4, 5, 0, 0, 0]) == util.block32_pad_bytes([1, 2, 3, 4, 5]) assert to_bytes([1, 2, 3, 4, 5, 6, 0, 0]) == util.block32_pad_bytes([1, 2, 3, 4, 5, 6]) assert to_bytes([1, 2, 3, 4, 5, 6, 7, 0]) == util.block32_pad_bytes([1, 2, 3, 4, 5, 6, 7]) assert to_bytes([1, 2, 3, 4, 5, 6, 7, 8]) == util.block32_pad_bytes([1, 2, 3, 4, 5, 6, 7, 8]) util.assert_block32_length([]) util.assert_block32_length([1, 2, 3, 4]) util.assert_block32_length([1, 2, 3, 4, 5, 6, 7, 8]) with pytest.raises(AssertionError): util.assert_block32_length([1]) with pytest.raises(AssertionError): util.assert_block32_length([1, 2]) with pytest.raises(AssertionError): util.assert_block32_length([1, 2, 3])