在網際網路中,資料封包從來源主機傳遞至目的主機,必須經由多個路由器轉發。每台路由器內部都維護一張路由表,根據目的 IP 位址決定下一跳。然而,網路拓撲會隨時變動,兩台主機之間並無固定路徑。若要掌握封包實際經過的路由節點,就需要進行「路由追蹤」。本文將詳細介紹如何利用 ICMP 協議的 TTL 機制,在 Visual C++ 6.0 環境下實作一個路由追蹤工具。
ICMP(Internet Control Message Protocol,網際網路控制訊息協議)是 IP 層的輔助協議,主要用於回報錯誤、交換控制訊息。ICMP 封包封裝在 IP 資料報的資料部分,再由資料鏈路層幀封裝傳輸。ICMP 封包頭部包含三個關鍵欄位:類型、代碼、檢驗和。常見類型包括:
當 IP 封包的 TTL(Time To Live)在經過每個路由器時遞減至 0,該路由器會丟棄封包,並向來源主機發送一個「TTL 超時」ICMP 訊息(類型 11),其 IP 來源位址即為該路由器位址。這正是路由追蹤的核心原理。

圖 1:ICMP 封包的封裝結構
追蹤流程如下:
關鍵在於動態設定 Socket 的 TTL 值,使用 setsockopt(m_Sock, IPPROTO_IP, IP_TTL, (LPSTR)&TTL, sizeof(int)) 即可實現。

圖 2:路由追蹤流程圖
RouteTrace。stdafx.h 中加入 #include "winsock2.h"。ws2_32.lib。在對話框上配置以下控制項:
| 控制項 | ID | 類型/變數 | 備註 |
|---|---|---|---|
| 位址下拉框 | IDC_COMBO | CComboBox m_comb | 輸入目的 IP/域名 |
| 最大跳數編輯框 | IDC_MAXHOT | int m_maxhot | 限制追蹤跳數 |
| 追蹤按鈕 | IDC_TRACE | OnTrace() | 啟動追蹤 |
| 停止按鈕 | IDC_STOP | OnStop() | 中止追蹤 |
| 結果列表 | IDC_LIST | CListCtrl m_list | 顯示路由節點 |

圖 3:程式執行介面
自訂 CICMP 類別封裝 ICMP 封包的建構、發送、接收與解析:
Initialize():初始化 Winsock、建立 Raw Socket、設定收發逾時。CheckSum():計算 ICMP 封包檢驗和。SendICMPPack():填充 ICMP 標頭(類型 8、ID 為進程 ID、序號、時間戳),發送封包。RecvICMPPack():接收回應,解析 IP 標頭長度,提取 ICMP 類型判斷是否為 TTL 超時(類型 11)或回應應答(類型 0),並記錄路由器 IP。核心程式碼片段:
// 設定 TTL
setsockopt(m_Sock, IPPROTO_IP, IP_TTL, (LPSTR)&TTL, sizeof(int));
// 發送 ICMP Echo Request
m_pIcmp->type = ICMP_ECHO;
m_pIcmp->code = 0;
m_pIcmp->ID = (USHORT)GetCurrentProcessId();
m_pIcmp->cksum = CheckSum((USHORT*)m_pIcmp, DEF_PACKET+sizeof(ICMP_HEAD));
sendto(winsock, (char*)m_pIcmp, DEF_PACKET+sizeof(ICMP_HEAD), 0, (sockaddr*)&sockAddr, sizeof(sockAddr));
// 接收並分析回應
recvfrom(winsock, (char*)m_pIp, MAX_PACKET, 0, (sockaddr*)&m_sockAddr, &len);
int ipheadlen = m_pIp->HeadLen * 4;
ICMP_HEAD* p_icmprev = (ICMP_HEAD*)((char*)m_pIp + ipheadlen);
switch(p_icmprev->type) {
case ICMP_ECHOREPLY: // 到達目的
case 11: // TTL 超時,取得路由器 IP
}
程式啟動後,在下拉框輸入目的位址(如 www.google.com),設定最大跳數,點擊「追蹤」按鈕,列表框將即時顯示每一跳的路由器 IP、主機名(若可解析)及往返時間。若某跳超時則顯示 *。

圖 4:路由追蹤執行效果
本文結合 ICMP 協議原理與 VC++ Socket 程式設計,完整實作了路由追蹤功能。關鍵在於利用 TTL 控制封包壽命,並解析路由器回傳的 ICMP TTL 超時訊息。此技術可應用於網路診斷、拓撲發現等場景。完整原始碼可供下載參考。