網路監聽工具 (Sniffer) 讓管理員檢視區域網路所有傳輸封包。核心在於將網卡設為「混雜模式」,接收非本機 MAC 位址的封包。Windows 下透過「原始套接字」即可實現,無需撰寫核心驅動,本文詳細說明原理與 VC++ 實作步驟。
WSAStartup(MAKEWORD(2,2), &wsaData)。socket(AF_INET, SOCK_RAW, IPPROTO_IP) (需 Administrator 權限)。setsockopt(s, IPPROTO_IP, IP_HDRINCL, ...) 讓應用程式自行填入 IP 標頭。bind(s, (sockaddr*)&local, sizeof(local)),local.sin_addr.s_addr 設為本機 IP。WSAIoctl(s, SIO_RCVALL, &opt, sizeof(opt), NULL, 0, &dwBytes, NULL, NULL),opt=TRUE。recvfrom(s, buf, sizeof(buf), 0, &from, &fromlen) 取得完整封包 (含 IP/TCP/UDP 標頭)。IP Header 判斷協議 (TCP/UDP/ICMP),再解析對應傳輸層標頭、應用層資料。
// 1. 初始化
WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData);
// 2. 建立 Raw Socket
SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (s == INVALID_SOCKET) return;
// 3. 設定 IP_HDRINCL
BOOL bOpt = TRUE;
setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char*)&bOpt, sizeof(bOpt));
// 4. 綁定本機 IP
sockaddr_in local; local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr("192.168.1.100"); // 本機 IP
local.sin_port = 0;
bind(s, (sockaddr*)&local, sizeof(local));
// 5. 啟用混雜模式
DWORD dwBytes;
WSAIoctl(s, SIO_RCVALL, &bOpt, sizeof(bOpt), NULL, 0, &dwBytes, NULL, NULL);
// 6. 接收迴圈
char buf[65536];
sockaddr_in from; int fromlen = sizeof(from);
while (running) {
int n = recvfrom(s, buf, sizeof(buf), 0, (sockaddr*)&from, &fromlen);
if (n > 0) ParsePacket(buf, n);
}
// 7. 關閉
closesocket(s); WSACleanup();
void ParsePacket(char* buf, int len) {
IPHeader* ip = (IPHeader*)buf;
if (len < sizeof(IPHeader)) return;
// IP 標頭長度 (IHL * 4)
int ipHeaderLen = (ip->ver_ihl & 0x0F) * 4;
char* transport = buf + ipHeaderLen;
switch (ip->protocol) {
case IPPROTO_TCP: {
TCPHeader* tcp = (TCPHeader*)transport;
// 解析 Source/Dest Port, Seq, Ack, Flags...
break;
}
case IPPROTO_UDP: {
UDPHeader* udp = (UDPHeader*)transport;
// 解析 Port, Length...
break;
}
case IPPROTO_ICMP: {
ICMPHeader* icmp = (ICMPHeader*)transport;
// 解析 Type, Code...
break;
}
}
// 顯示來源/目的 IP、協議、資料長度、前幾位元資料...
}
SOCK_RAW 與 SIO_RCVALL 要求提升權限。recvfrom 可能成為瓶頸,建議使用非阻塞/重疊 I/O 或專用驅動。原始套接字提供了一種無需驅動開發即可實現網路封包監聽的方法,適合教學、簡易診斷工具。但受限於權限、效能與功能限制,正式產品級監聽仍建議使用 WinPcap/Npcap 或 WFP 驅動層方案。