TCP/IP協議筆記5-ICMP協議及其應用

1 ICMP協議概述

ICMP(Internet Control Message Protocol)協議是因特網控制報文協議,ICMP常被認為是網絡層協議,它的報文存在于IP數據報的數據部分,如圖。

ICMP協議棧

因為ICMP是基于IP數據報的,所以跟TCP不同的是,它是不需要指定端口的,更沒有建立連接一說。而且,通常來說ICMP協議都是內核幫你實現的,系統自身就支持了,并不像TCP/HTTP等還要自己開個服務監聽對應端口啥的。 可能有人會有疑問了,既然沒有端口來標識了,那我有時候開多個ping進程,這些響應消息是怎么對應到不同的ping進程的? 這個就是ICMP報文里面的標識符的作用了。標識符會在響應中帶回來,這樣發送方就能根據標識符將請求和應答匹配了。在ping中,這個標識符就是進程ID。

ICMP報文有多種類型,如地址掩碼請求和應答、時間戳請求和應答、請求回顯和回顯應答等。ICMP報文通用格式如下,不同類型的報文內容有所不同。ICMP協議在 ping,traceroute等工具中有典型應用,下面都分析一下。

ICMP報文格式

2 Ping 原理分析

ping使用的是 ICMP 的請求回顯/回顯應答類型的報文,格式如下。它的內容包括標識符、序列號以及回顯數據3部分,報文大小默認為 64 字節(header的8字節+body的56字節)。

ICMP回顯報文格式
  • 請求回顯類型是8,回顯應答類型是0,他們代碼都是 0,校驗和是包內容根據算法生成用于校驗數據完整性。
  • 標識符在 Linux/macOS 中用的是進程ID。
  • 序列號在 Linux/macOS 中是從0遞增的,每個進程獨立的。
  • 回顯數據包括發送ping請求的時間戳(在macOS占8字節,在Linux占16字節),以及一串填充數據,在Linux這串數字默認是0x10...37,共40字節。在macOS中是0x08090a...37,共48字節。填充數據你也可以通過 -p pattern指定,比如 ping -pff 192.168.33.10,則填充數據全部是 ff。
  • 默認TTL是64,你可以通過 -t ttl 指定TTL值。
  • ping請求時間 = 接收到回顯應答的時間 - 應答回顯數據中的時間

實例分析

在測試機ping我的虛擬機 ping -c2 192.168.33.10,192.168.33.10是我測試用的虛擬機IP,wireshark抓包如下:

Ping請求
Ping響應

可以驗證前面的分析。第2對請求和應答跟第一對類似,只是序列號,校驗和等不同罷了。

關于校驗和

ICMP報文頭部中的校驗和生成/校驗方式也比較簡單。

  • 生成:先將校驗和置為0,然后將ICMP報文的header+body按16bit分組求和。如果結果溢出,則將高16位和低16位求和,直到高16位為0。最后求反就是檢驗和的值。
  • 校驗:將報文的header+body按16bit分組求和(包括校驗和字段),看看結果是否全是1,如果不是,則校驗失敗。
ICMP校驗和算法

如何自己寫一個ping?可以參考下這位朋友的ping工具的 python實現。 Lingerhk: icmp_ping_tool.py

3 Traceroute 原理分析

traceroute 用于查看IP數據報從一臺主機傳到另一臺主機所經過的路由。其實,在IP數據報的頭部的選項字段有一個 IP記錄路由選項(RR),它也可以記錄路由。為什么不直接用它而是另外弄出個traceroute工具,這是因為:

  • 1)IP首部長度限制,導致記錄的IP地址最多9個 ,遠遠不夠。
  • 2)并不是所有路由器都支持記錄路由選項,因此某些路徑無法使用。

traceroute 用到ICMP協議和TTL字段。TTL字段是數據報的生存周期,初始值通常默認是64,每個處理數據報的路由器都需要把TTL值減去1或者數據報在路由器停留的秒數(因為絕大多數路由器轉發數據報時延都小于1秒,因此通常都是減去1,而且很多路由器的實現即便超過1秒也是減去1,因此可以把TTL看做一個跳站計數器)。路由器接收到一份IP數據報時,如果TTL為0或者1,則路由器不轉發該數據報,而是丟棄并給源機器發送一份ICMP超時報文,而ICMP信息中的IP報文中源地址正是路由器的IP地址。

traceroute的原理就是:

  • 先發送一份TTL為1的報文,這樣第一個路由器會將TTL減1然后丟棄該報文,并發回一個ICMP超時報文,這樣就得到了第一個路由器的IP地址;接著發送一個TTL為2的報文,可以得到第二個路由器的IP地址;繼續該過程直到目的主機。
  • 但是目的主機即便收到TTL為1的報文,它也不會丟棄該數據報并發回一份ICMP超時報文,因為此時數據報已經到了目的地。為了判斷是否到達目的主機,traceroute發送的報文采用了UDP數據報,它選擇一個很大的端口值如30000以上的,以保證沒有其他應用程序使用該端口,然后目的主機會返回一個端口不可達的ICMP報文,這樣就可以知道什么時候結束。
  • traceroute針對每個TTL會發3次UDP報文,并打印每次的往返時間。如果5秒內沒有收到3次報文中任何一個的響應,則打印*號繼續下一個TLL的報文發送。3次報文選擇的UDP目的端口分別是 33435,33436,33437,UDP報文數據長度為24字節,內容為全0(macOS環境)。

實例分析

運行 traceroute 119.75.217.109,可以看到wireshark抓包的前幾跳信息,TTL最開始是1,然后是2...,端口是33435到33437,每個TTL發3次報文,在沒有達到目的主機前,返回的是ICMP超時報文。到達主機后,則會返回ICMP端口不可達報文。

traceroute 請求的UDP報文
traceroute 響應的ICMP超時報文
traceroute 目的主機響應的ICMP端口不可達報文

由于IP路由通常都是動態的,每個路由器都要判斷數據報接下來要轉發到哪個路由器,應用程序對路由策略并不控制。而traceroute程序的IP源站選路選項(-g gateway)可以實現發送者指定路由,比如指定必須經過哪些路由IP,這里就不展開了。有興趣的可以參見 《TCP/IP詳解 卷1:協議》的第8章。

參考資料

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 個人認為,Goodboy1881先生的TCP /IP 協議詳解學習博客系列博客是一部非常精彩的學習筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,090評論 0 8
  • 地址解析協議ARP 物理這一級,主機和路由器是用物理地址來區別的。物理地址是一個本地地址,管轄范圍是本地網絡,所以...
    顧慎為閱讀 1,106評論 0 1
  • IPv4分組 IPv4,即現在普遍使用的IP協議(版本為4)。IP協議定義數據傳送的基本單元——IP分組及其確切的...
    CodeKing2017閱讀 1,919評論 0 0
  • 前言 這一篇文章主要圍繞了IP協議,ICMP協議和UDP協議展開,希望可以在這里大概做一個總結,將《TCP/IP協...
    Noskthing閱讀 3,118評論 5 57
  • 本篇結構: ICMP IGMP 附 反思 接著上一篇TCP/IP--劃分子網和構造超網,本章接著分享IP協議的兩個...
    w1992wishes閱讀 11,028評論 0 4