Frame readPacketBlock() // an obsolete type but we may see it { blockStart = r.BaseStream.Position - 4; blockLength = r.ReadUInt32(); nextBlockStart = blockStart + blockLength; Frame nf = null; UInt16 InterfaceID = read2Bytes(); // InterfaceID is 0-based UInt16 DropsCount = read2Bytes(); UInt32 timestampHi = read4Bytes(); UInt32 timestampLo = read4Bytes(); UInt32 capturedLen = read4Bytes(); UInt32 packetLen = read4Bytes(); InterfaceOptions intOpt = (InterfaceOptions)(interfaceOptions[InterfaceID]); frameNumber++; nf = new Frame(); nf.frameLength = packetLen; nf.bytesAvailable = capturedLen; nf.frameNumber = frameNumber; nf.length = capturedLen; nf.ticks = timeToTicks(timestampHi, timestampLo, intOpt.timeResolution, intOpt.timestampOffset); nf.data = r.ReadBytes((Int32)capturedLen); nf.linkType = (UInt16)intOpt.LinkType; // Seek to beginning of the next block r.BaseStream.Seek(nextBlockStart, SeekOrigin.Begin); return(nf); }
Frame readSimplePacketBlock() // not supported because it does not contain a timestamp { blockStart = r.BaseStream.Position - 4; blockLength = r.ReadUInt32(); nextBlockStart = blockStart + blockLength; if (interfaceOptions == null || interfaceOptions.Count == 0) { throw new Exception("Invalid PCAPNG file. Simple Packet Block at offset " + blockStart + " not allowed. Section at offset " + sectionStart + " has no Interface Description Blocks."); } if (interfaceOptions.Count > 1) { throw new Exception("Invalid PCAPNG file. Simple Packet Block at offset " + blockStart + " not allowed. Section at offset " + sectionStart + " has more than one Interface Description Block."); } // does not have timestamps, so we really do not want these ... InterfaceOptions intOpt = (InterfaceOptions)(interfaceOptions[0]); if (intOpt.LinkType == 1) // Ethernet - return null for all others { throw new Exception("Simple Packet Block not allowed since it does not contain any timestamp information."); } // ignore the block if not Ethernet - perhaps a new section will have Ethernet traffic // Seek to beginning of the next block r.BaseStream.Seek(nextBlockStart, SeekOrigin.Begin); return(null); }
Frame readEnahancedPacketBlock() { blockStart = r.BaseStream.Position - 4; blockLength = r.ReadUInt32(); nextBlockStart = blockStart + blockLength; // // The main change from readPacketBlock and readEnhancedPacketBlock is that the InterfaceID is now 32-bits instead of 16 bits // and we no longer read the number of dropped packets (16 bite) as part of the block header. For dropped packet count, need to // read packet options after the frame data: OptID = 4, OptLen = 8 // // See readInterfaceBlock for implementation details. // Need to find the remainder for the frame data to align to DWORD boundary before reading options. // Frame nf = null; UInt32 InterfaceID = read4Bytes(); // InterfaceID is 0-based UInt32 timestampHi = read4Bytes(); UInt32 timestampLo = read4Bytes(); UInt32 capturedLen = read4Bytes(); UInt32 packetLen = read4Bytes(); InterfaceOptions intOpt = (InterfaceOptions)(interfaceOptions[(Int32)InterfaceID]); if (intOpt.LinkType == 1) // Ethernet - return null for all others { frameNumber++; nf = new Frame(); nf.frameLength = packetLen; nf.bytesAvailable = capturedLen; nf.frameNumber = frameNumber; nf.length = capturedLen; nf.ticks = timeToTicks(timestampHi, timestampLo, intOpt.timeResolution, intOpt.timestampOffset); nf.data = r.ReadBytes((Int32)capturedLen); } // Seek to beginning of the next block r.BaseStream.Seek(nextBlockStart, SeekOrigin.Begin); return(nf); }
void readInterfaceBlock() { // // There must be at least one of these following the header block and before the first packet block. // According to the spec, it must be immediately following, but the app doesn't care as long as we haven't hit a packet without a corresponding entry. // // We only support Ethernet (LinkType = InterfaceID = 1). All other packet blocks are ignored. // // For Simple Packet blocks, there must be 1 and only 1 Interface block in that section. Other packet types have the InterfaceID == LinkType in them. // We do not support Simple Packet blocks because they do not contain a timestamp. // blockStart = r.BaseStream.Position - 4; blockLength = r.ReadUInt32(); nextBlockStart = blockStart + blockLength; InterfaceOptions intOpt = new InterfaceOptions(); intOpt.LinkType = read2Bytes(); read2Bytes(); // skip unused portion of block intOpt.maxBytesRead = read4Bytes(); interfaceOptions.Add(intOpt); // read interface options UInt16 OptType = 0; UInt16 OptLen = 0; int padding = 0; if (blockLength > 40) { OptType = read2Bytes(); OptLen = read2Bytes(); padding = OptLen % 4; while (OptType != 0) { switch (OptType) { case 9: { intOpt.timeResolution = r.ReadByte(); r.ReadBytes(padding); break; } case 14: { intOpt.timestampOffset = (Int32)read8Bytes(); break; } default: // skip unhandled option types { r.ReadBytes(OptLen + padding); break; } } OptType = read2Bytes(); OptLen = read2Bytes(); padding = OptLen % 4; } } // Seek to beginning of the next block r.BaseStream.Seek(nextBlockStart, SeekOrigin.Begin); }