天天看點

速讀原著-TCP/IP(ICMP端口不可達差錯)

6.5 ICMP端口不可達差錯

最後兩小節我們來讨論 I C M P查詢封包—位址掩碼和時間戳查詢及應答。現在來分析一種I C M P差錯封包,即端口不可達封包,它是 I C M P目的不可到達封包中的一種,以此來看一看I C M P差錯封包中所附加的資訊。使用 U D P(見第11章)來檢視它。

U D P的規則之一是,如果收到一份 U D P資料報而目的端口與某個正在使用的程序不相符,那麼U D P傳回一個I C M P不可達封包。可以用 T F T P來強制生成一個端口不可達封包( T F T P将在第1 5章描述)。

對于T F T P伺服器來說, U D P的公共端口号是 6 9。但是大多數的 T F T P客戶程式允許用c o n n e c t指令來指定一個不同的端口号。這裡,我們就用它來指定 8 8 8 8端口:

速讀原著-TCP/IP(ICMP端口不可達差錯)

c o n n e c t指令首先指定要連接配接的主機名及其端口号,接着用 g e t指令來取檔案。敲入 g e t指令後,一份U D P資料報就發送到主機s v r 4上的8 8 8 8端口。t c p d u m p指令引起的封包交換結果如圖6 - 8所示。

速讀原著-TCP/IP(ICMP端口不可達差錯)

在U D P資料報送到s v r 4之前,要先發送一份A R P請求來确定它的硬體位址(第 1行)。接着傳回A R P應答(第2行),然後才發送U D P資料報(第3行)(在t c p d u m p的輸出中保留A R P請求和應答是為了提醒我們,這些封包交換可能在第一個 I P資料報從一個主機發送到另一個主機之前是必需的。在本書以後的章節中,如果這些封包與讨論的題目不相關,那麼我們将省

略它們)。

一個I C M P端口不可達差錯是立刻傳回的(第 4行)。但是,T F T P客戶程式看上去似乎忽略了這個I C M P封包,而在5秒鐘之後又發送了另一份 U D P資料報(第5行)。在客戶程式放棄之前重發了三次。

注意,I C M P封包是在主機之間交換的,而不用目的端口号,而每個 2 0位元組的U D P資料報則是從一個特定端口(2 9 2 4)發送到另一個特定端口( 8 8 8 8)。

跟在每個U D P後面的數字2 0指的是U D P資料報中的資料長度。在這個例子中, 2 0位元組包括T F T P的2個位元組的操作代碼, 9個位元組以空字元結束的檔案名 t e m p . f o o,以及9個位元組以空字元結束的字元串n e t a s c i i(T F T P封包的詳細格式參見圖1 5 - 1)。

如果用- e選項運作同樣的例子,我們可以看到每個傳回的 I C M P端口不可達封包的完整長度。這裡的長度為7 0位元組,各字段配置設定如圖6 - 9所示。

速讀原著-TCP/IP(ICMP端口不可達差錯)

I C M P的一個規則是, I C M P差錯封包(參見圖 6 - 3的最後一列)必須包括生成該差錯封包的資料報I P首部(包含任何選項),還必須至少包括跟在該 I P首部後面的前 8個位元組。在我們的例子中,跟在I P首部後面的前8個位元組包含U D P的首部(見圖11 - 2)。

一個重要的事實是包含在 U D P首部中的内容是源端口号和目的端口号。就是由于目的端口号(8 8 8 8)才導緻産生了 I C M P端口不可達的差錯封包。接收 I C M P的系統可以根據源端口号(2 9 2 4)來把差錯封包與某個特定的使用者程序相關聯(在本例中是 T F T P客戶程式)。

導緻差錯的資料報中的 I P首部要被送回的原因是因為 I P首部中包含了協定字段,使得I C M P可以知道如何解釋後面的 8個位元組(在本例中是 U D P首部)。如果我們來檢視 T C P首部(圖1 7 - 2),可以發現源端口和目的端口被包含在 T C P首部的前8個位元組中。

I C M P不可達封包的一般格式如圖 6 - 1 0所示。

速讀原著-TCP/IP(ICMP端口不可達差錯)

在圖6 - 3中,我們注意到有1 6種不同類型的I C M P不可達封包,代碼分别從0到1 5。I C M P端口不可達差錯代碼是3。另外,盡管圖6 - 1 0指出了在I C M P封包中的第二個32 bit字必須為0,但是當代碼為4時(“需要分片但設定了不分片比特”),路徑M T U發現機制(2 . 9節)卻允許路由器把外出接口的MTU填在這個32 bit字的低16 bit中。我們在11.6節中給出了一個這種差錯的例子。

盡管I C M P規則允許系統傳回多于8個位元組的産生差錯的I P資料報中的資料,但是大多數從伯克利派生出來的系統隻傳回 8個位元組。 Solaris 2.2的i p _ i c m p _ r e t u r n _d a t a _ b y t e s選項預設條件下傳回前6 4個位元組(E . 4節)。t c p d u m p時間系列

在本書的後面章節中,我們還要以時間系列的格式給出t c p d u m p指令的輸出,如圖6 - 11所示。

速讀原著-TCP/IP(ICMP端口不可達差錯)

時間随着向下而遞增,在圖左邊的時間标記與 t c p d u m p指令的輸出是相同的(見圖 6 - 8)。位于圖頂部的标記是通信雙方的主機名和端口号。需要指出的是,随着頁面向下的y坐标軸與真正的時間值不是成比例的。當出現一個有意義的時間段時,在本例中是每5秒之間的重發,我們就在時間系列的兩側作上标記。當U D P或T C P資料正在被傳送時,我們用粗線的行來表示。

當I C M P封包傳回時,為什麼 T F T P客戶程式還要繼續重發請求呢?這是由于網絡程式設計中的一個因素,即B S D系統不把從插口( s o c k e t )接收到的I C M P封包中的U D P資料通知使用者程序,除非該程序已經發送了一個 c o n n e c t指令給該插口。标準的 BSD TFTP客戶程式并不發送c o n n e c t指令,是以它永遠也不會收到 I C M P差錯封包的通知。

這裡需要注意的另一點是 T F T P客戶程式所采用的不太好的逾時重傳算法。它隻是假定 5秒是足夠的,是以每隔 5秒就重傳一次,總共需要 2 5秒鐘的時間。在後面我們将看到 T C P有一個較好的逾時重發算法。

T F T P客戶程式所采用的逾時重傳算法已被R F C所禁用。不過,在作者所在子網上的三個系統以及Solaris 2.2仍然在使用它。AIX 3.2.2采用一種指數退避方法來設定逾時值,分别在0、5、1 5和3 5秒時重發封包,這正是所推薦的方法。我們将在第 2 1章更詳細地讨論逾時問題。

最後需要指出的是,I C M P封包是在發送U D P資料報3.5 ms後傳回的,這與第7章我們所看到的P i n g應答的往返時間差不多。