1. 程式人生 > >TCP/IP-ICMP

TCP/IP-ICMP

TCP/IP-ICMP

作者:Danbo 2015-8-22

I C M P經常被認為是I P層的一個組成部分。它傳遞差錯報文以及其他需要注意的資訊。I C M P報文通常被I P層或更高層協議( T C P或U D P)使用。一些I C M P報文把差錯報文返回給使用者程序。I C M P報文是在I P資料報內部被傳輸的。型別欄位可以有1 5個不同的值,以描述特定型別的I C M P報文。某些I C M P報文還使用程式碼欄位的值來進一步描述不同的條件。檢驗和欄位覆蓋整個I C M P報文

ICMP報文

常見的型別和程式碼:
0 0 回顯應答
3 3 埠不可達
8 0 請求回顯
11 0 TTL超時(Traceroute會用到)


全部如下圖所示:

注意:埠不可達只能針對UDP,如果是TCP的話就會迴應TCP的RST包清理掉該連線請求。
不過基於安全和穩定方面的考慮,在開發應用程式的時候都會忽略ICMP不可達資訊,但是會提供足夠的資訊讓程式意識到這個問題的存在。

當傳送一份I C M P差錯報文時,報文始終包含I P的首部和產生I C M P差錯報文的I P資料報的前8個位元組。這樣,接收I C M P差錯報文的模組就會把它與某個特定的協議(根據I P資料報首部中的協議欄位來判斷)和使用者程序(根據包含在I P資料報前8個位元組中的T C P或U D P報文首部中的T C P或U D P埠號來判斷)聯絡起來。

下面各種情況都不會導致產生I C M P差錯報文


1) ICMP差錯報文(但是,I C M P查詢報文可能會產生I C M P差錯報文)。
2) 目的地址是廣播地址或多播地址的I P資料報。
3) 作為鏈路層廣播的資料報。
4) 不是I P分片的第一片。(只有第一片才有埠號資訊)
5) 源地址不是單個主機的資料報。這就是說,源地址不能為零地址、環回地址、廣播地址或多播地址。
這些規則是為了防止過去允許I C M P差錯報文對廣播分組響應所帶來的廣播風暴。

UDP埠不可達中返回ICMP報文的例項

PING

我們稱傳送回顯請求的p i n g程式為客戶,而稱被p i n g的主機為伺服器。

幾年前我們還可以作出這樣沒有限定的斷言,如果不能P i n g到某臺主機,那麼就不能Te l n e t或F T P到那臺主機。隨著I n t e r n e t安全意識的增強,出現了提供訪問控制清單的路由器和防火牆

(比如禁用了ping),那麼像這樣沒有限定的斷言就不再成立了。一臺主機的可達性可能不只取決於I P層是否可達,還取決於使用何種協議以及埠號

Ping的路徑記錄 選項:-R
p i n g程式為我們提供了檢視I P記錄路由( R R)選項的機會。大多數不同版本的p i n g程第7章Ping程式使用65 下載序都提供-R選項,以提供記錄路由的功能。它使得p i n g程式在傳送出去的I P資料報中設定I PR R選項(該I P資料報包含I C M P回顯請求報文)。這樣,每個處理該資料報的路由器都把它的I P地址放入選項欄位中。當資料報到達目的端時, I P地址清單應該複製到I C M P回顯應答中,這樣返回途中所經過的路由器地址也被加入清單中。當p i n g程式收到回顯應答時,它就打印出這份I P地址清單。源端主機生成RR選項,中間路由器對RR選項的處理,以及把ICMP回顯請求中的RR清單複製到ICMP回顯應答中。即來去都要記錄。

IP首部中的首部長度欄位只有4 bit,因此整個I P首部最長只能包括1 5個32 bit長的字(即6 0個位元組)。由於I P首部固定長度為2 0位元組, R R選項用去3個位元組(下面我們再討論),這樣只剩下3 7個位元組( 6 0-2 0-3)來存放I P地址清單,也就是說只能存放9個I P地址

IP記錄路由選項結構:

Ping的IP記錄會把出介面IP放入到清單中,最後一條會把入介面放入到清單中。後面講的Traceroute記錄的是入介面IP

通過下面我們可以對比一下Ping和Traceroute記錄IP的區別。

R1#traceroute 3.3.3.3
Type escape sequence to abort.
Tracing the route to 3.3.3.3
  1 12.1.1.2 40 msec 24 msec 32 msec
  2 23.1.1.3 40 msec 40 msec 40 msec

R1#ping ip
Target IP address: 3.3.3.3
Repeat count [5]: 1
Datagram size [100]:
Timeout in seconds [2]:
Extended commands [n]: y
Source address or interface:
Type of service [0]:
Set DF bit in IP header? [no]:
Validate reply data? [no]:
Data pattern [0xABCD]:
Loose, Strict, Record, Timestamp, Verbose[none]: R         
Number of hops [ 9 ]: 9
Loose, Strict, Record, Timestamp, Verbose[RV]:
Sweep range of sizes [n]:
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds:
Packet has IP options:  Total option bytes= 39, padded length=40
 Record route: <*>
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)

Reply to request 0 (68 ms).  Received packet has options
 Total option bytes= 40, padded length=40
 Record route:
   (12.1.1.1)
   (23.1.1.2)
   (3.3.3.3)
   (23.1.1.3)
   (12.1.1.2)
   (12.1.1.1) <*>
   (0.0.0.0)
   (0.0.0.0)
   (0.0.0.0)
 End of list

Traceroute

Tr a c e r o u t e程式可以讓我們看到I P資料報從一臺主機傳到另一臺主機所經過的路由。

Traceroute操作的過程:
它傳送一份T T L欄位為1的I P資料報給目的主機。處理這份資料報的第一個路由器將T T L值減1,丟棄該資料報,併發回一份超時I C M P報文。這樣就得到了該路徑中的第一個路由器的地址。然後Tr a c e r o u t e程式傳送一份T T L值為2的資料報,這樣我們就可以得到第二個路由器的地址。繼續這個過程直至該資料報到達目的主機。但是目的主機哪怕接收到T T L值為1的I P資料報,也不會丟棄該資料報併產生一份超時I C M P報文,這是因為資料報已經到達其最終目的地。那麼我們該如何判斷是否已經到達目的主機了呢?
Tr a c e r o u t e程式傳送一份U D P資料報給目的主機,但它選擇一個不可能的值作為U D P埠號(大於30 000),使目的主機的任何一個應用程式都不可能使用該埠。因為,當該資料報到達時,將使目的主機的U D P模組產生一份“埠不可達”錯誤的I C M P報文。這樣,Tr a c e r o u t e程式所要做的就是區分接收到的I C M P報文是超時還是埠不可達,以判斷什麼時候結束。

下圖是Traceroute的一個抓包過程例項:

我們發現源埠(49175)也很大。Traceroute程式將其傳送的UDP資料報的源埠設定為Unix程序號與32768之間的邏輯或值。對於在同一臺主機上多次執行Traceroute程式的情況,每個程序都檢視ICMP返回的UDP首部的源埠號,並且只處理那些對自己傳送應答的報文。1)、我們並不能保證現在的路由也是將來的所要採用的路由,甚至兩份連續的IP資料報都可能採用不同的路由。
2)、不能保證ICMP報文的路由與Traceroute程式傳送的UDP資料報採用同一路由。這表明打印出來的往返的時間可能並不能真正體現資料報發出和返回的時間差(如UDP資料報從源到路由器的時間是1s,而ICMP報文用另一條路由返回信源用了3s時間,則打印出來的往返時間是4s)
3)、返回的ICMP報文中的源IP是UDP資料報達到的路由器介面的IP地址。這與IP記錄路由選項不同,IP記錄的記錄的是傳送介面的IP地址

源站路由所指的每一個IP地址是如介面IP。分為嚴格和寬鬆,嚴格則必須每一條都是直連的;而寬鬆則沒必要,只要經過的路由IP是在記錄內即可。

一個Traceroute應用的例項:
有時候我們ping不通,此時有可能是ping包沒有到達目的地,也有可能ping包無法返回。此時我們就用到Traceroute,目的IP寫自己的IP地址,寬鬆源站路由寫目的IP:Traceroute過去到了目的,然後再Traceroute回來。只要中間任何地方出現了不通就會報錯,然後就知道問題出現在哪兒了。

預設情況下XP是不轉發資料包的,交換機也是不轉發包的。

ICMP重定向

當I P資料報應該被髮送到另一個路由器時,收到資料報的路由器就要傳送I C M P重定向差錯報文給I P資料報的傳送端。只有當主機可以選擇路由器傳送分組的情況下,我們才可能看到I C M P重定向報文。
1) 我們假定主機發送一份I P資料報給R 1。這種選路決策經常發生,因為R 1是該主機的預設路由。
2) R1收到資料報並且檢查它的路由表,發現R 2是傳送該資料報的下一站。當它把資料報傳送給R 2時,R 1檢測到它正在傳送的介面與資料報到達介面是相同的(即主機和兩個路由器所在的L A N)。這樣就給路由器傳送重定向報文給原始傳送端提供了線索。
3) R1 傳送一份I C M P重定向報文給主機,告訴它以後把資料報傳送給R 2而不是R 1。

我們做一下實驗:

此時我們在Host上配置預設閘道器:default gataway 123.1.1.2,然後關閉Host的F0/0介面的路由功能:no ip routing。R2與R3執行OSPF,然後我們在Host上Traceroute 3.3.3.3發生了重定向:
R1#traceroute 3.3.3.3
Type escape sequence to abort.
Tracing the route to 3.3.3.3
  1 123.1.1.3 28 msec 20 msec 16 msec

然後啟動Host上的路由功能,配置指向R2的預設路由 ip route 0.0.0.0 0.0.0.0 123.1.1.2,此時我們抓包發現Host還是能收到R2傳送的重定向訊息,不過Host並不會理睬這個訊息,因為自己有路由功能。
R1#traceroute 3.3.3.3
Type escape sequence to abort.
Tracing the route to 3.3.3.3
  1 123.1.1.2 40 msec 12 msec 8 msec
  2 123.1.1.3 16 msec 20 msec 20 msec

在生成I C M P重定向報文之前這些條件都要滿足。
1) 出介面必須等於入介面。
2) 用於向外傳送資料報的路由不能被I C M P重定向報文建立或修改過,而且不能是路由器的預設路由。
3) 資料報不能用源站選路來轉發。
4) 核心必須配置成可以傳送重定向報文。

主機在收到ICMP重定向訊息後要做以下檢查:
1) 新的路由器必須直接與網路相連線。
2) 重定向報文必須來自當前到目的地所選擇的路由器。
3) 重定向報文不能讓主機本身作為路由器。
4) 被修改的路由必須是一個間接路由。