ICMP的正式規(guī)范參見RFC 792
ICMP它傳遞差錯報文以及其他需要注意的信息。ICMP報文通常被IP層或更高層協(xié)議(TCP/UDP)使用。一些ICMP報文把差錯報文返回給用戶進程。
ICMP報文是在IP數(shù)據(jù)報內(nèi)部被傳輸?shù)?,如圖

ICMP的報文格式

所有報文的前4個字節(jié)都是一樣的,但是剩下的其他字節(jié)則互不相同。
類型字段可以有15個不同的值,以描述特定類型的ICMP報文。某些ICMP報文還使用代碼字段的值來進一步描述不同的條件。
檢驗和字段覆蓋整個ICMP報文。使用的算法和IP首部校驗和算法相同。ICMP的檢驗和是必需的。
ICMP報文類型
不同類型報文由報文種的類型字段和代碼字段來共同決定。


因為ICMP差錯報文有時需要作特殊處理,因此我們需要對其進行區(qū)別(查詢報文和差錯報文)
例如:在對ICMP差錯報文進行響應時,永遠不會生成另一份ICMP差錯報文(如果沒有這個限制,可能會遇到一個差錯產(chǎn)生另一個差錯的情況,而差錯再產(chǎn)生差錯,這樣會無休止地循環(huán)下去)
當發(fā)送一份ICMP差錯報文時,報文始終包含IP的首部和產(chǎn)生ICMP差錯報文的IP數(shù)據(jù)報的前8個字節(jié),這樣接收ICMP差錯報文的模塊就會把它與某個特定的協(xié)議(根據(jù)IP數(shù)據(jù)報首部中的協(xié)議字段來判斷)和用戶進程(根據(jù)包含在IP數(shù)據(jù)報前8個字節(jié)中的TCP或UDP報文首部中的TCP或UDP端口號來判斷)聯(lián)系起來。
下面情況都不會導致產(chǎn)生ICMP差錯報文:
1、ICMP差錯報文(但是,ICMP查詢報文可能產(chǎn)生ICMP差錯報文)
2、目的地址是廣播地址或多播地址的IP數(shù)據(jù)報
3、作為鏈路層廣播的數(shù)據(jù)報
4、不是IP分片的第一片
5、源地址不是單個主機的數(shù)據(jù)報,也就是說,源地址不能為零地址、環(huán)回地址、廣播地址或多播地址
這些規(guī)則是為了防止過去允許ICMP差錯報文對廣播分組響應所帶來的廣播風暴。
ICMP地址掩碼請求與應答
ICMP地址掩碼請求用于無盤系統(tǒng)在引導過程中獲取自己的子網(wǎng)掩碼。系統(tǒng)廣播它的ICMP請求報文(類似于RARP)。無盤系統(tǒng)獲取子網(wǎng)掩碼的另一個方法是BOOTP協(xié)議。
ICMP地址掩碼請求和應答報文格式:

ICMP報文中的標識符和序列號字段由發(fā)送端任意選擇設定,這些值在應答中將被返回。這樣,發(fā)送端就可以把應答和請求進行匹配。
廣播的一般特性:發(fā)送主機也能通過某種內(nèi)部環(huán)回機制收到一份廣播報文拷貝。
廣播的定義是指局域網(wǎng)上的所有主機,因此它必須包括發(fā)送主機在內(nèi)(參考第二章,當以太網(wǎng)驅(qū)動程序識別出目的地址是廣播地址后,它就把分組送到網(wǎng)絡上,同時傳一份拷貝到環(huán)回接口)
RFC規(guī)定,除非系統(tǒng)是地址掩碼的授權(quán)代理,否則它不能發(fā)送地址掩碼應答(為了成為授權(quán)代理,它必須進行特殊配置,以發(fā)送這些應答),但是大多數(shù)主機在收到請求時都發(fā)送一個應答,甚至有一些主機還發(fā)送差錯的應答。

ICMP時間戳請求和應答
ICMP時間戳請求允許系統(tǒng)向另一個系統(tǒng)查詢當前的時間。返回的建議值是自午夜開始計算的毫秒數(shù),協(xié)調(diào)的統(tǒng)一時間(Coordinated Universal Time,UTC)這種ICMP報文的好處是它提供了毫秒級的分辨率,而利用其他方法從別的主機獲取的時間(如某些Unix系統(tǒng)提供的rdate命令)只能提供秒級的分辨率。
由于返回的時間是從午夜開始計算的,因此調(diào)用者必須通過其他方法獲知當時的日期,這是它的一個缺陷
報文格式:

請求端填寫發(fā)起時間戳,然后發(fā)送報文,應答系統(tǒng)收到請求報文時填寫接收時間戳,在發(fā)送應答時填寫發(fā)送時間戳。但是,實際上大多數(shù)的實現(xiàn)把后面的兩個字段都設成相同的值(提供三個字段的原因是可以讓發(fā)送方分別計算發(fā)送請求時間和發(fā)送應答的時間)
發(fā)起時間戳(orig)、接收時間戳(recv)、發(fā)送時間戳(xmit)、往返時間rtt
ICMP端口不可達差錯
它是ICMP目的不可到達報文的一種,以此來看一看ICMP差錯報文中附加的信息,使用UDP來查看它
UDP的規(guī)則之一是:如果收到一份UDP數(shù)據(jù)報而目的端口與某個正在使用的進程不相符,那么UDP返回一個ICMP不可達報文,可以用TFTP來強制生成一個端口不可達報文
對于TFTP來說,UDP公共端口號是69
大多數(shù)的TFTP客戶程序允許用connect命令來指定一個不同的端口號。我們用它來指定8888端口:





ICMP的一個規(guī)則就是,ICMP差錯報文必須包括生成該差錯報文的數(shù)據(jù)IP首部(包含任何選項),還必須至少包括跟在該IP首部后面的前8個字節(jié)。

