ICMP 是個啥破玩意?
點擊藍(lán)色“程序員cxuan ”關(guān)注我喲
加個“星標(biāo)”,及時接收最新文章

我們之前的文章中了解過 TCP/IP 協(xié)議,我那時候碼了一句

原文鏈接見如下:
下面我們就來真正認(rèn)識一下 ICMP 協(xié)議
什么是 ICMP
ICMP 的全稱是 Internet Control Message Protocol(互聯(lián)網(wǎng)控制協(xié)議),它是一種互聯(lián)網(wǎng)套件,它用于IP 協(xié)議中發(fā)送控制消息。也就是說,ICMP 是依靠 IP 協(xié)議來完成信息發(fā)送的,它是 IP 的主要部分,但是從體系結(jié)構(gòu)上來講,它位于 IP 之上,因為 ICMP 報文是承載在 IP 分組中的,就和 TCP 與 UDP 報文段作為 IP 有效載荷被承載那樣。這也就是說,當(dāng)主機收到一個指明上層協(xié)議為 ICMP 的 IP 數(shù)據(jù)報時,它會分解出該數(shù)據(jù)報的內(nèi)容給 ICMP,就像分解數(shù)據(jù)報的內(nèi)容給 TCP 和 UDP 一樣。
ICMP 協(xié)議和 TCP、UDP 等協(xié)議不同,它不用于傳輸數(shù)據(jù),只是用來發(fā)送消息。因為 IP 協(xié)議現(xiàn)在有兩類版本:IPv4 和 IPv6 ,所以 ICMP 也有兩個版本:ICMPv4 和 ICMPv6。
ICMP 的主要功能
對于 ICMP 的功能,主要分為兩個
ICMP 的第一個功能是確認(rèn) IP 包是否能夠成功到達(dá)目標(biāo)地址,當(dāng)兩個設(shè)備通過互聯(lián)網(wǎng)相連時,任意一個設(shè)備發(fā)送給另一個設(shè)備的 IP 包如果沒有到達(dá),就會生成 ICMP 數(shù)據(jù)包發(fā)送給設(shè)備共享。 ICMP 的第二個功能是進(jìn)行 網(wǎng)絡(luò)診斷,經(jīng)常使用 ICMP 數(shù)據(jù)包的兩個終端程序是ping和traceroute,traceroute 程序用于顯示兩臺互聯(lián)網(wǎng)設(shè)備之間可能的路徑并測量數(shù)據(jù)包在 IP 網(wǎng)絡(luò)上的時延。ping 程序是 traceroute 的簡化版本,我們經(jīng)常使用 ping 命令來測試兩臺設(shè)備之間是否互聯(lián),ping 通常用來測試兩臺主機之間的連接速度,并準(zhǔn)確報告數(shù)據(jù)包到達(dá)目的地并返回后所花費的時間。
現(xiàn)在我們知道了,如果在 IP 通信過程中由于某個 IP 包由于某種原因未能到達(dá)目標(biāo)主機,那么這個具體的原因?qū)⒂?ICMP 進(jìn)行通知,下面是一個 ICMP 的通知示意圖

上面我們只是畫出了路由器 2 給主機 A 發(fā)送了一個 ICMP 數(shù)據(jù)包,而沒有畫出具體的通知類型,但實際情況是,上面發(fā)送的是目標(biāo)不可達(dá)類型(Destination unreachable),ICMP 也是具有不同的通知類型的,下面我們匯總了 ICMP 數(shù)據(jù)包的具體通知類型。
| 通知類型(十進(jìn)制數(shù)) | 具體內(nèi)容 |
|---|---|
| 0 | 回送應(yīng)答(Echo Reply) |
| 3 | 目標(biāo)不可達(dá)(Destination Unreachable) |
| 4 | 原點抑制(Source Quench) |
| 5 | 重定向或改變路由(Redirect) |
| 8 | 回送請求(Echo Request) |
| 9 | 路由器公告(Router Advertisement) |
| 10 | 路由器請求(Router Solicitation) |
| 11 | ICMP 超時(Time Exceeded) |
| 17 | 地址子網(wǎng)請求(Address Mask Request) |
| 18 | 地址子網(wǎng)應(yīng)答(Address Mask Reply) |
上表顯示的 ICMP 通知類型主要分為兩類:有關(guān) IP 數(shù)據(jù)報傳遞的 ICMP 報文,這類報文也叫做差錯報文(error message),以及有關(guān)信息采集和配置的 ICMP 報文,這類報文也被稱為查詢 query 或者信息類報文。
信息類報文包括回送請求和回送應(yīng)答(類型 8 和 類型 0 ),路由器公告和路由器請求(類型 9 和 類型 0 )。最常見的差錯報文類型包括目標(biāo)不可達(dá)(類型 3 )、重定向(類型 5)、超時(類型 11)。
ICMP 在 IPv4 和 IPv6 的封裝
我們知道,ICMP 是承載在 IP 內(nèi)部的,而且 IPv4 和 IPv6 的封裝位置不同:
ICMP 在 IPv4 協(xié)議中的封裝

ICMP 在 IPv6 協(xié)議中的封裝

上面兩張圖顯示了 ICMPV4 和 ICMPv6 的報文格式。開頭的 4 個字節(jié)在所有的報文中都是一樣的。但是其余部分在不同的報文中卻不一樣。
ICMP 頭部包含了整個 ICMP 數(shù)據(jù)段的校驗和,具體格式如下

所有的 ICMP 報文都以 8 位的類型(Type) 和代碼(Code) 字段開始,其后的 16 位校驗和涵蓋了整個報文,ICMPv4 和 ICMPv6 種的類型和代碼字段是不同的。
ICMP 的主要消息
ICMP 目標(biāo)不可達(dá)(類型 3)
我們知道,路由器無法將 IP 數(shù)據(jù)報發(fā)送給目標(biāo)地址時,會給發(fā)送端主機返回一個目標(biāo)不可達(dá)(Destination Unreachable Message) 的 ICMP 消息,并且會在消息中顯示不可達(dá)的具體原因。

實際通信過程中會顯示各種各樣的不可達(dá)信息,比如錯誤代碼時 1 表示主機不可達(dá),它指的是路由表中沒有主機的信息,或者主機沒有連接到網(wǎng)絡(luò)的意思。一些 ICMP 不可達(dá)信息的具體原因如下
| 錯誤號 | ICMP 不可達(dá)消息 |
|---|---|
| 0 | 0 = net unreachable 網(wǎng)絡(luò)不可達(dá) |
| 1 | 1 = host unreachable 主機不可達(dá) |
| 2 | 2 = protocol unreachable 協(xié)議不可達(dá) |
| 3 | 3 = port unreachable 端口不可達(dá) |
| 4 | 4 = fragmentation needed and DF set 需要進(jìn)行分片但設(shè)置不分片比特 |
| 5 | 5 = source route failed 源站選路失敗 |
| 6 | 6 = Destination network unknown 目的網(wǎng)絡(luò)不認(rèn)識 |
| 7 | 7 = Destination host unknown 目的主機不認(rèn)識 |
| 8 | 8 = Source host isolated (obsolete)源主機被隔離(作廢不用) |
| 9 | 9 = Destination network administratively prohibited 目的網(wǎng)絡(luò)被強制禁止 |
| 10 | 10 = Destination host administratively prohibited目的主機被強制禁止 |
| 11 | 11 = Network unreachable for Type Of Service 由于 TOS,網(wǎng)絡(luò)不可達(dá) |
| 12 | 12 = Host unreachable for Type Of Service 由于 TOS,主機不可達(dá) |
ICMP 重定向消息(類型 5)
如果路由器發(fā)現(xiàn)發(fā)送端主機使用了次優(yōu)的路徑發(fā)送數(shù)據(jù),那么它會返回一個 ICMP 重定向(ICMP Redirect Message) 的消息給這個主機。這個 ICMP 重定向消息包含了最合適的路由信息和源數(shù)據(jù)。這種情況會發(fā)生在路由器持有更好的路由信息的情況下。路由器會通過這樣的 ICMP 消息給發(fā)送端主機一個更合適的發(fā)送路由。

主機 Host 的 IP 地址為 10.0.0.100。主機的路由表中有一個默認(rèn)路由條目,指向路由器 G1 的 IP 地址 10.0.0.1 作為默認(rèn)網(wǎng)關(guān)。路由器 G1 在將數(shù)據(jù)包轉(zhuǎn)發(fā)到目的網(wǎng)絡(luò) X 時,會使用路由器 G2 的 IP 地址 10.0.0.2 作為下一跳。
當(dāng)主機向目的網(wǎng)絡(luò) X 發(fā)送數(shù)據(jù)包時,會發(fā)生以下情況
IP 地址為 10.0.0.1 的網(wǎng)關(guān) G1 在其所連接的網(wǎng)絡(luò)上接收來自 10.0.0.100 的數(shù)據(jù)包。
網(wǎng)關(guān) G1 檢查其路由表,并在通往數(shù)據(jù)包目的網(wǎng)絡(luò) X 的路由中獲取下一個網(wǎng)關(guān) G2 的 IP 地址 10.0.0.2。
如果 G2 和 IP 數(shù)據(jù)包的源地址標(biāo)識的主機位于同一網(wǎng)絡(luò)中(也就是 Host 主機),那么 G1 會向主機發(fā)送 ICMP 重定向消息。ICMP 重定向消息建議主機直接將發(fā)送到網(wǎng)絡(luò) X 的數(shù)據(jù)包發(fā)送至 G2,因為 Host - G2 這是通往目的地的較短路徑。
網(wǎng)關(guān) G1 將原始數(shù)據(jù)包轉(zhuǎn)發(fā)到其目的地。
當(dāng)然,根據(jù)主機的配置,Host 主機也可以選擇忽略 G1 給它發(fā)送的 ICMP 重定向消息。但是,這樣就享受不到 ICMP 重定向帶來的兩大好處,即
優(yōu)化數(shù)據(jù)在網(wǎng)絡(luò)中的轉(zhuǎn)發(fā)路徑;流量更快到達(dá)目的地 降低網(wǎng)絡(luò)資源利用率,例如帶寬和路由器 CPU 負(fù)載
如果 Host 主機采用了 ICMP 提供的重定向路徑的話,那么 Host 就會直接把數(shù)據(jù)包發(fā)送至網(wǎng)絡(luò) X,如下圖所示

在主機為 G2 作為下一跳的網(wǎng)絡(luò) X 創(chuàng)建路由緩存條目后,這些優(yōu)勢在網(wǎng)絡(luò)中可見:
交換機和路由器 G1 之間鏈路的帶寬利用率在兩個方向上都會降低 由于從主機到網(wǎng)絡(luò) X 的流量不再流經(jīng)此節(jié)點,因此路由器 G1 的 CPU 使用率降低 主機和網(wǎng)絡(luò) X 之間的端到端網(wǎng)絡(luò)延遲得到改善。
ICMP 重定向示例如下

ICMP 超時消息(類型 11)
在 IP 數(shù)據(jù)包中有一個叫做 TTL(Time To Live, 生存周期) ,它的值在每經(jīng)過路由器一跳之后都會減 1,IP 數(shù)據(jù)包減為 0 時會被丟棄。此時,IP 路由器會發(fā)送一個 ICMP 超時消息(ICMP TIme Exceeded Message, 錯誤號 0)發(fā)送給主機,通知該包已經(jīng)被丟棄。
設(shè)置生存周期的主要目的就是為了防止路由器控制遇到問題發(fā)生循環(huán)狀況時,避免 IP 包無休止的在網(wǎng)絡(luò)上轉(zhuǎn)發(fā),如下圖所示

這里給大家推薦一款比較好用的追蹤超時消息的工具
traceroute,它可以顯示出由執(zhí)行程序的主機到達(dá)特定主機之前需要經(jīng)過多少路由器。traceroute 的官網(wǎng)如下 http://www.traceroute.org
ICMP 回送消息(類型 0 和 類型 8)
ICMP 回送消息用于判斷相互通信的主機之間是否連通,也就是判斷所發(fā)送的數(shù)據(jù)包是否能夠到達(dá)目標(biāo)主機。可以向?qū)Χ酥鳈C發(fā)送回送請求的消息(ICMP Echo Request Message,類型 8),也可以接收對端主機發(fā)送來的回送消息(ICMP Echo Reply Message, 類型 0 )。網(wǎng)絡(luò)上最常用的 ping 命令就是利用這個實現(xiàn)的。

其他 ICMP 消息
ICMP 原點抑制消息(類型 4)
在使用低速率網(wǎng)絡(luò)的情況下,網(wǎng)絡(luò)通信可能會遇到網(wǎng)絡(luò)擁堵的情況下,ICMP 的原點抑制就是為了應(yīng)對這種情況的。當(dāng)路由器向低速線路發(fā)送數(shù)據(jù)時,其發(fā)送隊列的殘存數(shù)據(jù)報變?yōu)?0 從而無法發(fā)送時,可以向 IP 數(shù)據(jù)報的源地址發(fā)送一個 ICMP 原點抑制(ICMP Source Quench Message) 消息,收到這個消息的主機了解到線路某處發(fā)生了擁堵,從而抑制 IP 數(shù)據(jù)報的發(fā)送。

不過這個 ICMP 消息可能會引起不公平的網(wǎng)絡(luò)通信,一般不被使用。
ICMP 路由器探索消息(類型 9、10)
ICMP 路由器探索消息主要用于路由器發(fā)現(xiàn)(Router Discovery, RD),它主要分為兩種,路由器請求(Router Solicitation, 類型 10) 和路由器響應(yīng)(Router Advertisement, 類型 9)。主機會在任意路由連接組播的網(wǎng)絡(luò)上發(fā)送一個 RS 消息,想要選擇一個路由器進(jìn)行學(xué)習(xí),以此來作為默認(rèn)路由,而相對應(yīng)的該路由會發(fā)送一個 RA 消息來作為默認(rèn)路由的響應(yīng)。

ICMP 地址掩碼消息(類型 17、18)
主要用于主機或者路由器想要了解子網(wǎng)掩碼的情況。可以向那些目標(biāo)主機或路由器發(fā)送 ICMP 地址掩碼請求消息(ICMP Address Mask Request, 類型 17) 和 ICMP 地址掩碼應(yīng)答消息(ICMP Address Mask Reply, 類型 18) 獲取子網(wǎng)掩碼信息。
ICMPv6
ICMPv6 的作用
IPv4 中 ICMP 僅僅作為一個輔助作用支持 IPv4。也就是說,在 IPv4 時期,即使沒有 ICMP,也能進(jìn)行正常的 IP 數(shù)據(jù)包的發(fā)送和接收,也就是 IP 通信。但是在 IPv6 中,ICMP 的作用被放大了,如果沒有 ICMP,則不能進(jìn)行正常的 IP 通信。
尤其在 IPv6 中,從 IP 定位 MAC 地址的協(xié)議從 ARP 轉(zhuǎn)為 ICMP 的鄰居探索消息(Neighbor Discovery) 。這種鄰居探索消息融合了 IPv4 的 ARP、ICMP 重定向以及 ICMP 的路由選擇等功能于一體。甚至還提供了自動設(shè)置 IP 的功能。
在 IPv6 中,ICMP 消息主要分為兩類:一類是錯誤消息,一類是信息消息。0 - 127 屬于錯誤消息;128 - 255 屬于信息消息。
RFC 2463 中描述了以下消息類型:
| 類型 | 描述 |
|---|---|
| 1 | 目標(biāo)不可達(dá) Destination Unreachable |
| 2 | 數(shù)據(jù)包太大 Packet Too Big |
| 3 | 超時 Time Exceeded |
| 4 | 參數(shù)問題 Parameter Problem |
| 128 | 回送請求消息 Echo Request |
| 129 | 回送應(yīng)答消息 Echo Reply |
| 130 | 多播監(jiān)聽查詢 Multicast Listener Query |
| 131 | 多播監(jiān)聽報告 Multicast Listener Report |
| 132 | 多播監(jiān)聽結(jié)束 Multicast Listener Done |
| 133 | 路由器請求消息 Router Solicitation |
| 134 | 路由器公告消息 Router Advertisement |
| 135 | 鄰居請求消息 Neighbor Solicitation |
| 136 | 鄰居宣告消息 Neighbor Advertisement |
| 137 | 重定向消息 Redirect Message |
| 138 | 路由器重編號 Router Renumbering |
| 139 | 信息查詢 ICMP Node Information Query |
| 140 | 信息應(yīng)答 ICMP Node Information Response |
| 141 | 反鄰居探索請求消息 Inverse Neighbor Discovery Solicitation |
| 142 | 反鄰居探索宣告消息 Inverse Neighbor Discovery Advertisement |
ICMPv6 除了包含 ICMPv4 的所有功能外,還有兩個額外的功能。
ICMPv6 鄰居探索
鄰居探索是 ICMPv6 非常重要的功能,主要表示的類型是 133 - 137 之間的消息叫做鄰居探索消息。這種鄰居探索消息對于 IPv6 通信起到舉足輕重的作用。鄰居請求消息用于查詢 IPv6 地址于 MAC 地址的對應(yīng)關(guān)系。鄰居請求消息利用 IPv6 的多播地址實現(xiàn)傳輸。

此外,由于 IPv6 實現(xiàn)了即插即用的功能,所以在沒有 DHCP 服務(wù)器的環(huán)境下也能實現(xiàn) IP 地址的自動獲取。如果是一個沒有路由器的網(wǎng)絡(luò),就使用 MAC 地址作為鏈路本地單播地址。如果在一個有路由器的網(wǎng)絡(luò)環(huán)境中,可以從路由器獲得 IPv6 地址的前面部分,后面部分使用 MAC 地址進(jìn)行設(shè)置。此時可以利用路由器請求消息和路由器公告消息進(jìn)行設(shè)置。

ICMPv6 的組播收聽發(fā)現(xiàn)協(xié)議
組播收聽發(fā)現(xiàn)協(xié)議(MLD,Multicast Listener Discovery)由子網(wǎng)內(nèi)的組播成員管理。MLD 協(xié)議定義了3條ICMPv6 消息:
組播收聽查詢消息:組播路由器向子網(wǎng)內(nèi)的組播收聽者發(fā)送此消息,以獲取組播收聽者的狀態(tài)。 組播收聽者報告消息:組播收聽者向組播路由器匯報當(dāng)前狀態(tài),包括離開某個組播組。 組播收聽者。
與 ICMP 有關(guān)的攻擊
涉及 ICMP 攻擊主要分為 3 類:泛洪(flood)、炸彈(bomb) 和信息泄露(information disclsure)。
泛洪將會產(chǎn)生大量流量,導(dǎo)致針對一臺或者多臺計算機的有效 Dos 攻擊。 炸彈指的是發(fā)送經(jīng)過特殊構(gòu)造的報文,這類報文能夠?qū)е?IP 或者 ICMP 的處理失效或者崩潰。 信息泄露本身不會造成危害,但是能夠幫助輔助其他攻擊。
針對 TCP 的 ICMP 攻擊已經(jīng)記錄在了 RFC5927 中。
完
往期推薦
??
如何系統(tǒng)學(xué)習(xí)計算機網(wǎng)絡(luò)?
我畫了 40 張圖就是為了讓你搞懂計算機網(wǎng)絡(luò)層
閱片無數(shù)的 cxuan 給你推薦比某 hub 更爽的網(wǎng)站
另外,cxuan 肝了六本 PDF,公號回復(fù) cxuan ,領(lǐng)取作者全部 PDF 。

