public static EnhancedPacketBlock Parse(BaseBlock baseBlock, Action <Exception> ActionOnException) { CustomContract.Requires <ArgumentNullException>(baseBlock != null, "BaseBlock cannot be null"); CustomContract.Requires <ArgumentNullException>(baseBlock.Body != null, "BaseBlock.Body cannot be null"); CustomContract.Requires <ArgumentException>(baseBlock.BlockType == BaseBlock.Types.EnhancedPacket, "Invalid packet type"); long positionInStream = baseBlock.PositionInStream; using (Stream stream = new MemoryStream(baseBlock.Body)) { using (BinaryReader binaryReader = new BinaryReader(stream)) { int interfaceID = binaryReader.ReadInt32().ReverseByteOrder(baseBlock.ReverseByteOrder); byte[] timestamp = binaryReader.ReadBytes(8); var timestampHelper = new TimestampHelper(timestamp, baseBlock.ReverseByteOrder); int capturedLength = binaryReader.ReadInt32().ReverseByteOrder(baseBlock.ReverseByteOrder); int packetLength = binaryReader.ReadInt32().ReverseByteOrder(baseBlock.ReverseByteOrder); byte[] data = binaryReader.ReadBytes(capturedLength); if (data.Length < capturedLength) { throw new EndOfStreamException("Unable to read beyond the end of the stream"); } int remainderLength = (int)capturedLength % BaseBlock.AlignmentBoundary; if (remainderLength > 0) { int paddingLength = BaseBlock.AlignmentBoundary - remainderLength; binaryReader.ReadBytes(paddingLength); } var option = EnhancedPacketOption.Parse(binaryReader, baseBlock.ReverseByteOrder, ActionOnException); var enhancedBlock = new EnhancedPacketBlock(interfaceID, timestampHelper, packetLength, data, option, positionInStream); return(enhancedBlock); } } }
/// <summary> /// An Enhanced Packet Block is the standard container for storing the packets coming from the network. The Enhanced Packet Block /// is optional because packets can be stored either by means of this block or the Simple Packet Block, which can be used to speed /// up dump generation. /// The Enhanced Packet Block is an improvement over the original Packet Block: /// it stores the Interface Identifier as a 32bit integer value. This is a requirement when a capture stores packets coming from /// a large number of interfaces differently from the Packet Block, the number of packets dropped by the capture system between /// this packet and the previous one is not stored in the header, but rather in an option of the block itself. /// </summary> public EnhancedPacketBlock(int InterfaceID, TimestampHelper Timestamp, int PacketLength, byte[] Data, EnhancedPacketOption Options, long PositionInStream = 0) { CustomContract.Requires <ArgumentNullException>(Timestamp != null, "Timestamp cannot be null"); CustomContract.Requires <ArgumentNullException>(Options != null, "Options cannot be null"); CustomContract.Requires <ArgumentNullException>(Data != null, "Data cannot be null"); this.InterfaceID = InterfaceID; this.Timestamp = Timestamp; this.PacketLength = PacketLength; this.data = Data; this.options = Options; this.PositionInStream = PositionInStream; }