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

ICMP 協定深度解析 (三):使用未公開 ICMP.dll 實作 Ping

     編輯:關於VC++

本文示範呼叫微軟未公開文件化的 ICMP.dll 內部 API (IcmpCreateFile、IcmpSendEcho、IcmpCloseHandle) 實作 Ping 功能。此 DLL 自 Windows 95 起存在,Windows 2000 仍保留,但微軟已宣佈將以更好方案取代,不建議新專案採用。

動態載入 ICMP.dll 並取得函數指標


HINSTANCE hIcmp = LoadLibrary("ICMP.DLL");
if (!hIcmp) { /* 錯誤處理 */ }

// 定義函數指標型別 (參數複雜,使用 typedef 簡化)
typedef HANDLE (WINAPI *PFN_ICMPCREATEFILE)(VOID);
typedef BOOL   (WINAPI *PFN_ICMPCLOSEHANDLE)(HANDLE);
typedef DWORD  (WINAPI *PFN_ICMPSENDECHO)(HANDLE, DWORD, LPVOID, WORD,
                                          PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD);

PFN_ICMPCREATEFILE  pIcmpCreateFile  = (PFN_ICMPCREATEFILE) GetProcAddress(hIcmp, "IcmpCreateFile");
PFN_ICMPCLOSEHANDLE pIcmpCloseHandle = (PFN_ICMPCLOSEHANDLE) GetProcAddress(hIcmp, "IcmpCloseHandle");
PFN_ICMPSENDECHO    pIcmpSendEcho    = (PFN_ICMPSENDECHO)   GetProcAddress(hIcmp, "IcmpSendEcho");

必要結構定義 (icmpdefs.h)


typedef struct {
    UCHAR Ttl;           // Time To Live
    UCHAR Tos;           // Type Of Service
    UCHAR Flags;         // IP 標頭旗標
    UCHAR OptionsSize;   // 選項資料大小
    UCHAR *OptionsData;  // 選項資料指標
} IP_OPTION_INFORMATION, *PIP_OPTION_INFORMATION;

typedef struct {
    DWORD  Address;           // 回應位址
    ULONG  Status;            // 回應狀態
    ULONG  RoundTripTime;     // RTT (毫秒)
    USHORT DataSize;          // 回應資料大小
    USHORT Reserved;          // 保留
    void   *Data;             // 回應資料指標
    IP_OPTION_INFORMATION Options; // 回應選項
} IP_ECHO_REPLY, *PIP_ECHO_REPLY;

完整 Ping 流程

  1. WSAStartup(MAKEWORD(1,1)) 初始化 Winsock
  2. gethostbyname 解析目標主機名稱取得 IP 位址
  3. LoadLibrary("ICMP.DLL") + GetProcAddress 取得三個函數入口
  4. pIcmpCreateFile() 開啟 Ping 服務取得 Handle
  5. 配置發送緩衝區 (64 bytes 填充 0xAA) 與接收緩衝區 (GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT, sizeof(IP_ECHO_REPLY)+64))
  6. pIcmpSendEcho(hIP, destIP, sendBuf, 64, NULL, pReply, replyBufSize, 5000) 同步發送並等待回應 (5 秒逾時)
  7. 檢查回傳狀態:成功則從 pReply 解析 IP、RTT、TTL 輸出
  8. GlobalFree、FreeLibrary、WSACleanup 釋放資源

程式碼優化建議

  • 將命令列參數處理移至 main(),doit() 僅負責核心邏輯
  • 錯誤碼應對應 IP_ECHO_REPLY.Status 詳細分類 (參考 WinError.h)
  • 支援多次 Ping、統計封包損失率、最小/最大/平均 RTT

總結

ICMP.dll 方式程式碼簡潔,封裝度高,適合快速原型開發。但因屬非公開 API,存在相容性風險 (Vista 後行為變更),生產環境建議改用 RAW Socket (下一篇) 或 Winsock 2 標準介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved