(一百七十六)TCP/IP詳解筆記-第6章 ICMP:Internet控制報文協議

6.1 引言

ICMP經常被認爲是IP層的一個組成部分。它傳遞差錯報文以及其他需要注意的信息。ICMP報文通常被IP層或更高層協議(TCP或UDP)使用。一些ICMP報文把差錯報文返回給用戶進程。

ICMP報文是在IP數據報內部被傳輸的,如圖6-1所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-1 ICMP封裝在IP數據報內部

ICMP的正式規範參見RFC 792[Posterl 1981b]。

ICMP報文的格式如圖6-2所示。所有報文的前4個字節都是一樣的,但是剩下的其他字節則互不相同。下面我們將逐個介紹各種報文格式。

類型字段可以有15個不同的值,以描述特定類型的ICMP報文。某些ICMP報文還使用代碼字段的值來進一步描述不同的條件。

檢驗和字段覆蓋整個ICMP報文。使用的算法與我們在3.2節中介紹的IP首部檢驗和算法相同。ICMP的檢驗和是必需的。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-2 ICMP報文

在本章中,我們將一般地討論ICMP報文,並對其中一部分作詳細介紹:地址掩碼請求和應答、時間戳請求和應答以及不可達端口。我們將詳細介紹第27章Ping程序所使用的迴應請求和應答報文和第9章處理IP路由的ICMP報文。

 

回顧一下ip datagram的格式

IP數據報的格式

第3ç«  IP:ç½éåè®®_TCP/IP详解å·1 åè®®_å³æ¶é讯ç½(52im.net)

 

6.2 ICMP報文的類型

各種類型的ICMP報文如圖6-3所示,不同類型由報文中的類型字段和代碼字段來共同決定。

圖中的最後兩列表明ICMP報文是一份查詢報文還是一份差錯報文。因爲對ICMP差錯報文有時需要作特殊處理,因此我們需要對它們進行區分。例如,在對ICMP差錯報文進行響應時,永遠不會生成另一份ICMP差錯報文(如果沒有這個限制規則,可能會遇到一個差錯產生另一個差錯的情況,而差錯再產生差錯,這樣會無休止地循環下去)。

當發送一份ICMP差錯報文時,報文始終包含IP的首部和產生ICMP差錯報文的IP數據報的前8個字節這樣,接收ICMP差錯報文的模塊就會把它與某個特定的協議(根據IP數據報首部中的協議字段來判斷)和用戶進程(根據包含在IP數據報前8個字節中的TCP或UDP報文首部中的TCP或UDP端口號來判斷)聯繫起來。6.5節將舉例來說明一點。

第6ç«  ICMP:Internetæ§å¶æ¥æåè®®_å³æ¶é讯ç½(52im.net)

下面各種情況都不會導致產生ICMP差錯報文:

  1. ICMP差錯報文(但是,ICMP查詢報文可能會產生ICMP差錯報文)。
  2. 目的地址是廣播地址(見圖3-9)或多播地址(D類地址,見圖1-5)的IP數據報。
  3. 作爲鏈路層廣播的數據報。
  4. 不是IP分片的第一片(將在11.5節介紹分片)。
  5. 源地址不是單個主機的數據報。這就是說,源地址不能爲零地址、環回地址、廣播地址或多播地址。

這些規則是爲了防止過去允許ICMP差錯報文對廣播分組響應所帶來的廣播風暴。

抓了一個ping的icmp

6.3 ICMP地址掩碼請求與應答

ICMP地址掩碼請求用於無盤系統在引導過程中獲取自己的子網掩碼(3.5節)。系統廣播它的ICMP請求報文(這一過程與無盤系統在引導過程中用RARP獲取IP地址是類似的)。無盤系統獲取子網掩碼的另一個方法是BOOTP協議,我們將在第16章中介紹。ICMP地址掩碼請求和應答報文的格式如圖6-4所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-4 ICMP地址掩碼請求和應答報文

ICMP報文中的標識符和序列號字段由發送端任意選擇設定,這些值在應答中將被返回。這樣,發送端就可以把應答與請求進行匹配。

我們可以寫一個簡單的程序(取名爲icmpaddrmask),它發送一份ICMP地址掩碼請求報文,然後打印出所有的應答。由於一般是把請求報文發往廣播地址,因此這裏我們也這樣做。目的地址(140.252.13.63)是子網140.252.13.32的廣播地址(見圖3-12)。

sun % icmpaddrmask 140.252.13.63

received mask = ffffffe0, from 140.252.13.33 來自本機

received mask = ffffffe0, from 140.252.13.35 來自bsdi

received mask = ffff0000, from 140.252.13.34 來自svr4

在輸出中我們首先注意到的是,從svr4返回的子網掩碼是錯的。顯然,儘管svr4接口已經設置了正確的子網掩碼,但是SVR4還是返回了一個普通的B類地址掩碼,就好像子網並不存在一樣。

svr4 % ifconfig emd0

emd0: flags=23<UP,BROADCAST,NOTRAILERS>

inet 140.252.13.34 netmask ffffffe0 broadcast 140.252.13.63

SVR4處理ICMP地址掩碼請求過程存在差錯。

我們用tcpdump命令來查看主機bsdi上的情況,輸出如圖6-5所示。我們用-e選項來查看硬件地址。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-5 發到廣播地址的ICMP地址掩碼請求

注意,儘管在線路上什麼也看不見,但是發送主機sun也能接收到ICMP應答(帶有上面“來自本機”的輸出行)。這是廣播的一般特性:發送主機也能通過某種內部環回機制收到一份廣播報文拷貝。由於術語“廣播”的定義是指局域網上的所有主機,因此它必須包括髮送主機在內(參見圖2-4,當以太網驅動程序識別出目的地址是廣播地址後,它就把分組送到網絡上,同時傳一份拷貝到環回接口)。

接下來,bsdi廣播應答,而svr4卻只把應答傳給請求主機。通常,應答地址必須是單播地址,除非請求端的源IP地址是0.0.0.0。本例不屬於這種情況,因此,把應答發送到廣播地址是BSD/386的一個內部差錯。

RFC規定,除非系統是地址掩碼的授權代理,否則它不能發送地址掩碼應答(爲了成爲授權代理,它必須進行特殊配置,以發送這些應答。參見附錄E)。但是,正如我們從本例中看到的那樣,大多數主機在收到請求時都發送一個應答,甚至有一些主機還發送差錯的應答。

最後一點可以通過下面的例子來說明。我們向本機IP地址和環回地址分別發送地址掩碼請求:

sun % icmpaddrmask sun

received mask = ff000000, from 140.252.13.33

sun %icmpaddrmask localhost

received mask = ff000000, from 127.0.0.1

上述兩種情況下返回的地址掩碼對應的都是環回地址,即A類地址127.0.0.1。還有,我們從圖2-4可以看到,發送給本機IP地址的數據報(140.252.12.33)實際上是送到環回接口。ICMP地址掩碼應答必須是收到請求接口的子網掩碼(這是因爲多接口主機每個接口有不同的子網掩碼),因此兩種情況下地址掩碼請求都來自於環回接口。

 

6.4 ICMP時間戳請求與應答

ICMP時間戳請求允許系統向另一個系統查詢當前的時間。返回的建議值是自午夜開始計算的毫秒數,協調的統一時間(Coordinated Universal Time,UTC)(早期的參考手冊認爲UTC是格林尼治時間)。這種ICMP報文的好處是它提供了毫秒級的分辨率,而利用其他方法從別的主機獲取的時間(如某些Unix系統提供的rdate命令)只能提供秒級的分辨率。由於返回的時間是從午夜開始計算的,因此調用者必須通過其他方法獲知當時的日期,這是它的一個缺陷。

ICMP時間戳請求和應答報文格式如圖6-6所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-6 ICMP時間戳請求和應答報文

請求端填寫發起時間戳,然後發送報文。應答系統收到請求報文時填寫接收時間戳,在發送應答時填寫發送時間戳。但是,實際上,大多數的實現把後面兩個字段都設成相同的值(提供三個字段的原因是可以讓發送方分別計算髮送請求的時間和發送應答的時間)。

6.4.1 舉例

我們可以寫一個簡單程序(取名爲icmptime),給某個主機發送ICMP時間戳請求,並打印出返回的應答。它在我們的小互聯網上運行結果如下:

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

程序打印出ICMP報文中的三個時間戳:發起時間戳(orig)、接收時間戳(recv)以及發送時間戳(xmit)。正如我們在這個例子以及下面的例子中所看到的那樣,所有的主機把接收時間戳和發送時間戳都設成相同的值。

我們還能計算出往返時間(rtt),它的值是收到應答時的時間值減去發送請求時的時間值。difference的值是接收時間戳值減去發起時間戳值。這些值之間的關係如圖6-7所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-7icmptime程序輸出的值之間的關係

如果我們相信RTT的值,並且相信RTT的一半用於請求報文的傳輸,另一半用於應答報文的傳輸,那麼爲了使本機時鐘與查詢主機的時鐘一致,本機時鐘需要進行調整,調整值是difference減去RTT的一半。在前面的例子中,bsdi的時鐘比sun的時鐘要慢7ms和8ms。

 

6.5 ICMP端口不可達差錯

最後兩小節我們來討論ICMP查詢報文—地址掩碼和時間戳查詢及應答。現在來分析一種ICMP差錯報文,即端口不可達報文,它是ICMP目的不可到達報文中的一種,以此來看一看ICMP差錯報文中所附加的信息。使用UDP(見第11章)來查看它。

UDP的規則之一是,如果收到一份UDP數據報而目的端口與某個正在使用的進程不相符,那麼UDP返回一個ICMP不可達報文。可以用TFTP來強制生成一個端口不可達報文(TFTP將在第15章描述)。

對於TFTP服務器來說,UDP的公共端口號是69。但是大多數的TFTP客戶程序允許用connect命令來指定一個不同的端口號。這裏,我們就用它來指定8888端口:

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

connect命令首先指定要連接的主機名及其端口號,接着用get命令來取文件。敲入get命令後,一份UDP數據報就發送到主機svr4上的8888端口。tcpdump命令引起的報文交換結果如圖6-8所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-8 由TFTP產生的ICMP端口不可達差錯

在UDP數據報送到svr4之前,要先發送一份ARP請求來確定它的硬件地址(第1行)。接着返回ARP應答(第2行),然後才發送UDP數據報(第3行)(在tcpdump的輸出中保留ARP請求和應答是爲了提醒我們,這些報文交換可能在第一個IP數據報從一個主機發送到另一個主機之前是必需的。在本書以後的章節中,如果這些報文與討論的題目不相關,那麼我們將省略它們)。

一個ICMP端口不可達差錯是立刻返回的(第4行)。但是,TFTP客戶程序看上去似乎忽略了這個ICMP報文,而在5秒鐘之後又發送了另一份UDP數據報(第5行)。在客戶程序放棄之前重發了三次。

注意,ICMP報文是在主機之間交換的,而不用目的端口號,而每個20字節的UDP數據報則是從一個特定端口(2924)發送到另一個特定端口(8888)。

跟在每個UDP後面的數字20指的是UDP數據報中的數據長度。在這個例子中,20字節包括TFTP的2個字節的操作代碼,9個字節以空字符結束的文件名temp.foo,以及9個字節以空字符結束的字符串netascii(TFTP報文的詳細格式參見圖15-1)。

如果用-e選項運行同樣的例子,我們可以看到每個返回的ICMP端口不可達報文的完整長度。這裏的長度爲70字節,各字段分配如圖6-9所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-9 “UDP端口不可達”例子中返回的ICMP報文

ICMP的一個規則是,ICMP差錯報文(參見圖6-3的最後一列)必須包括生成該差錯報文的數據報IP首部(包含任何選項),還必須至少包括跟在該IP首部後面的前8個字節。在我們的例子中,跟在IP首部後面的前8個字節包含UDP的首部(見圖11-2)。

一個重要的事實是包含在UDP首部中的內容是源端口號和目的端口號。就是由於目的端口號(8888)才導致產生了ICMP端口不可達的差錯報文。接收ICMP的系統可以根據源端口號(2924)來把差錯報文與某個特定的用戶進程相關聯(在本例中是TFTP客戶程序)。

導致差錯的數據報中的IP首部要被送回的原因是因爲IP首部中包含了協議字段,使得ICMP可以知道如何解釋後面的8個字節(在本例中是UDP首部)。如果我們來查看TCP首部(圖17-2),可以發現源端口和目的端口被包含在TCP首部的前8個字節中。

ICMP不可達報文的一般格式如圖6-10所示。

第6章 ICMP:Internet控制報文協議_TCP/IP詳解卷1 協議_即時通訊網(52im.net)

圖6-10 ICMP不可達報文

在圖6-3中,我們注意到有16種不同類型的ICMP不可達報文,代碼分別從0到15。ICMP端口不可達差錯代碼是3。另外,儘管圖6-10指出了在ICMP報文中的第二個32 bit字必須爲0,但是當代碼爲4時(“需要分片但設置了不分片比特”),路徑MTU發現機制(2.9節)卻允許路由器把外出接口的MTU填在這個32 bit字的低16 bit中。我們在11.6節中給出了一個這種差錯的例子。

 

6.6 ICMP報文的4.4BSD處理

由於ICMP覆蓋的範圍很廣,從致命差錯到信息差錯,因此即使在一個給定的系統實現中,對每個ICMP報文的處理都是不相同的。圖6-12的內容與圖6-3相同,它顯示的是4.4BSD系統對每個可能的ICMP報文的處理方法。

第6章 ICMP:Internet控制報文協議_即時通訊網(52im.net)

 

6.7 小結

本章對每個系統都必須包括的Internet控制報文協議進行了討論。圖6-3列出了所有的ICMP報文類型,其中大多數都將在以後的章節中加以討論。

我們詳細討論了ICMP地址掩碼請求和應答以及時間戳請求和應答。這些是典型的請求—應答報文。二者在ICMP報文中都有標識符和序列號。發送端應用程序在標識字段內存入一個唯一的數值,以區別於其他進程的應答。序列號字段使得客戶程序可以在應答和請求之間進行匹配。

我們還討論了ICMP端口不可達差錯,一種常見的ICMP差錯。對返回的ICMP差錯信息進行了分析:導致差錯的IP數據報的首部及後續8個字節。這個信息對於ICMP差錯的接收方來說是必要的,可以更多地瞭解導致差錯的原因。這是因爲TCP和UDP都在它們的首部前8個字節中存入源端口號和目的端口號。

最後,我們第一次給出了按時間先後的tcpdump輸出,這種表示方式在本書後面的章節中會經常用到。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章