Packet32 以三大核心結構串聯整個捕獲流程:_ADAPTER(介面卡實例)、_PACKET(封包緩衝)、_PACKET_OID_DATA(OID 控制)。輔助結構涵蓋網路位址、BPF 標頭/指令/程式/統計、傾印格式、連結層類型。本文逐欄位說明用途與典型值。
typedef struct _ADAPTER {
HANDLE hFile; // NPF 驅動程式裝置句柄 (CreateFile 返回)
CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; // 符號連結名 \\.\Packet_NPF_{GUID}
int NumWrites; // 寫入封包計數
HANDLE ReadEvent; // 讀取就緒事件 (WaitForSingleObject 等待)
UINT ReadTimeOut; // 讀取超時 (ms, 0=無限, -1=立即返回)
} ADAPTER, *LPADAPTER;
關鍵點:ReadEvent 讓 GUI 執行緒可整合訊息迴圈;ReadTimeOut 由 PacketSetReadTimeout 設定。
typedef struct _PACKET {
HANDLE hEvent; // 向後相容 (Overlapped I/O)
OVERLAPPED OverLapped; // 向後相容
PVOID Buffer; // 使用者配置的資料緩衝區指標
UINT Length; // 緩衝區總大小 (bytes)
DWORD ulBytesReceived; // 實際接收位元組數 (上次 PacketReceivePacket 填入)
BOOLEAN bIoComplete; // 向後相容
} PACKET, *LPPACKET;
使用模式:應用層 malloc 大緩衝區 → PacketAllocatePacket 配結構 → PacketInitPacket 關聯 → 重複呼叫 PacketReceivePacket。
typedef struct _PACKET_OID_DATA {
ULONG Oid; // OID 代碼 (如 OID_GEN_VENDOR_DESCRIPTION)
ULONG Length; // Data 區長度
UCHAR Data[1]; // 彈性陣列:輸入參數或輸出結果
} PACKET_OID_DATA, *PPACKET_OID_DATA;
配置時需依 Length 動態分配:malloc(sizeof(PACKET_OID_DATA) + Length - 1)。
typedef struct npf_if_addr {
struct sockaddr IPAddress; // IP 位址
struct sockaddr SubnetMask; // 子網路遮罩
struct sockaddr Broadcast; // 廣播位址
} npf_if_addr;
struct bpf_hdr {
struct timeval bh_tstamp; // 捕獲時間戳
UINT bh_caplen; // 捕獲長度 (實際存入緩衝區)
UINT bh_datalen; // 線上原始長度
USHORT bh_hdrlen; // 本標頭長度 (含對齊填充)
};
資料緩衝區布局:[bpf_hdr][封包資料...][下一個 bpf_hdr]...,需用 bh_hdrlen 定位下一個封包。
struct bpf_insn {
USHORT code; // 指令碼 (載入/跳轉/運算/返回)
UCHAR jt; // 條件真跳轉偏移
UCHAR jf; // 條件假跳轉偏移
int k; // 立即數/偏移/常數
};
由 PacketSetBPF 注入核心,對每個進入封包執行過濾。
struct bpf_program {
UINT bf_len; // 指令數
struct bpf_insn* bf_insns; // 指令陣列指標
};
struct bpf_stat {
UINT bs_recv; // 驅動收到總封包數
UINT bs_drop; // 驅動丟棄封包數 (緩衝區滿)
UINT ps_ifdrop; // 介面卡硬體丟棄 (保留欄位)
UINT bs_capt; // 通過過濾器封包數
};
struct dump_bpf_hdr {
struct timeval ts; // 時間戳
UINT caplen; // 捕獲長度
UINT len; // 原始長度
};
用於 pcap_dump 格式檔案,較 bpf_hdr 簡化。
struct NetType {
UINT LinkType; // MAC 類型 (如 NdisMedium802_3 = 以太網)
UINT LinkSpeed; // 速率 (bps, 如 100000000 = 100 Mbps)
};
由 PacketGetNetType 取得,可用於 UI 顯示介面卡能力。
sizeof 不同,傳遞指標時需確保雙方編譯選項一致bpf_hdr.bh_hdrlen 必須用於計算下一個封包位移,不可假設固定大小PACKET_OID_DATA.Data[1] 為 C99 柔性陣列成員,MSVC 需手動多配記憶體