開發者嘗試將抓取的網絡數據包(十六進制字符串)直接寫入 .pcap 文件,期望用 Wireshark 打開分析。但直接寫入原始數據包缺少 PCAP 文件頭與數據包頭,導致 Wireshark 報錯「數據包過大」或解析失敗。
+-------------------+ | Global Header (24 bytes) | // 文件全局頭:魔數、版本、時區、鏈路層類型等 +-------------------+ | Packet Header 1 (16 bytes) | // 第 1 個數據包頭:時間戳、捕獲長度、原始長度 +-------------------+ | Packet Data 1 (variable) | // 第 1 個數據包內容 +-------------------+ | Packet Header 2 (16 bytes) | +-------------------+ | Packet Data 2 (variable) | +-------------------+ ...
放棄手工拼接二進制結構,直接調用成熟庫函數,保證格式完全合規。
pcap_open_dead() 創建離線保存句柄(指定鏈路層類型 DLT_EN10MB)。pcap_dump_open() 打開輸出文件獲取 dumper。struct pcap_pkthdr(時間戳、捕獲長度、原始長度)。pcap_dump() 寫入數據包頭與數據。pcap_dump_close() 關閉文件。#include
// 假設 raw_data 指向完整以太網幀,长度为 data_len
pcap_t *pd = pcap_open_dead(DLT_EN10MB, 65535); // 鏈路層類型、最大捕獲長度
if (!pd) { fprintf(stderr, "pcap_open_dead failed\n"); return -1; }
pcap_dumper_t *dumper = pcap_dump_open(pd, "output.pcap");
if (!dumper) { fprintf(stderr, "pcap_dump_open failed\n"); pcap_close(pd); return -1; }
struct pcap_pkthdr hdr;
hdr.ts.tv_sec = time(NULL); // 秒級時間戳
hdr.ts.tv_usec = 0; // 微秒
hdr.caplen = data_len; // 捕獲長度
hdr.len = data_len; // 原始長度
pcap_dump((u_char *)dumper, &hdr, raw_data); // 寫入
pcap_dump_close(dumper);
pcap_close(pd);
用戶提到使用 netsh trace 生成 .etl 文件,需解析 ETL 獲取數據包與進程 ID。建議:
Microsoft-Windows-TCPIP (GUID: {9A280AC0-C8E0-11D1-84E2-00C04FB998A2}) 包含網絡發送/接收事件,負載中含完整幀數據與 PID。核心教訓: 任何涉及標準文件格式(PCAP、ELF、ZIP、PNG...)的生成,**務必使用成熟庫**,手工拼接二進制結構極易踩坑且難維護。