在互聯網傳輸過程當中,IP數據報不免會出現差錯,一般出現差錯,處理方法就是丟棄,可是有不少狀況出現差錯後,會發送ICMP報文給主機,告訴它一些差錯信息,以及對當前的網絡狀態進行一個探尋。能夠說,ICMP的主要目的是用於在TCP/IP網絡中發送出錯和控制消息。ICMP報文封裝以下: html
ICMP報文主要分三類,即差錯報告報文、控制報文、請求/應答報文,以下圖所示: 緩存
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
當路由器收到一個沒法傳遞下去的IP報文時,會發送ICMP目的不可達報文(Type爲3)給IP報文的源發送方。報文中的Code就表示發送失敗的緣由。bash
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
網絡傳輸IP數據報的過程當中,若是IP數據包的TTL值逐漸遞減爲0時,須要丟棄數據報。這時,路由器須要向源發送方發送ICMP超時報文(Type爲11),Code爲0,表示傳輸過程當中超時了。服務器
一個IP數據報可能會由於過大而被分片,而後在目的主機側把全部的分片重組。若是主機遲遲沒有等到全部的分片報文,就會向源發送方發送一個ICMP超時報文,Code爲1,表示分片重組超時了。微信
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Pointer | unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
當路由器或主機處理數據報時,發現由於報文頭的參數錯誤而不得不丟棄報文時,須要向源發送方發送參數錯誤報文(Type爲12)。當Code爲0時,報文中的Pointer表示錯誤的字節位置。網絡
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| unused |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
路由器在處理報文時會有一個緩存隊列。若是超過最大緩存隊列,將沒法處理,從而丟棄報文。並向源發送方發一個ICMP源抑制報文(Type爲4),告訴對方下降發送速率。工具
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Gateway Internet Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
當路由收到IP數據報,發現數據報的目的地址在路由表上沒有,它就會發ICMP重定向報文(Type爲5)給源發送方,提醒它想要發送的地址不在,去其餘地方找找吧。測試
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ...
+-+-+-+-+-
複製代碼
Type(8)是請求回顯報文(Echo);Type(0)是回顯應答報文(Echo Reply)。this
請求回顯或回顯應答報文屬於查詢報文。Ping就是用這種報文進行查詢和迴應。spa
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
複製代碼
這種報文是用來找出一個主機所在的網絡個數(一個主機可能會在多個網絡中)。報文的IP消息頭的目的地址會填爲全0,表示this,源地址會填爲源IP所在的網絡IP。
最後,補充一張ICMP報文類型碼錶:
更多可參考協議文檔
在有些狀況下,爲了防止在網絡中產生大量的ICMP差錯報文(廣播風暴),影響網絡的正常工做,即便發生差錯,也不會產生ICMP差錯報文,這些狀況包括:
Ping 是 ICMP 的一個重要應用,主要用來測試兩臺主機之間的連通性。Ping 的原理是經過向目的主機發送 ICMP Echo 請求報文,目的主機收到以後會發送 Echo 回答報文。Ping 會根據時間和成功響應的次數估算出數據包往返時間以及丟包率。
Ping的完整工做流程: Ping本質上是ICMP數據包,因此其工做流程就是ICMP數據包的發送與解析流程。 大體流程以下: 構造ICMP數據包-->構造IP數據包-->構造以太網數據幀----物理傳輸到目標主機---->獲取以太網數據幀-->解析出IP數據包-->解析出ICMP數據包-->發送回送應答報文
本地主機處理流程:
目的主機處理流程:
因此,Ping的本質其實就是ICMP回送請求報文和回送應答報文。咱們可經過Wireshark抓包工具對Ping進行分析。使用ping命令:
本機會向遠端主機發送ICMP回送請求報文。遠端主機收到後會發送回送應答報文:
在這裏補充一張IP數據報格式圖:
Traceroute 是 ICMP 的另外一個應用,用來跟蹤一個分組從源點到終點的路徑。有2種實現方案:基於UDP實現和基於ICMP實現。
在基於UDP的實現中,客戶端發送的數據包是經過UDP協議來傳輸的,使用了一個大於30000的端口號,服務器在收到這個數據包的時候會返回一個端口不可達的ICMP錯誤信息,客戶端經過判斷收到的錯誤信息是TTL超時仍是端口不可達來判斷數據包是否到達目標主機。流程以下:
Linux中的traceroute就是這種實現方式。
在這一種實現中咱們不使用UDP協議,而是直接發送一個ICMP回顯請求(echo request)數據包,服務器在收到回顯請求的時候會向客戶端發送一個ICMP回顯應答(echo reply)數據包。流程與上面類似,只是最後判斷結束上爲目標主機(而不是中間通過的主機或路由器)返回一個ICMP回顯應答,則結束。
Windows中的tracert就是這種實現方式。利用Wireshark分析以下: 在cmd下輸入tracert www.baidu.com
:
每一跳默認發送三個數據包,咱們會看到下面這樣的輸出:
能夠看到TTL逐個遞增,而且最終到達目的主機180.97.33.107,到達目的主機,目的主機回覆,終止。
參考文檔:
以太網幀格式、IP數據報格式、TCP段格式+UDP段格式 詳解
www.rfc-editor.org/rfc/rfc792.…
關注微信公衆號,天天進步一點點!