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

Windows 原始套接字 實作網路封包偵聽與解析 (IP/TCP/UDP/ICMP)

     編輯:關於C++

前言

本文提供一個完整的 C/C++ 控制台程式範例,展示如何在 Windows 上使用 Raw Socket (SOCK_RAW, IPPROTO_IP) 捕獲本機網卡經過的所有 IP 封包,並解析 IP、TCP、UDP、ICMP 標頭與資料載荷。程式支援協議過濾、IP 過濾、埠號過濾、敏感字串搜尋與資料十六進位/ASCII 轉傳。

核心架構

  1. 初始化 Winsock 2.2:WSAStartup(MAKEWORD(2,2), ...)。
  2. 建立原始套接字:socket(AF_INET, SOCK_RAW, IPPROTO_IP) 需系統管理員權限。
  3. 綁定本機介面:取得主機名 → gethostbyname → 綁定任一本機 IP。
  4. 啟用混亂模式:WSAIoctl(s, SIO_RCVALL, ...) 讓網卡接收所有封包(非僅本機)。
  5. 迴圈接收與解析:recvfrom → DecodeIpPack → 依協議分派 DecodeTcpPack/UdpPack/IcmpPack。

關鍵資料結構 (標準 RFC 791/793/768/792)

// 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;

解析流程重點

IP 層

  • 依 h_lenver & 0x0F 計算首部長度 (IHL × 4 bytes)。
  • 取出 proto 決定上層協議。
  • 來源/目的 IP 以 inet_ntoa 轉點分十進位。
  • 支援來源/目的 IP 過濾字串比對。

TCP 層

  • 首部長度 (th_lenres >> 4) × 4 bytes。
  • 旗標位元對應:FIN(0x01), SYN(0x02), RST(0x04), PSH(0x08), ACK(0x10), URG(0x20)。
  • 埠號過濾:來源或目的埠符合指定值才顯示。
  • 敏感字串搜尋:僅當 TCP 載荷包含指定字串才輸出 (可用於偵測明文密碼等)。
  • -p 參數啟用載荷轉傳 (ASCII 可列印字元顯示字元,其餘顯示 Hex)。

UDP/ICMP 層

  • UDP:固定 8 bytes 標頭,載荷直接跟隨。
  • ICMP:類型/代碼過濾 (以 -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:STRTCP 載荷敏感字串/s:PASS
/o:PORT埠號/ICMP 類型過濾/o:80

編譯與執行需求

  • Visual C++ / MinGW / BCB 均可編譯,需連結 ws2_32.lib。
  • 必須以系統管理員身分執行,否則 SIO_RCVALL 會失敗 (錯誤 10013 WSAEACCES)。
  • Windows 10/11 可能需關閉「核心隔離/記憶體完整性」或使用 WinPcap/Npcap 驅動以獲得更穩定的原始封包捕獲。

完整原始碼結構

#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 查詢等) 或加密封包的中繼資料。

進階替代方案

  • WinPcap / Npcap:業界標準封包捕獲庫,支援 BPF 過濾器、更高效能、跨平台。
  • Wireshark (tshark):圖形化/CLI 專業分析工具,內建數百種協議解析器。
  • Windows Filtering Platform (WFP):核心層封包過濾/檢測架構,適用於防火牆/EDR 開發。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved