mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns/PcapNG: Rewrite hexpat for bugfixing (#462)
PcapNG: Rewrite hexpat. Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
@@ -1,39 +1,27 @@
|
||||
#pragma description PcapNG
|
||||
#pragma MIME application/vnd.tcpdump.pcapng
|
||||
#pragma author 5h4rrK
|
||||
|
||||
import std.mem;
|
||||
import std.core;
|
||||
import std.math;
|
||||
import std.io;
|
||||
#pragma author Antonio Vázquez Blanco
|
||||
|
||||
#define MAX_VALUE_U64 0xffffffffffffffff
|
||||
|
||||
fn format_version(auto version){
|
||||
return std::format(
|
||||
"{}.{}", version.major, version.minor
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
fn is_valid_len(auto val){
|
||||
if (val == MAX_VALUE_U64){
|
||||
return std::format("[Not Specified]");
|
||||
}
|
||||
else{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
import std.mem;
|
||||
import std.core;
|
||||
import std.io;
|
||||
|
||||
enum PcapOrder : u32{
|
||||
Little = 0x1a2b3c4d,
|
||||
Big = 0x4d3c2b1a,
|
||||
};
|
||||
|
||||
struct Version {
|
||||
u16 major;
|
||||
u16 minor;
|
||||
};
|
||||
// Perform a read to get the endianness of the file and set
|
||||
// the default endianness acordingly.
|
||||
u32 order = std::mem::read_unsigned(0x8, 0x4);
|
||||
if (order == PcapOrder::Little) {
|
||||
std::core::set_endian(std::mem::Endian::Little);
|
||||
} else {
|
||||
std::core::set_endian(std::mem::Endian::Big);
|
||||
}
|
||||
|
||||
enum BlockType : u32{
|
||||
// Mandatory Blocks
|
||||
@@ -79,6 +67,119 @@ enum BlockType : u32{
|
||||
|
||||
};
|
||||
|
||||
enum SHBType : u16 {
|
||||
EndOfOpt = 0x0,
|
||||
Hardware = 0x2,
|
||||
OS = 0x3,
|
||||
Application = 0x4,
|
||||
EndOfOpt = 0x0
|
||||
};
|
||||
|
||||
enum IDHType : u16 {
|
||||
EndOfOpt = 0,
|
||||
Name = 2, // UTF-8 device name (e.g., "eth0")
|
||||
Description = 3, // UTF-8 device description
|
||||
IPv4Addr = 4, // IPv4 address + netmask (8 bytes)
|
||||
IPv6Addr = 5, // IPv6 address + prefix len (17 bytes)
|
||||
MACAddr = 6, // MAC address (6 bytes)
|
||||
EUIAddr = 7, // EUI-64 address (8 bytes)
|
||||
Speed = 8, // Interface speed (bps, 8 bytes)
|
||||
TimestampRes = 9, // Timestamp resolution (1 byte)
|
||||
TimeZone = 10, // Time zone (4 bytes)
|
||||
Filter = 11, // Capture filter string
|
||||
OS = 12, // OS name (UTF-8 string)
|
||||
FCSLength = 13, // Frame Check Sequence length (1 byte)
|
||||
TimestampOffset = 14, // Timestamp offset (8 bytes)
|
||||
Hardware = 15, // Variable length
|
||||
TxSpeed = 16, // 8bytes
|
||||
RxSpeed = 17 // 8bytes
|
||||
};
|
||||
|
||||
enum NameResolutionType: u16 {
|
||||
EndOfRecord = 0x00,
|
||||
IPv4 = 0x01,
|
||||
IPv6 = 0x02
|
||||
};
|
||||
|
||||
enum InterfaceStatsType : u16 {
|
||||
EndOfOpt = 0,
|
||||
Comment = 1, // isb_comment
|
||||
StartTime = 2, // isb_starttime
|
||||
EndTime = 3, // isb_endtime
|
||||
IfRecv = 4, // isb_ifrecv
|
||||
IfDrop = 5, // isb_ifdrop
|
||||
FilterAccept = 6, // isb_filteraccept
|
||||
OSdrop = 7, // isb_osdrop
|
||||
UserDeliver = 8, // isb_usrdeliv
|
||||
};
|
||||
|
||||
enum EnhancedPacketType : u16 {
|
||||
EndOfOpt = 0x0,
|
||||
Flags = 0x2,
|
||||
Hash = 0x3,
|
||||
DropCount = 0x4,
|
||||
PacketId = 0x5,
|
||||
Queue = 0x6,
|
||||
Verdict = 0x7,
|
||||
};
|
||||
|
||||
enum PacketBlockType : u16 {
|
||||
Flags = 0x2,
|
||||
Hash = 0x3,
|
||||
EndOfOpt = 0x0,
|
||||
};
|
||||
|
||||
struct Option {
|
||||
if (this.parent.block_type == BlockType::SectionHeader) {
|
||||
SHBType option_type;
|
||||
} else if(this.parent.block_type == BlockType::InterfaceDesc) {
|
||||
IDHType option_type;
|
||||
} else if (this.parent.block_type == BlockType::NameResolution) {
|
||||
NameResolutionType record_type[[name("record")]];
|
||||
} else if (this.parent.block_type == BlockType::InterfaceStats){
|
||||
InterfaceStatsType option_type;
|
||||
} else if (this.parent.block_type == BlockType::EnhancedPacket) {
|
||||
EnhancedPacketType option_type;
|
||||
} else if (this.parent.block_type == BlockType::Packet){
|
||||
PacketBlockType option_type;
|
||||
}
|
||||
u16 option_len;
|
||||
|
||||
if (option_len > 0){
|
||||
char data[option_len];
|
||||
} else{
|
||||
return;
|
||||
}
|
||||
u8 pad_size = (4 - ( $ % 4 )) % 4;
|
||||
$ = $ + pad_size;
|
||||
};
|
||||
|
||||
struct Version {
|
||||
u16 major;
|
||||
u16 minor;
|
||||
};
|
||||
|
||||
fn format_version(auto version){
|
||||
return std::format(
|
||||
"{}.{}", version.major, version.minor
|
||||
);
|
||||
};
|
||||
|
||||
fn is_valid_len(auto val){
|
||||
if (val == MAX_VALUE_U64){
|
||||
return std::format("[Not Specified]");
|
||||
}
|
||||
else{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
struct SectionHeaderBlockBody {
|
||||
PcapOrder sectionbyteorder;
|
||||
Version version [[name("Version"), format("format_version")]];
|
||||
u64 section_len [[name("SectionLen"), format("is_valid_len")]];
|
||||
};
|
||||
|
||||
enum LinkType : u16 {
|
||||
LINKTYPE_NULL = 0,
|
||||
LINKTYPE_ETHERNET = 1,
|
||||
@@ -196,335 +297,104 @@ enum LinkType : u16 {
|
||||
LINKTYPE_ETW = 290
|
||||
};
|
||||
|
||||
enum SHBType : u16{
|
||||
EndOfOpt = 0x0,
|
||||
Hardware = 0x2,
|
||||
OS = 0x3,
|
||||
Application = 0x4,
|
||||
EndOfOpt = 0x0
|
||||
};
|
||||
|
||||
enum IDHType : u16 {
|
||||
EndOfOpt = 0,
|
||||
Name = 2, // UTF-8 device name (e.g., "eth0")
|
||||
Description = 3, // UTF-8 device description
|
||||
IPv4Addr = 4, // IPv4 address + netmask (8 bytes)
|
||||
IPv6Addr = 5, // IPv6 address + prefix len (17 bytes)
|
||||
MACAddr = 6, // MAC address (6 bytes)
|
||||
EUIAddr = 7, // EUI-64 address (8 bytes)
|
||||
Speed = 8, // Interface speed (bps, 8 bytes)
|
||||
TimestampRes = 9, // Timestamp resolution (1 byte)
|
||||
TimeZone = 10, // Time zone (4 bytes)
|
||||
Filter = 11, // Capture filter string
|
||||
OS = 12, // OS name (UTF-8 string)
|
||||
FCSLength = 13, // Frame Check Sequence length (1 byte)
|
||||
TimestampOffset = 14, // Timestamp offset (8 bytes)
|
||||
Hardware = 15, // Variable length
|
||||
TxSpeed = 16, // 8bytes
|
||||
RxSpeed = 17 // 8bytes
|
||||
};
|
||||
|
||||
enum NameResolutionType: u16 {
|
||||
EndOfRecord = 0x00,
|
||||
IPv4 = 0x01,
|
||||
IPv6 = 0x02
|
||||
};
|
||||
|
||||
enum InterfaceStatsType : u16 {
|
||||
EndOfOpt = 0,
|
||||
Comment = 1, // isb_comment
|
||||
StartTime = 2, // isb_starttime
|
||||
EndTime = 3, // isb_endtime
|
||||
IfRecv = 4, // isb_ifrecv
|
||||
IfDrop = 5, // isb_ifdrop
|
||||
FilterAccept = 6, // isb_filteraccept
|
||||
OSdrop = 7, // isb_osdrop
|
||||
UserDeliver = 8, // isb_usrdeliv
|
||||
};
|
||||
|
||||
enum EnhancedPacketType : u16 {
|
||||
EndOfOpt = 0x0,
|
||||
Flags = 0x2,
|
||||
Hash = 0x3,
|
||||
DropCount = 0x4,
|
||||
PacketId = 0x5,
|
||||
Queue = 0x6,
|
||||
Verdict = 0x7,
|
||||
};
|
||||
|
||||
enum PacketBlockType : u16 {
|
||||
Flags = 0x2,
|
||||
Hash = 0x3,
|
||||
EndOfOpt = 0x0,
|
||||
};
|
||||
|
||||
|
||||
struct Option {
|
||||
|
||||
if (this.parent.block_type == BlockType::SectionHeader) {
|
||||
SHBType option_type;
|
||||
} else if(this.parent.block_type == BlockType::InterfaceDesc) {
|
||||
IDHType option_type;
|
||||
} else if (this.parent.block_type == BlockType::NameResolution) {
|
||||
NameResolutionType record_type[[name("record")]];
|
||||
} else if (this.parent.block_type == BlockType::InterfaceStats){
|
||||
InterfaceStatsType option_type;
|
||||
} else if (this.parent.block_type == BlockType::EnhancedPacket) {
|
||||
EnhancedPacketType option_type;
|
||||
} else if (this.parent.block_type == BlockType::Packet){
|
||||
PacketBlockType option_type;
|
||||
}
|
||||
u16 option_len;
|
||||
|
||||
if (option_len > 0){
|
||||
char data[option_len];
|
||||
} else{
|
||||
return;
|
||||
}
|
||||
// u8 pad_size = (4 - ( $ % 4 ));
|
||||
u8 pad_size = (4 - ( $ % 4 )) % 4;
|
||||
// if(this.parent.block_type == BlockType::InterfaceStats) {
|
||||
// std::print("Current Pos {:#x} {:#x}",$, pad_size);
|
||||
// }
|
||||
|
||||
$ = $ + pad_size;
|
||||
};
|
||||
|
||||
|
||||
struct SectionHeaderBlock {
|
||||
BlockType block_type;
|
||||
u32 length;
|
||||
PcapOrder sectionbyteorder;
|
||||
Version version [[name("Version"), format("format_version")]];
|
||||
u64 section_len [[name("SectionLen"), format("is_valid_len")]];
|
||||
u64 prev_pos = $;
|
||||
Option options [ while( $ < (prev_pos + length - 28))];
|
||||
u32 block_length [[name("BlockLen")]];
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct NameResolutionBlock {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
u64 prev_pos = $;
|
||||
Option records [ while($ < (prev_pos + block_len1 - 12)) ];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
struct SystemJournalExportBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
char data[block_len1];
|
||||
$ = $ + (4 - ($ % 4 ) ); // Padding
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
struct CustomBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
u32 pen[[name("PrivateEnterpriseNumber")]];
|
||||
char data[block_len1];
|
||||
u64 prev_pos = $;
|
||||
$ = $ + (4 - ($ % 4 ) ); // Padding
|
||||
Option options [while($ < (prev_pos + block_len1 - 16))] [[name("Options")]];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
struct InterfaceBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
struct InterfaceDescBlockBody {
|
||||
LinkType link_type [[name("LinkType")]];
|
||||
u16 reserved [[name("Reserved")]];
|
||||
u32 snap_len [[name("SnapLen")]];
|
||||
u64 prev_pos = $;
|
||||
Option options [ while( $ < (prev_pos + block_len1 - 20))];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
struct EnhancedPacketBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
struct EnhancedPacketBlockBody {
|
||||
u32 interface_id[[name("InterfaceID")]];
|
||||
u64 timestamp[[name("Timestamp")]];
|
||||
u32 captured_len[[name("CapturedLen")]];
|
||||
u32 pkt_len[[name("PacketLen")]];
|
||||
char data[captured_len][[name("Data")]];
|
||||
// 32 (BlockType + BlockLen1 + InterfaceID + Timestamp + CapturedLen + PacketLen + BlockLen2)
|
||||
$ = $ + (block_len1 - captured_len - 32);
|
||||
u64 prev_pos = $;
|
||||
// Current Pos - Prev Pos - 4 (BlockLen2)
|
||||
// std::print("Option Size :: {:#x}", ($ - prev_pos));
|
||||
if (($ - prev_pos ) > 0) {
|
||||
Option options [ while( $ < ( prev_pos + ($ - prev_pos ) ) ) ];
|
||||
}
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
|
||||
};
|
||||
|
||||
struct SimplePacketBlock {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
u32 pkt_len[[name("PacketLen")]];
|
||||
char data[[name("Data")]];
|
||||
u8 pad_size = (4 - ( $ % 4 )) % 4;
|
||||
$ = $ + pad_size;
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
// Obsolete!
|
||||
struct PacketBlock {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
u16 interface_id[[name("InterfaceID")]];
|
||||
u16 drop_count[[name("DropCount")]];
|
||||
u64 timestamp[[name("Timestamp")]];
|
||||
u32 captured_len[[name("CapturedLen")]];
|
||||
u32 pkt_len[[name("PacketLen")]];
|
||||
if (block_len1 > 32){
|
||||
char data[captured_len];
|
||||
}
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
enum CompressionType: u8 {
|
||||
Uncompressed = 0x0,
|
||||
LempelZiv = 0x1,
|
||||
Gzip = 0x2
|
||||
};
|
||||
|
||||
enum EncryptionType : u32 {
|
||||
TLS = 0x544c534b, /* TLS Key Log */
|
||||
SSH = 0x5353484b, /* SSH Key Log */
|
||||
WIREGUARD = 0x57474b4c, /* WireGuard Key Log */
|
||||
ZIGBEE_NWK_KEY = 0x5a4e574b, /* Zigbee NWK Key */
|
||||
ZIGBEE_APS_KEY = 0x5a415053 /* Zigbee APS Key */
|
||||
};
|
||||
|
||||
enum FixedLengthType : u8 {
|
||||
// Experimental
|
||||
};
|
||||
|
||||
// Experimental
|
||||
struct CompressionBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
CompressionType comp_type [[name("Compresssion")]];
|
||||
char data[block_len1];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
struct EncryptionBlock{
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
EncryptionType comp_type [[name("Encryption")]];
|
||||
u32 secrets_len[[name("SecretsLength")]];
|
||||
char data[secrets_len];
|
||||
padding[-$ & 3];
|
||||
// https://ietf-opsawg-wg.github.io/draft-ietf-opsawg-pcap/draft-ietf-opsawg-pcapng.html#section-4.7-6.6.1
|
||||
// No DSB-specific options are currently defined
|
||||
// Option options;
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
|
||||
// Experimental
|
||||
struct FixedLengthBlock {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
FixedLengthType comp_type [[name("FixedLength")]];
|
||||
char data[block_len1];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
struct NameResolutionBlockBody {
|
||||
// This block is empty, only contains options.
|
||||
};
|
||||
|
||||
struct InterfaceStatsBlock {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
u32 interface_id[[name("InterfaceID")]];
|
||||
u64 timestamp[[name("Timestamp")]];
|
||||
if(block_len1 > 24) {
|
||||
u64 prev_pos = $;
|
||||
Option options [ while( $ < (prev_pos + block_len1 - 24))];
|
||||
}
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
};
|
||||
};
|
||||
|
||||
struct PCAPng{
|
||||
if (std::mem::eof()){
|
||||
break;
|
||||
struct SimplePacketBlockBody {
|
||||
u32 pkt_len[[name("PacketLen")]];
|
||||
char data[[name("Data")]];
|
||||
};
|
||||
|
||||
// Obsolete!
|
||||
struct PacketBlockBody {
|
||||
std::print("Obsolete Packet Block Body at offset {:#x}\n", $);
|
||||
u16 interface_id[[name("InterfaceID")]];
|
||||
u16 drop_count[[name("DropCount")]];
|
||||
u64 timestamp[[name("Timestamp")]];
|
||||
u32 captured_len[[name("CapturedLen")]];
|
||||
u32 pkt_len[[name("PacketLen")]];
|
||||
if (parent.block_body_len > 20){
|
||||
char data[captured_len];
|
||||
}
|
||||
if (order == PcapOrder::Little){
|
||||
le u32 block_type = std::mem::read_unsigned($, 0x4, std::mem::Endian::Little);
|
||||
} else {
|
||||
be u32 block_type = std::mem::read_unsigned($, 0x4, std::mem::Endian::Big);
|
||||
}
|
||||
// std::print("{} , {:#x}, {:#x}", "Parsing", $, block_type);
|
||||
// std::print("Parsing : Offset({:#x}), Order({:#x}), BlockType({:#x})", $, order, block_type);
|
||||
};
|
||||
|
||||
struct CustomBlockBody {
|
||||
u32 pen[[name("PrivateEnterpriseNumber")]];
|
||||
char data[parent.block_body_len-4];
|
||||
};
|
||||
|
||||
enum EncryptionType : u32 {
|
||||
TLS = 0x544c534b, // TLS Key Log
|
||||
SSH = 0x5353484b, // SSH Key Log
|
||||
WIREGUARD = 0x57474b4c, // WireGuard Key Log
|
||||
ZIGBEE_NWK_KEY = 0x5a4e574b, // Zigbee NWK Key
|
||||
ZIGBEE_APS_KEY = 0x5a415053 // Zigbee APS Key
|
||||
};
|
||||
|
||||
struct EncryptionBlockBody {
|
||||
EncryptionType comp_type [[name("Encryption")]];
|
||||
u32 secrets_len[[name("SecretsLength")]];
|
||||
char data[secrets_len];
|
||||
};
|
||||
|
||||
struct Block {
|
||||
BlockType block_type[[name("BlockType")]];
|
||||
u32 block_len1[[name("BlockLen1")]];
|
||||
// Block body
|
||||
u32 block_body_len = block_len1-12;
|
||||
u64 block_body_end = $ + block_body_len;
|
||||
if (block_type == BlockType::SectionHeader) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le SectionHeaderBlock SHB;
|
||||
} else {
|
||||
be SectionHeaderBlock SHB;
|
||||
}
|
||||
SectionHeaderBlockBody SHB;
|
||||
} else if (block_type == BlockType::InterfaceDesc) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le InterfaceBlock IDH;
|
||||
} else {
|
||||
be InterfaceBlock IDH;
|
||||
}
|
||||
InterfaceDescBlockBody IDH;
|
||||
} else if (block_type == BlockType::EnhancedPacket) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le EnhancedPacketBlock EBP;
|
||||
} else {
|
||||
be EnhancedPacketBlock EBP;
|
||||
}
|
||||
EnhancedPacketBlockBody EBP;
|
||||
} else if (block_type == BlockType::NameResolution) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le NameResolutionBlock NRB;
|
||||
} else {
|
||||
be NameResolutionBlock NRB;
|
||||
}
|
||||
NameResolutionBlockBody NRB;
|
||||
} else if (block_type == BlockType::InterfaceStats) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le InterfaceStatsBlock ISB;
|
||||
} else {
|
||||
be InterfaceStatsBlock ISB;
|
||||
}
|
||||
InterfaceStatsBlock ISB;
|
||||
} else if (block_type == BlockType::SimplePacket) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le SimplePacketBlock SPB;
|
||||
} else {
|
||||
be SimplePacketBlock SPB;
|
||||
}
|
||||
SimplePacketBlockBody SPB;
|
||||
} else if (block_type == BlockType::Packet) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le PacketBlock PB;
|
||||
} else {
|
||||
be PacketBlock PB;
|
||||
}
|
||||
PacketBlockBody PB;
|
||||
} else if (block_type == BlockType::Custom) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le CustomBlock CB;
|
||||
} else {
|
||||
be CustomBlock CB;
|
||||
}
|
||||
CustomBlockBody CB;
|
||||
} else if (block_type == BlockType::CustomNoCopy) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le CustomBlock CBN;
|
||||
} else {
|
||||
be CustomBlock CBN;
|
||||
}
|
||||
CustomBlockBody CBN;
|
||||
} else if (block_type == BlockType::Decryption) {
|
||||
if (order == PcapOrder::Little) {
|
||||
le EncryptionBlock DSB;
|
||||
} else {
|
||||
be EncryptionBlock DSB;
|
||||
}
|
||||
EncryptionBlockBody DSB;
|
||||
} else {
|
||||
std::print("Unknown BlockType at offset {:#x}\n", $);
|
||||
break;
|
||||
char block[block_body_len][[name("Block Body Data")]];
|
||||
std::print("Unknown Block type at offset {:#x}\n", $);
|
||||
}
|
||||
} [[inline]];
|
||||
// Block body must be aligned to 32 bit (4 byte)
|
||||
std::mem::AlignTo<4>;
|
||||
// Block options
|
||||
Option options [ while( $ < block_body_end)];
|
||||
u32 block_len2[[name("BlockLen2")]];
|
||||
if (block_len1 != block_len2) {
|
||||
std::print("Inconsistent Block size at offset {:#x}\n", $);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
u32 order = std::mem::read_unsigned(0x8, 0x4);
|
||||
PCAPng PcapNG [while(!std::mem::eof())] @0x00;
|
||||
Block PcapNG [while(!std::mem::eof())] @0x00;
|
||||
Reference in New Issue
Block a user