本文提供一個完整的 C/C++ 控制台程式範例,展示如何在 Windows 上使用 Raw Socket (SOCK_RAW, IPPROTO_IP) 捕獲本機網卡經過的所有 IP 封包,並解析 IP、TCP、UDP、ICMP 標頭與資料載荷。程式支援協議過濾、IP 過濾、埠號過濾、敏感字串搜尋與資料十六進位/ASCII 轉傳。
WSAStartup(MAKEWORD(2,2), ...)。socket(AF_INET, SOCK_RAW, IPPROTO_IP) 需系統管理員權限。gethostbyname → 綁定任一本機 IP。WSAIoctl(s, SIO_RCVALL, ...) 讓網卡接收所有封包(非僅本機)。recvfrom → DecodeIpPack → 依協議分派 DecodeTcpPack/UdpPack/IcmpPack。// IP 標頭 (最小 20 bytes)
typedef struct _iphdr {
unsigned char h_lenver; // 4-bit 版本 + 4-bit 首部長度(單位:4 bytes)
unsigned char tos;
unsigned short total_len;
unsigned short ident;
unsigned short frag_and_flags;
unsigned char ttl;
unsigned char proto; // 協議號: 1=ICMP, 6=TCP, 17=UDP
unsigned short checksum;
unsigned int sourceIP;
unsigned int destIP;
} IP_HEADER;
// TCP 標頭 (最小 20 bytes)
typedef struct _tcphdr {
unsigned short th_sport; // 來源埠
unsigned short th_dport; // 目的埠
unsigned int th_seq; // 序號
unsigned int th_ack; // 確認號
unsigned char th_lenres; // 4-bit 首部長度 + 6-bit 保留
unsigned char th_flag; // 6-bit 旗標 (FIN,SYN,RST,PSH,ACK,URG)
unsigned short th_win; // 視窗大小
unsigned short th_sum; // 檢驗和
unsigned short th_urp; // 緊急指標
} TCP_HEADER;
// UDP 標頭 (固定 8 bytes)
typedef struct _udphdr {
unsigned short uh_sport;
unsigned short uh_dport;
unsigned short uh_len; // UDP 長度(含標頭)
unsigned short uh_sum;
} UDP_HEADER;
// ICMP 標頭
typedef struct _icmphdr {
unsigned char i_type; // 類型 (0=Echo Reply, 8=Echo Request, 3=Destination Unreachable...)
unsigned char i_code; // 代碼
unsigned short i_cksum;
unsigned short i_id; // 識別碼
unsigned short i_seq; // 序號
unsigned long timestamp; // 時間戳 (選用)
} ICMP_HEADER;
h_lenver & 0x0F 計算首部長度 (IHL × 4 bytes)。proto 決定上層協議。inet_ntoa 轉點分十進位。(th_lenres >> 4) × 4 bytes。FIN(0x01), SYN(0x02), RST(0x04), PSH(0x08), ACK(0x10), URG(0x20)。-p 參數啟用載荷轉傳 (ASCII 可列印字元顯示字元,其餘顯示 Hex)。-o 指定類型碼)。-p 載荷十六進位/ASCII 混合轉傳。| 參數 | 功能 | 範例 |
|---|---|---|
| /t | 顯示 TCP 封包 | /t |
| /u | 顯示 UDP 封包 | /u |
| /i | 顯示 ICMP 封包 | /i |
| /p | 啟用載荷解碼轉傳 | /p |
| /f:IP | 來源 IP 過濾 | /f:192.168.1.100 |
| /d:IP | 目的 IP 過濾 | /d:8.8.8.8 |
| /s:STR | TCP 載荷敏感字串 | /s:PASS |
| /o:PORT | 埠號/ICMP 類型過濾 | /o:80 |
ws2_32.lib。SIO_RCVALL 會失敗 (錯誤 10013 WSAEACCES)。#include <winsock2.h>, <mstcpip.h>, <stdio.h>, <string.h>, <math.h>
// 定義常數、結構體、全域變數、函數原型
// main(): 初始化 -> 建立 Raw Socket -> 綁定 -> SIO_RCVALL -> while(1) recv -> 解析
// DecodeIpPack(): IP標頭解析、過濾、分派
// DecodeTcpPack/UdpPack/IcmpPack(): 各協議詳細解析與格式化輸出
// CheckProtocol(): 協議號對應名稱
// GetCmdLine(): 命令列解析
// usage(): 顯示說明
// CheckSockError(): 統一錯誤處理
原始套接字偵聽屬於網路監控/分析工具,僅限於:
現代加密協議 (TLS 1.2/1.3, SSH, VPN, QUIC) 的應用層資料已加密,本工具僅能見明文協議 (HTTP, FTP, Telnet, DNS 查詢等) 或加密封包的中繼資料。