| 函數 | 用途 |
pcap_findalldevs | 列舉網卡,獲取 pcap_if_t 鏈表 |
pcap_open_live | 開啟網卡捕獲/發送句柄 (promiscuous 模式) |
pcap_sendpacket | 發送原始封包 |
pcap_next_ex | 捕獲下一個封包 (非阻塞/超時) |
pcap_compile / pcap_setfilter | 編譯/設置 BPF 過濾器 (如 "arp") |
pcap_close | 關閉句柄釋放資源 |
三、功能 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 由網卡硬體自動生成。
- 上一篇文章: C 語言程式設計考題筆記(上):基礎知識、程式結構、標識符常量變量、資料類型
- 下一篇文章: C 語言柔性數組:結構體中 char data[0] 的深度解析與實戰應用
Copyright ©
程式碼之家 All Rights Reserved