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

Winpcap 程式設計實戰:ARP 封包構造發送與捕獲解析完整範例

     編輯:關於C語言

Winpcap 程式設計實戰:ARP 封包構造發送與捕獲解析完整範例

Winpcap (Windows Packet Capture) 提供底層網路封包捕獲/發送 API。本文實現兩大功能:構造發送 ARP 請求/應答、捕獲解析網路上 ARP 封包,完整代碼可編譯運行。

一、ARP 封包格式

以太網頭 (14B) + ARP 載荷 (28B) = 42B 最小封包
以太網頭:目的 MAC(6) + 來源 MAC(6) + 類型(2, 0x0806=ARP)
ARP 載荷:
  硬體類型(2, 1=乙太網) | 協議類型(2, 0x0800=IPv4)
  硬體長度(1, 6) | 協議長度(1, 4)
  操作碼(2, 1=請求 2=應答)
  發送端 MAC(6) | 發送端 IP(4)
  目標 MAC(6)   | 目標 IP(4)

二、關鍵 Winpcap API

三、功能 1:構造並發送 ARP 封包

// 參數: src_ip dst_ip src_mac flag(1=請求 2=應答)
int main(int argc, char **argv) {
    u_char pkt[100] = {0};
    // 1. 列舉網卡選擇
    pcap_if_t *alldevs; pcap_findalldevs(&alldevs, errbuf);
    // ... 選擇介面 inum ...
    pcap_t *ad = pcap_open_live(dev->name, 65536, 1, 1000, errbuf);

    // 2. 填充以太網頭
    if (flag==1) { // 請求: 目的 MAC 全 FF
        memset(pkt, 0xFF, 6);
        mac_str_to_bytes(argv[3], pkt+6);   // 來源 MAC
        mac_str_to_bytes(argv[3], pkt+22);  // ARP 發送端 MAC
    } else { // 應答: 目的 MAC = 指定 MAC
        mac_str_to_bytes(argv[3], pkt);     // 目的 MAC
        memset(pkt+6, 0, 6);                // 來源 MAC 暫 0
        mac_str_to_bytes(argv[3], pkt+32);  // ARP 目標 MAC
        mac_str_to_bytes(argv[3], pkt+22);  // ARP 發送端 MAC
    }
    pkt[12]=0x08; pkt[13]=0x06; // EtherType=ARP

    // 3. 填充 ARP 載荷
    pkt[14]=0x00; pkt[15]=0x01; // 硬體類型
    pkt[16]=0x08; pkt[17]=0x00; // 協議類型
    pkt[18]=0x06; pkt[19]=0x04; // 長度
    pkt[20]=0x00; pkt[21]=flag; // 操作碼
    ip_str_to_bytes(argv[1], pkt+28); // 發送端 IP
    ip_str_to_bytes(argv[2], pkt+38); // 目標 IP

    // 4. 發送
    pcap_sendpacket(ad, pkt, 64);
    pcap_close(ad);
}

四、功能 2:捕獲解析 ARP 封包

// 參數: 日誌檔名
int main(int argc, char *argv[]) {
    FILE *log = fopen(argv[1], "a");
    pcap_if_t *alldevs; pcap_findalldevs(&alldevs, errbuf);
    // ... 選擇介面 ...
    pcap_t *ad = pcap_open_live(dev->name, 65536, 1, 1000, errbuf);
    
    // 設置 BPF 過濾器僅捕獲 ARP
    struct bpf_program fp;
    pcap_compile(ad, &fp, "arp", 1, netmask);
    pcap_setfilter(ad, &fp);

    struct pcap_pkthdr *hdr; const u_char *data;
    while (pcap_next_ex(ad, &hdr, &data) >= 0) {
        // 跳過以太網頭 14B
        struct arp_pkt *arp = (struct arp_pkt*)(data + 14);
        // 解析並輸出到螢幕與日誌
        log_arp(arp, hdr->ts, log);
    }
    fclose(log); pcap_close(ad);
}

五、編譯與運行

# 安裝 Winpcap 開發包 (含 wpcap.lib, Packet.lib)
# VC++ 編譯
cl /I "C:\WpdPack\Include" arp_send.c /link "C:\WpdPack\Lib\wpcap.lib" "C:\WpdPack\Lib\Packet.lib" ws2_32.lib
cl /I "C:\WpdPack\Include" arp_capture.c /link "C:\WpdPack\Lib\wpcap.lib" "C:\WpdPack\Lib\Packet.lib" ws2_32.lib

# 運行發送 (需管理員權限)
arp_send.exe 192.168.1.100 192.168.1.1 00-11-22-33-44-55 1
# 運行捕獲
arp_capture.exe arp.log

六、Wireshark 驗證

啟動 Wireshark 捕獲對應網卡,過濾 arp,可見發送的 ARP 請求/應答封包,欄位解析與代碼構造一致。

注意事項

  • Winpcap 已停止維護,新專案建議使用 **Npcap** (相容 Winpcap API,支援 Win10/11、回環捕獲)。
  • 發送原始封包需管理員權限 / `SeEnableDelegationPrivilege`。
  • MAC 地址字串解析需處理大小寫、分隔符 (:, -, 空格)。
  • 校驗和計算:ARP 無校驗和,以太網 CRC 由網卡硬體自動生成。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數用途
pcap_findalldevs列舉網卡,獲取 pcap_if_t 鏈表
pcap_open_live開啟網卡捕獲/發送句柄 (promiscuous 模式)
pcap_sendpacket發送原始封包
pcap_next_ex捕獲下一個封包 (非阻塞/超時)
pcap_compile / pcap_setfilter編譯/設置 BPF 過濾器 (如 "arp")
pcap_close關閉句柄釋放資源