ICMP(Internet Control Message Protocol)運行在網絡層,其目的為了更有效的轉發IP數據報和提高交付成功的機會。
ICMP協議的格式
使用wireshark抓取含有ICMP的數據報:

ICMP報文作為IP數據報的數據部分來傳輸,在ICMP報文中含有一下字段:
| 字段名 | 描述 |
|---|---|
| Type | 占1個字節,標識ICMP報文的類型 |
| Code | 占1個字節,標識對應ICMP報文的代碼 |
| Checksum | 占2個字節,校驗包括數據在內的整個ICMP數據包 |
| Identifier | 占2個字節,用於標識本ICMP進程 |
| Sequence Number | 占2個字節,用於標識請求、響應報文 |
其中,標識符(Identifier)與序列號(Sequence Number)的值取決於ICMP報文的類型。
ICMP報文的種類
| ICMP報文種類 | 類型的值 | ICMP報文的類型 |
| 差錯報告報文 | 3 | 終點不可達 |
| 11 | 時間超過 | |
| 12 | 參數問題 | |
| 5 | 改變路由(redirect) | |
| 詢問報文 | 8或5 | 回顯(echo)請求或回答 |
| 13或14 | 時間戳(Timestamp)請求或回答 |
其中,所有的ICMP差錯報告報文中的數據字段都具有如下圖所示的格式。把需要進行差錯報告的IP數據報的首部和數據字段的前8個字節提取出來,作為ICMP報文的數據字段。再加上ICMP報文的前8個字節。

ICMP應用
Ping
在MS DOS中使用ping命令:

使用wireshark抓包:

在輸入ping hostname之后,連續發送4個ICMP回顯請求報文,並等待ICMP回顯應答。
使用Ping可以測試網絡的連通性,還能測出兩台主機間的往返時間,以表明兩者的距離。
Tracert
在MS DOS中使用tracert命令:

使用wireshark抓包:

在輸入tracert hostname之后,源主機向目的主機發送一連串的IP數據報,該數據包中封裝的是“無法交付”的UDP用戶數據報。
第一個數據報\(P_1\)的TTL設置為1。當\(P_1\)到達路徑上的第一個路由器\(R_1\)時,該路由器收下\(P_1\),接着將TTL的值減1。由於TTL的的值變為了0,\(R_1\)將該數據報丟棄然后向源主機發送一個超時ICMP差錯報告報文。
源主機接受到ICMP差錯報告報文,便發送第二個數據報\(P_2\),設置其TTL的值為2,當\(P_2\)被路徑上的第二個路由器\(R_2\)接收后,TTL的值變為0,\(R_2\)丟棄該數據報並向源主機發送超時ICMP差錯報告報文。就這樣一直下去,直到最后一個數據報到達目的地址,由於IP數據報中封裝的是“無法交付”的UDP數據報,目的主機源主機發送一個終點不可達ICMP差錯報告報文。
通過上述操作,源主機得到了到達目主機所經過的路由器的IP地址,以及到達每個路由器的往返時間。
對“無法交付”的UDP用戶數據報的解釋:
所謂“無法交付”,是指讓發送的UDP報文故意使用一個錯誤的端口,在該報文到達目的主機后被丟棄,目的主機向源主機發送終點不可達ICMP差錯報告報文。
總結
ICMP協議位於網絡層,在網絡層的抽象上提供了差錯報告服務,為傳輸層的實現提供了基礎。
本文介紹了:
- ICMP報文的格式
- ICMP報文的類型(差錯報文與詢問報文)
- ICMP的應用(Ping與Tracert)
