class InterfaceStatistics: def __init__(self, section): self.section = section self.block_type_int = INTERFACE_STATISTICS_BLOCK_INT self.block_type_packed = struct.pack( "%sI" % (self.section.sectionHeader.endianness), self.block_type_int) self.block_total_length_first_int = 0 self.block_total_length_first_packed = "\x00\x00\x00\x00" self.interface_id_packed = "\x00\x00\x00\x00" self.interface_id_int = 0 self.timestamp_high_packed = "\x00\x00\x00\x00" self.timestamp_high_int = 0 self.timestamp_low_packed = "\x00\x00\x00\x00" self.timestamp_low_int = 0 self.options = None self.block_total_length_last_int = 0 self.block_total_length_last_packed = "\x00\x00\x00\x00" self.block_size = INTERFACE_STATISTICS_BLOCK_BODY_SIZE_FIXED def Read(self, inp): self.block_total_length_first_packed = inp.read(4) self.block_total_length_first_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_first_packed)[0] self.interface_id_packed = inp.read(4) self.interface_id_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.interface_id_packed)[0] self.timestamp_high_packed = inp.read(4) self.timestamp_high_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.timestamp_high_packed)[0] self.timestamp_low_packed = inp.read(4) self.timestamp_low_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.timestamp_low_packed)[0] self.timestamp = ( self.timestamp_high_int << 32) | self.timestamp_low_int if self.block_total_length_first_int != self.block_size: self.options = Options(self.section, self.block_type_int) self.options.Read(inp) self.block_size += self.options.size self.block_total_length_last_packed = inp.read(4) self.block_total_length_last_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_last_packed)[0] def __repr__(self): ret = "" ret += "Block Type: 0x%08x (Interface Statistics)\n" % ( self.block_type_int) ret += "Block Total Length First: %d\n" % ( self.block_total_length_first_int) ret += "Block Total Length Last: %d\n" % ( self.block_total_length_last_int) ret += "Interface Id: %d\n" % (self.interface_id_int) ret += "Timestamp High: 0x%08x (%d)\n" % (self.timestamp_high_int, self.timestamp_high_int) ret += "Timestamp Low: 0x%08x (%d)\n" % (self.timestamp_low_int, self.timestamp_low_int) #ret+= "Timestamp: %s\n" % () if self.options: ret += "Options\n" ret += "\t%s\n" % (("%s" % self.options).replace("\n", "\n\t")) return ret[:-1]
class NameResolution: def __init__(self, section): self.section = section self.block_type_int = NAME_RESOLUTION_BLOCK_INT self.block_type_packed = struct.pack( "%sI" % (self.section.sectionHeader.endianness), self.block_type_int) self.block_total_length_first_int = 0 self.block_total_length_first_packed = "\x00\x00\x00\x00" self.records = None self.options = None self.block_total_length_last_int = 0 self.block_total_length_last_packed = "\x00\x00\x00\x00" self.block_size = NAME_RESOLUTION_BLOCK_BODY_SIZE_FIXED def Read(self, inp): self.block_total_length_first_packed = inp.read(4) self.block_total_length_first_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_first_packed)[0] self.records = Records(self.section) self.records.Read(inp) self.block_size += self.records.size #Align to 32 bit boundary while self.block_size % 4 != 0: self.block_size += 1 inp.read(1) if self.block_total_length_first_int != self.block_size: self.options = Options(self.section, self.block_type_int) self.options.Read(inp) self.block_size += self.options.size self.block_total_length_last_packed = inp.read(4) self.block_total_length_last_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_last_packed)[0] if self.block_total_length_last_int != self.block_total_length_first_int: Warning( "Total block lengths (first %d and last %d) do not match. File may be corrupt!" % (self.block_total_length_first_int, self.block_total_length_last_int)) def Write(self, out): out.write(self.block_total_length_first_packed) if self.records: self.records.Write(out) if self.options: self.options.Write(out) out.write(self.block_total_length_last_packed) def __repr__(self): ret = "" ret += "Block Type: 0x%08x (Name Resolution)\n" % (self.block_type_int) ret += "Block Total Length First: %d\n" % ( self.block_total_length_first_int) ret += "Block Total Length Last: %d\n" % ( self.block_total_length_last_int) if self.records: ret += "Records\n" ret += "\t%s\n" % (("%s" % self.records).replace("\n", "\n\t")) if self.options: ret += "Options\n" ret += "\t%s\n" % (("%s" % self.options).replace("\n", "\n\t")) return ret[:-1]
class InterfaceDescription: def __init__(self, section): self.section = section self.block_type_int = INTERFACE_DESCRIPTION_BLOCK_INT self.block_type_packed = struct.pack( "%sI" % (self.section.sectionHeader.endianness), self.block_type_int) self.block_total_length_first_int = 0 self.block_total_length_first_packed = "\x00\x00\x00\x00" self.link_type_int = 0 self.link_type_packed = "\x00\x00" self.reserved_int = 0 self.reserved_packed = "\x00\x00" self.snaplen_int = 0 self.snaplen_packed = "\x00\x00\x00\x00" self.options = None self.block_total_length_last_int = 0 self.block_total_length_last_packed = "\x00\x00\x00\x00" self.block_size = INTERFACE_DESCRIPTION_BLOCK_BODY_SIZE_FIXED def Read(self, inp): self.block_total_length_first_packed = inp.read(4) self.block_total_length_first_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_first_packed)[0] self.link_type_packed = inp.read(2) self.link_type_int = struct.unpack( "%sH" % (self.section.sectionHeader.endianness), self.link_type_packed)[0] self.reserved_packed = inp.read(2) self.reserved_int = struct.unpack( "%sH" % (self.section.sectionHeader.endianness), self.reserved_packed)[0] self.snaplen_packed = inp.read(4) self.snaplen_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.snaplen_packed)[0] if self.block_total_length_first_int != self.block_size: self.options = Options(self.section, self.block_type_int) self.options.Read(inp) self.block_size += self.options.size self.block_total_length_last_packed = inp.read(4) self.block_total_length_last_int = struct.unpack( "%sI" % (self.section.sectionHeader.endianness), self.block_total_length_last_packed)[0] def Write(self, out): out.write(self.block_total_length_first_packed) out.write(self.link_type_packed) out.write(self.reserved_packed) out.write(self.snaplen_packed) if self.options: self.options.Write(out) out.write(self.block_total_length_last_packed) def __repr__(self): ret = "" ret += "Block Type: 0x%08x (Interface Description)\n" % ( self.block_type_int) ret += "Block Total Length First: %d\n" % ( self.block_total_length_first_int) ret += "Block Total Length Last: %d\n" % ( self.block_total_length_last_int) try: ret += "Link Type: %s (0x%04x)\n" % ( linkTypeIntToStr[self.link_type_int], self.link_type_int) except KeyError: ret += "Link Type: Unknown (0x%04x)\n" % (self.link_type_int) ret += "Reserved: 0x%04x\n" % (self.reserved_int) ret += "Snap Length: %d\n" % (self.snaplen_int) if self.options: ret += "Options\n" ret += "\t%s\n" % (("%s" % self.options).replace("\n", "\n\t")) return ret[:-1]
class EnhancedPacket: def __init__(self,section): self.section = section self.block_type_int = ENHANCED_PACKET_BLOCK_INT self.block_type_packed = struct.pack("%sI" % (self.section.sectionHeader.endianness),self.block_type_int) self.block_total_length_first_int = 0 self.block_total_length_first_packed = "\x00\x00\x00\x00" self.interface_id_packed = "\x00\x00\x00\x00" self.interface_id_int = 0 self.timestamp_high_packed = "\x00\x00\x00\x00" self.timestamp_high_int = 0 self.timestamp_low_packed = "\x00\x00\x00\x00" self.timestamp_low_int = 0 self.captured_len_packed = "\x00\x00\x00\x00" self.captured_len_int = 0 self.packet_len_packed = "\x00\x00\x00\x00" self.packet_len_int = 0 self.options = None self.block_total_length_last_int = 0 self.block_total_length_last_packed = "\x00\x00\x00\x00" self.block_size = ENHANCED_PACKET_BLOCK_BODY_SIZE_FIXED def Read(self,inp): self.block_total_length_first_packed = inp.read(4) self.block_total_length_first_int = struct.unpack("%sI" % (self.section.sectionHeader.endianness),self.block_total_length_first_packed)[0] self.interface_id_packed = inp.read(4) self.interface_id_int = struct.unpack("%sI"%(self.section.sectionHeader.endianness),self.interface_id_packed)[0] self.timestamp_high_packed = inp.read(4) self.timestamp_high_int = struct.unpack("%sI"%(self.section.sectionHeader.endianness),self.timestamp_high_packed)[0] self.timestamp_low_packed = inp.read(4) self.timestamp_low_int = struct.unpack("%sI"%(self.section.sectionHeader.endianness),self.timestamp_low_packed)[0] self.timestamp = (self.timestamp_high_int<<32)|self.timestamp_low_int self.captured_len_packed = inp.read(4) self.captured_len_int = struct.unpack("%sI"%(self.section.sectionHeader.endianness),self.captured_len_packed)[0] self.packet_len_packed = inp.read(4) self.packet_len_int = struct.unpack("%sI"%(self.section.sectionHeader.endianness),self.packet_len_packed)[0] if self.captured_len_int > self.block_total_length_first_int-ENHANCED_PACKET_BLOCK_BODY_SIZE_FIXED: Warning("EnhancedPacket.Read : self.captured_len_int (%d) exceeds the block boundaries (block size: %d-%d)" % (self.captured_len_int,self.block_total_length_first_int,ENHANCED_PACKET_BLOCK_BODY_SIZE_FIXED)) self.captured_len_int = self.block_total_length_first_int-ENHANCED_PACKET_BLOCK_BODY_SIZE_FIXED self.packet_data = inp.read(self.captured_len_int) self.block_size += len(self.packet_data) #Align to 32 bit boundary while self.block_size%4 != 0 : self.block_size += 1 inp.read(1) if self.block_total_length_first_int != self.block_size: self.options = Options(self.section,self.block_type_int) self.options.Read(inp) self.block_size += self.options.size self.block_total_length_last_packed = inp.read(4) self.block_total_length_last_int = struct.unpack("%sI" % (self.section.sectionHeader.endianness),self.block_total_length_last_packed)[0] def Write(self,out): out.write(self.block_total_length_first_packed) out.write(self.interface_id_packed) out.write(self.timestamp_high_packed) out.write(self.timestamp_low_packed) out.write(self.captured_len_packed) out.write(self.packet_len_packed) out.write(self.packet_data) if self.options: self.options.Write(out) out.write(self.block_total_length_last_packed) def __repr__(self): ret="" ret+="Block Type: 0x%08x (Enhanced Packet)\n" % (self.block_type_int) ret+="Block Total Length First: %d\n" % (self.block_total_length_first_int) ret+="Block Total Length Last: %d\n" % (self.block_total_length_last_int) ret+="Interface Id: %d\n" % (self.interface_id_int) ret+="Timestamp High: 0x%08x (%d)\n" % (self.timestamp_high_int,self.timestamp_high_int) ret+="Timestamp Low: 0x%08x (%d)\n" % (self.timestamp_low_int,self.timestamp_low_int) #ret+= "Timestamp: %s\n" % () ret+="Captured Length: %d\n" % (self.captured_len_int) ret+="Packet Length: %d\n" % (self.packet_len_int) ret+="Packet Data\n\t%s\n" % (HexDump(self.packet_data).replace("\n","\n\t")) if self.options: ret+="Options\n" ret+="\t%s\n" % (("%s"%self.options).replace("\n","\n\t")) return ret[:-1]
class SectionHeader: def __init__(self, section): self.section = section self.block_type_int = 0 self.is_valid = True self.block_type_packed = "\x00\x00\x00\x00" self.byte_order_packed = "\x1a\x2b\x3c\x4d" self.endianness = ">" self.block_total_length_first_int = 0 self.block_total_length_first_packed = "\x00\x00\x00\x00" self.major_version_int = 0 self.major_version_packed = "\x00\x00" self.minor_version_int = 0 self.minor_version_packed = "\x00\x00" self.section_length_int = 0 self.section_length_packed = "\x00" * 8 self.options = None self.block_total_length_last_int = 0 self.block_total_length_last_packed = "\x00\x00\x00\x00" self.block_size = SECTION_HEADER_BLOCK_BODY_SIZE_FIXED def Read(self, inp): self.block_type_packed = inp.read(4) self.block_type_int = struct.unpack(">I", self.block_type_packed)[0] if self.block_type_int != SECTION_HEADER_BLOCK_INT: self.is_valid = False return self.block_total_length_first_packed = inp.read(4) self.byte_order_packed = inp.read(4) if self.byte_order_packed == "\x1a\x2b\x3c\x4d": self.endianness = ">" elif self.byte_order_packed == "\x4d\x3c\x2b\x1a": self.endianness = "<" else: self.is_valid = False self.block_total_length_first_int = struct.unpack( "%sI" % (self.endianness), self.block_total_length_first_packed)[0] self.major_version_packed = inp.read(2) self.major_version_int = struct.unpack("%sH" % (self.endianness), self.major_version_packed)[0] self.minor_version_packed = inp.read(2) self.minor_version_int = struct.unpack("%sH" % (self.endianness), self.minor_version_packed)[0] self.section_length_packed = inp.read(8) self.section_length_int = struct.unpack("%sq" % (self.endianness), self.section_length_packed)[0] if self.block_total_length_first_int != self.block_size: self.options = Options(self.section, self.block_type_int) self.options.Read(inp) self.block_size += self.options.size self.block_total_length_last_packed = inp.read(4) self.block_total_length_last_int = struct.unpack( "%sI" % (self.endianness), self.block_total_length_last_packed)[0] def Write(self, out): out.write(self.block_type_packed) out.write(self.block_total_length_first_packed) out.write(self.byte_order_packed) out.write(self.major_version_packed) out.write(self.minor_version_packed) out.write(self.section_length_packed) if self.options: self.options.Write(out) out.write(self.block_total_length_last_packed) def __repr__(self): ret = "" ret += "Block Type: 0x%08x (Section Header)\n" % (self.block_type_int) ret += "Block Total Length First: %d\n" % ( self.block_total_length_first_int) ret += "Block Total Length Last: %d\n" % ( self.block_total_length_last_int) if self.byte_order_packed == "\x1a\x2b\x3c\x4d": ret += "Byte Order: 0x%s (Big-Endian)\n" % (binascii.hexlify( self.byte_order_packed)) elif self.byte_order_packed == "\x4d\x3c\x2b\x1a": ret += "Byte Order: 0x%s (Little-Endian)\n" % (binascii.hexlify( self.byte_order_packed)) else: ret += "Byte Order: 0x%s (Unknown)\n" % (binascii.hexlify( self.byte_order_packed)) ret += "Version: %d.%d\n" % (self.major_version_int, self.minor_version_int) if self.section_length_int == -1: ret += "Section Length: %d (Not Specified)\n" % ( self.section_length_int) else: ret += "Section Length: %d\n" % (self.section_length_int) if self.options: ret += "Options\n" ret += "\t%s\n" % (("%s" % self.options).replace("\n", "\n\t")) return ret[:-1]