首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Packet32 網路監聽開發包函數參考(四):封包過濾、緩衝區、超時與統計

     編輯:關於VC++

系列說明

本系列詳細解析 Packet32(WinPcap 核心層)的 API 與資料結構。前三篇已涵蓋封包獲取、介面卡列舉、資料結構定義。本文聚焦 硬體過濾器、核心緩衝區、讀取超時、封包記憶體管理、封包接收與統計 六大核心函數。

3. PacketSetHwFilter — 設定網卡硬體過濾模式


BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject, ULONG Filter);

常用 Filter 常數(定義於 ntddndis.h):

常數用途
NDIS_PACKET_TYPE_PROMISCUOUS混雜模式:接收所有封包(監聽核心)
NDIS_PACKET_TYPE_DIRECTED僅接收發給本機 MAC 的單播封包
NDIS_PACKET_TYPE_BROADCAST僅接收廣播封包
NDIS_PACKET_TYPE_MULTICAST接收本機加入之多播群組封包
NDIS_PACKET_TYPE_ALL_MULTICAST接收所有多播封包
NDIS_PACKET_TYPE_ALL_LOCAL接收所有本地封包

實作:填充 PACKET_OID_DATA 的 Oid = OID_GEN_CURRENT_PACKET_FILTER、Data = Filter,呼叫 PacketRequest 下發 OID 請求。

4. PacketSetBuff — 設定核心層捕獲緩衝區大小


BOOLEAN PacketSetBuff(LPADAPTER AdapterObject, int dim); // dim: bytes

關鍵行為:

  • 重設緩衝區會丟棄舊緩衝區內所有未讀封包
  • 預設大小為 0,必須在開啟介面卡後立即設定適當值(建議 1 MB)
  • 過小 → 高負載丟包;過大 → 佔用非分頁池記憶體

實作:DeviceIoControl(hFile, pBIOCSETBUFFERSIZE, ...),控制碼 #define pBIOCSETBUFFERSIZE 9592。

5. PacketSetReadTimeout — 設定讀取超時時間


BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject, int timeout); // ms

特殊值語意:

  • 0:永不超時(封包到達前永久阻塞)
  • -1:立即返回(非阻塞輪詢)
  • >0:毫秒級超時,超時喚醒 ReadEvent

亦用於統計模式下的報告間隔控制。實作同樣透過 DeviceIoControl 送控制碼。

6. PacketAllocatePacket / PacketInitPacket — 封包記憶體管理


LPPACKET PacketAllocatePacket(void); // 僅配置 _PACKET 結構
VOID PacketInitPacket(LPPACKET lpPacket, PVOID Buffer, UINT Length); // 關聯使用者緩衝區

設計哲學:分離結構配置與資料緩衝,允許應用層自行管理大緩衝區(如 256 KB),一次 PacketReceivePacket 可讀回多個封包,大幅減少系統呼叫開銷。

7. PacketReceivePacket — 核心讀取入口


BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject, LPPACKET lpPacket, BOOLEAN Sync);

流程:

  1. 檢查 AdapterObject->ReadTimeOut:
  2. 非 -1 → WaitForSingleObject(ReadEvent, ReadTimeOut)
  3. -1 → 略過等待
  4. 呼叫 ReadFile 讀取驅動程式緩衝區資料

返回資料:lpPacket->Buffer 含一或多個封包(含 bpf_hdr 頭),lpPacket->Length 為實際位元組數。統計模式下則回傳 bpf_stat 結構。

8. PacketGetStats — 取得捕獲統計


BOOLEAN PacketGetStats(LPADAPTER AdapterObject, struct bpf_stat* s);

bpf_stat 關鍵欄位:

  • bs_recv:驅動程式從網卡收到的總封包數(含驅動丟棄)
  • bs_drop:驅動緩衝區滿導致丟棄的封包數
  • bs_capt:通過 BPF 過濾器的封包數

實作:DeviceIoControl(pBIOCGSTATS) 取得完整結構後擷取上述三欄位。

9. PacketCloseAdapter — 關閉介面卡


VOID PacketCloseAdapter(LPADAPTER lpAdapter);

依序執行:CloseHandle(hFile) → SetEvent/CloseHandle(ReadEvent) → 解鎖並釋放 ADAPTER 結構記憶體。

開發建議

  1. 開啟介面卡後立即呼叫 PacketSetBuff(1024*1024) 避免高流量丟包
  2. GUI 應用請設定 PacketSetReadTimeout(100~500) 並搭配 ReadEvent 以 MsgWaitForMultipleObjects 整合訊息迴圈
  3. 大量封包處理時,配置 ≥ 256 KB 使用者緩衝區並呼叫 PacketInitPacket
  4. 定期呼叫 PacketGetStats 監控 bs_drop,動態調整緩衝區或優化過濾器
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved