1. 程式人生 > >ICMP協議及應用例項(Ping,Traceroute)

ICMP協議及應用例項(Ping,Traceroute)

ICMP協議

在網際網路傳輸過程中,IP資料報難免會出現差錯,通常出現差錯,處理方法就是丟棄,但是一般,出現差錯後,會發送ICMP報文給主機,告訴它一些差錯資訊,以及對當前的網路狀態進行一個探尋。可以說,ICMP的主要目的是用於在TCP/IP網路中傳送出錯和控制訊息。

ICMP報文封裝如下:
在這裡插入圖片描述

主要ICMP報文

ICMP報文主要分三類,即差錯報告報文、控制報文、請求/應答報文,如下圖所示:
在這裡插入圖片描述

目的不可達(Destination Unreachable Message)

    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就表示傳送失敗的原因。

超時(Time Exceeded Message)

    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,表示分片重組超時了。

引數錯誤報文(Parameter Problem Message)

   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表示錯誤的位元組位置。

源抑制(Source Quench Message)

   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),告訴對方降低傳送速率。

重定向(Redirect Message)

    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)給源傳送方,提醒它想要傳送的地址不在,去其他地方找找吧。

請求回顯或回顯應答(Echo or Echo Reply Message)

    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)。

請求回顯或回顯應答報文屬於查詢報文。Ping就是用這種報文進行查詢和迴應。

資訊請求或資訊響應(Information Request or Information Reply Message)

 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差錯報文(廣播風暴),影響網路的正常工作,即使發生差錯,也不會產生ICMP差錯報文,這些情況包括:

  • 對ICMP差錯報告報文不再發送 ICMP差錯報告報文
  • 除第1個IP資料報分片外, 對所有後續分片均不傳送ICMP差錯報告報文
  • 對所有多播IP資料報均不傳送 ICMP差錯報告報文
  • 對具有特殊地址( 如127.0.0.0 或 0.0.0.0) 的IP資料報不傳送ICMP 差錯報告報文
ICMP應用例項——Ping

Ping 是 ICMP 的一個重要應用,主要用來測試兩臺主機之間的連通性。

Ping 的原理是通過向目的主機發送 ICMP Echo 請求報文,目的主機收到之後會發送 Echo 回答報文。Ping 會根據時間和成功響應的次數估算出資料包往返時間以及丟包率。

Ping的完整工作流程:
Ping本質上是ICMP資料包,所以其工作流程就是ICMP資料包的傳送與解析流程。
大致流程如下:
構造ICMP資料包–>構造IP資料包–>構造乙太網資料幀----物理傳輸到目標主機---->獲取乙太網資料幀–>解析出IP資料包–>解析出ICMP資料包–>傳送回送應答報文

本地主機處理流程:

  1. 在本地,ping命令會構建一個ICMP資料包(構造回送請求報文)
  2. 將該ICMP資料包和目標IP地址給IP協議,IP協議將本地地址作為源地址,與目的地址等構造IP資料包
  3. 根據本地ARP快取查詢目的地址IP對應的MAC地址,如果快取中沒有則通過ARP協議找到對應IP的MAC地址。將MAC地址交給資料鏈路層以構造資料幀
  4. 經物理層傳送給目的主機

目的主機處理流程:
0. 目的主機接收到資料包

  1. 物理層接收到二進位制資料流經資料鏈路層,按照乙太網協議解析出資料幀,如果資料幀中的目標MAC地址與本機MAC地址相同,則接收該資料包,否則丟棄該資料包。
  2. 接收到該資料包之後,經網路層解析出IP資料包,通過IP包頭中的協議欄位判斷出是ICMP資料包。之後解析出ICMP資料包,發現是回送請求報文(ping request)後馬上構建一個ICMP回送應答報文(ping reply)
  3. 將封裝好的ICMP資料包經網路層、資料鏈路層、物理層傳送回源主機

所以,Ping的本質其實就是ICMP回送請求報文和回送應答報文。我們可通過Wireshark抓包工具對Ping進行分析。使用ping命令:
在這裡插入圖片描述
本機會向遠端主機發送ICMP回送請求報文。
在這裡插入圖片描述

遠端主機收到後會傳送回送應答報文:
在這裡插入圖片描述

在這裡補充一張IP資料報格式圖:
在這裡插入圖片描述

ICMP應用例項——Traceroute

Traceroute 是 ICMP 的另一個應用,用來跟蹤一個分組從源點到終點的路徑。有2種實現方案:基於UDP實現和基於ICMP實現。

基於UDP實現traceroute工作原理:
在基於UDP的實現中,客戶端傳送的資料包是通過UDP協議來傳輸的,使用了一個大於30000的埠號,伺服器在收到這個資料包的時候會返回一個埠不可達的ICMP錯誤資訊,客戶端通過判斷收到的錯誤資訊是TTL超時還是埠不可達來判斷資料包是否到達目標主機。流程如下:

  1. 源主機向目的主機發送一連串的 IP 資料報(UDP報文)。第一個資料報 P1 的生存時間 TTL 設定為 1,當 P1 到達路徑上的第一個路由器 R1 時,R1 收下它並把 TTL 減 1,此時 TTL 等於 0,R1 就把 P1 丟棄,並向源主機發送一個 ICMP 時間超過差錯報告報文;
  2. 源主機接著傳送第二個資料報 P2,並把 TTL 設定為 2。P2 先到達 R1,R1 收下後把 TTL 減 1 再轉發給 R2,R2 收下後也把 TTL 減 1,由於此時 TTL 等於 0,R2 就丟棄 P2,並向源主機發送一個 ICMP 時間超過差錯報文。
  3. 不斷執行這樣的步驟,直到最後一個數據報剛剛到達目的主機,主機不轉發資料報,也不把 TTL 值減 1。但是因為資料報封裝的是無法交付的 UDP,因此目的主機要向源主機發送 ICMP 終點不可達差錯報告報文。
  4. 之後源主機知道了到達目的主機所經過的路由器 IP 地址以及到達每個路由器的往返時間。

Linux中的traceroute就是這種實現方式。

基於ICMP實現的tracert工作原理:
在這一種實現中我們不使用UDP協議,而是直接傳送一個ICMP回顯請求(echo request)資料包,伺服器在收到回顯請求的時候會向客戶端傳送一個ICMP回顯應答(echo reply)資料包。流程與上面相似,只是最後判斷結束上為目標主機(而不是中間經過的主機或路由器)返回一個ICMP回顯應答,則結束。

Windows中的tracert就是這種實現方式。利用Wireshark分析如下:
在cmd下輸入tracert www.baidu.com
在這裡插入圖片描述

每一跳預設傳送三個資料包,我們會看到下面這樣的輸出:
在這裡插入圖片描述
在這裡插入圖片描述

可以看到TTL逐個遞增,並且最終到達目的主機180.97.33.107,到達目的主機,目的主機回覆,終止。