瑞士軍刀協(xié)議——ICMP
ICMP協(xié)議
IP協(xié)議的一個重要補充是是ICMP協(xié)議。ICMP(Internet Control Message Protocol)是介于網(wǎng)絡(luò)層和傳輸層的協(xié)議。它的主要功能是傳輸網(wǎng)絡(luò)診斷信息。
ICMP傳輸?shù)男畔⒖梢苑譃閮深?,一類是錯誤(error)信息,這一類信息可用來診斷網(wǎng)絡(luò)故障。我們已經(jīng)知道,IP協(xié)議的工作方式是“Best Effort”,如果IP包沒有被傳送到目的地,或者IP包發(fā)生錯誤,IP協(xié)議本身不會做進(jìn)一步的努力。但上游發(fā)送IP包的主機和接力的路由器并不知道下游發(fā)生了錯誤和故障,它們可能繼續(xù)發(fā)送IP包。通過ICMP包,下游的路由器和主機可以將錯誤信息匯報給上游,從而讓上游的路由器和主機進(jìn)行調(diào)整。需要注意的是,ICMP只提供特定類型的錯誤匯報,它不能幫助IP協(xié)議成為“可靠”(reliable)的協(xié)議。另一類信息是咨詢(Informational)性質(zhì)的,比如某臺計算機詢問路徑上的每個路由器都是誰,然后各個路由器同樣用ICMP包回答。
(ICMP基于IP協(xié)議。也就是說,一個ICMP包需要封裝在IP包中,然后在互聯(lián)網(wǎng)傳送。ICMP是IP套裝的必須部分,也就是說,任何一個支持IP協(xié)議的計算機,都要同時實現(xiàn)ICMP。)
ICMP包的結(jié)構(gòu):

A bunch of Types
ICMP包都會有Type, Code和Checksum三部分。Type表示ICMP包的大的類型,而Code是一個Type之內(nèi)細(xì)分的小類型。針對不同的錯誤信息或者咨詢信息,會有不同的Type和Code。從上面我們可以看到,ICMP支持的類型非常多,就好像瑞士軍刀一樣,有各種各樣的功能。Checksum與IP協(xié)議的header checksum相類似,但與IP協(xié)議中checksum只校驗頭部不同,這里的Checksum所校驗的是整個ICMP包(包括頭部和數(shù)據(jù))。
余下的ICMP包格式根據(jù)不同的類型不同。另一方面,ICMP包通常是由某個IP包觸發(fā)的。這個觸發(fā)IP包的頭部和一部份數(shù)據(jù)會被包含在ICMP包的數(shù)據(jù)部分。
ICMP協(xié)議是實現(xiàn)ping命令和traceroute命令的基礎(chǔ)。這兩個工具常用于網(wǎng)絡(luò)排錯。
常見的ICMP包類型
回音
回音(Echo)屬于咨詢信息。ping命令就是利用了該類型的ICMP包。當(dāng)使用ping命令的時候,將向目標(biāo)主機發(fā)送Echo-詢問類型的ICMP包,而目標(biāo)主機在接收到該ICMP包之后,會回復(fù)Echo-回答類型的ICMP包,并將詢問ICMP包包含在數(shù)據(jù)部分。ping命令是我們進(jìn)行網(wǎng)絡(luò)排查的一個重要工具。如果一個IP地址可以通過ping命令收到回復(fù),那么其他的網(wǎng)絡(luò)協(xié)議通信方式也很有可能成功。
源頭冷卻
源頭冷卻(source quench)屬于錯誤信息。如果某個主機快速的向目的地傳送數(shù)據(jù),而目的地主機沒有匹配的處理能力,目的地主機可以向出發(fā)主機發(fā)出該類型的ICMP包,提醒出發(fā)主機放慢發(fā)送速度(請溫柔一點吧)。
目的地?zé)o法到達(dá)
目的地?zé)o法到達(dá)(Destination Unreachable)屬于錯誤信息。如果一個路由器接收到一個沒辦法進(jìn)一步接力的IP包,它會向出發(fā)主機發(fā)送該類型的ICMP包。比如當(dāng)IP包到達(dá)最后一個路由器,路由器發(fā)現(xiàn)目的地主機down機,就會向出發(fā)主機發(fā)送目的地?zé)o法到達(dá)(Destination Unreachable)類型的ICMP包。目的地?zé)o法到達(dá)還可能有其他的原因,比如不存在接力路徑,比如不被接收的端口號等等。
超時
超時(Time Exceeded)屬于錯誤信息。IPv4中的Time to Live(TTL)和IPv6中的Hop Limit會隨著經(jīng)過的路由器而遞減,當(dāng)這個區(qū)域值減為0時,就認(rèn)為該IP包超時(Time Exceeded)。Time Exceeded就是TTL減為0時的路由器發(fā)給出發(fā)主機的ICMP包,通知它發(fā)生了超時錯誤。
traceroute就利用了這種類型的ICMP包。traceroute命令用來發(fā)現(xiàn)IP接力路徑(route)上的各個路由器。它向目的地發(fā)送IP包,第一次的時候,將TTL設(shè)置為1,引發(fā)第一個路由器的Time Exceeded錯誤。這樣,第一個路由器回復(fù)ICMP包,從而讓出發(fā)主機知道途徑的第一個路由器的信息。隨后TTL被設(shè)置為2、3、4,...,直到到達(dá)目的主機。這樣,沿途的每個路由器都會向出發(fā)主機發(fā)送ICMP包來匯報錯誤。traceroute將ICMP包的信息打印在屏幕上,就是接力路徑的信息了。
重新定向
重新定向(redirect)屬于錯誤信息。當(dāng)一個路由器收到一個IP包,對照其routing table,發(fā)現(xiàn)自己不應(yīng)該收到該IP包,它會向出發(fā)主機發(fā)送重新定向類型的ICMP,提醒出發(fā)主機修改自己的routing table。比如下面的網(wǎng)絡(luò):
假如145.1發(fā)送到145.15的IP包,結(jié)果被中間的路由器通過145.17的NIC收到。那么路由器會發(fā)現(xiàn),根據(jù)自己的routing table,這個IP包要原路返回。那么router就可以判斷出145.1的routing table可能有問題。所以路由器會向145.1發(fā)送redirect類型的ICMP包。
IPv6的Neighbor Discovery
ARP協(xié)議用于發(fā)現(xiàn)周邊的IP地址和MAC地址的對應(yīng)。然而,ARP協(xié)議只用于IPv4,IPv6并不使用ARP協(xié)議。IPv6包通過鄰居探索(ND, Neighbor Discovery)來實現(xiàn)ARP的功能。ND的工作方式與ARP類似,但它基于ICMP協(xié)議。ICMP包有Neighbor Solicitation和Neighbor Advertisement類型。這兩個類型分別對應(yīng)ARP協(xié)議的詢問和回復(fù)信息。
總結(jié)
ICMP協(xié)議是IP協(xié)議的排錯幫手,它可以幫助人們及時發(fā)現(xiàn)IP通信中出現(xiàn)的故障?;贗CMP的ping和traceroute也構(gòu)成了重要的網(wǎng)絡(luò)診斷工具。然而,需要注意的是,盡管ICMP的設(shè)計是出于好的意圖,但I(xiàn)CMP卻經(jīng)常被黑客借用進(jìn)行網(wǎng)絡(luò)攻擊,比如利用偽造的IP包引發(fā)大量的ICMP回復(fù),并將這些ICMP包導(dǎo)向受害主機,從而形成DoS攻擊。而redirect類型的ICMP包可以引起某個主機更改自己的routing table,所以也被用作攻擊工具。許多站點選擇忽視某些類型的ICMP包來提高自身的安全性。