2008年1月20日 星期日

[TCP/IP Illustrated] ICMP

簡介

ICMP(Internet Control Message Protocol) 屬於 Network Layer,與 IP 屬於同一層;用途在於當網路傳輸發生異常時,作為警示訊息的通訊之用。

從上面這張圖可以看出,跟 ICMP 往來的協定,除了 IP 之外,還有其他 Application Layer 的協定也會使用到 ICMP。

不過由於 ICMP 終究屬於 Network Layer,因此 ICMP 訊息的傳輸還是必須包在 IP datagram 中進行傳輸,以下用兩張圖來表示其格式:


由於是 IP datagram 的關係,因此 ICMP message 的前方必須還要再加上 20 bytes 的 IP header 資訊才有辦法傳送出去。

ICMP 是個很重要的協定,不論是常用的 ping,甚至是處理 IP routing 的時候,都會用到 ICMP;在這個部分,我們將會針對 address mask request/reply、timestamp request/reply、port unreachable error ....等不同型態的 ICMP message 進行說明。


ICMP message Type

在介紹 ICMP message Type 之前,必須先知道 ICMP message 的結構是如何,以下用依張圖來說明:


其中最前面的 16 bits (0~15) 的 type + code 欄位,即是是用來表示 ICMP message Type,以下用一個表格列出 ICMP message Type:(表格中的最後兩個欄位用來表示 ICMP message 是用來查詢,或是通知有錯誤發生之用)
type
code
描述
Query
Error
0
0
echo reply (ping)
*

3

destination unreachable



0
network unreachable

*

1
host unreachable

*

2
protocol unreachable

*

3
port unreachable

*

4
fragmentation needed but don't-fragment bit set

*

5
source route failed

*

6
destination network unknown

*

7
destination host unknown

*

8
source host isolated (此狀態淘汰不用了)

*

9
destination network administratively prohibited

*

10
destination host administratively prohibited
*

11
network unreachable for TOS

*

12
host unreachable for TOS

*

13
communication administratively prohibited by filtering

*

14
host precedence violation

*

15
precedence cutoff in effect

*
4
0
source quench (elementary flow control)

*
5

redirect



0
redirect for network

*

1
redirect for host

*

2
redirect for type-of-service and network

*

3
redirect for type-of-service and host

*
8
0
echo request (ping)
*

9
0
router advertisement
*

10
0
router solicitation
*

11

time exceeded



0
time-to-live equal 0 during transit (traceroute)

*

1
time-to-live equal 0 during reassembly

*
12

parameter problem



0
IP header bad (catchall error)

*

1
required option missing

*
13
0
timestamp request
*

14
0
timestamp reply
*

15
0
information request
*

16
0
information reply
*

17
0
address mask request
*

18
0
address mask reply
*


由上表可知,ICMP message 有分為 Query 與 Error 兩種;其中若發送的是 ICMP error message,表示在 ICMP message 中一定包含了讓網路通訊發生錯誤的 IP datagram 其中的一些資訊。

其中,針對以下幾種訊息,不會產生 ICMP error message 作為回應:
  1. ICMP error message
    若是會針對 ICMP error message 回應 ICMP error message,那就會變成無限迴圈了....
  2. 目的地為 IP broadcast address 或是 IP multicast address 的 datagram
  3. 在 Link Layer 廣播的 datagram
  4. 切成多段 fragment 的訊息 (第一個 fragment 除外)
  5. 在 source address 欄位部分沒有定義主機資訊的 datagram(這表示 source address 不會是 zero address、loopback address、broadcast address、或是 multicast address)

以上的種種限制,都是為了不讓 ICMP error message 在網路上過於氾濫而造成 broadcast storm。


ICMP address mask request/reply

ICMP address mask request 通常是用在無硬碟的系統上,用來在開機時取得 subnet mask(子網路遮罩) 的資訊,其作用類似 ARP,只不過問的不是 MAC address 而是 subnet mask address。

以下用一張圖來說明 ICMP address mask message 的結構:

其中 identifier 與 sequence number 的欄位可由傳送 reply 訊息的人填入任何訊息,再跟著 ICMP address mask reply message 一起回傳。

在這裡有一點必須注意,由於 ICMP message 屬於 broadcast,而在同一個網段內,所有的電腦都會收到 broadcast 訊息,包含自己! (大概是因為 loopback 的機制)

因此若是用 tcpdump 程式去監控機器的封包,若是發出 ICMP request message,有時候會看到自己對此封包的 ICMP reply message。

另外一點需要補充的是,在正常的情況下,包含 ICMP reply 的 IP datagram 中,會指定 IP header 中的 source address 為發送 ICMP request 的機器,而不會是 broadcast。


ICMP timestamp request/reply

ICMP timestamp request 是用來詢問其他電腦時間之用,以下先介紹 ICMP timestamp message 的結構:


稍微注意一下在 timestamp 的部分有三個欄位,分別是 originate、receive、transmit,透過這三個欄位的搭配計算,就可以將兩台電腦的時間進行同步。

此外,還有其他方法可以取得目前時間,以下舉個例子:
#直接詢問 time server
shell> telnet stdtime.gov.tw daytime


ICMP port unreachable error

上面兩個部分講的都是 query message,這個部分要說的是 error message - port unreachable error。

不論是 TCP or UDP,當傳輸的封包中,在 TCP/UDP header 中的 destination port 欄位所指定的值,對方主機並沒有針對此 port 提供服務,那就會回傳 ICMP port unreachable error。

以下用圖來表示 ICMP unreachable message 的結構:


從 ICMP message type 的列表中,光是 destination unreachable (type = 3) 的錯誤就有 16 種(code = 0~15),其中 port unreachable (code = 3) 只是其中一種而已。

以下還是以 port unreachable error 說明一下流程;按照正常的情況下,透過 telnet 去偵測一個未開啟服務的 port,應該會發生以下的事情:
  1. sender 傳送 ARP request 詢問 MAC address
  2. receiver 回傳 ARP reply 告知 MAC address
  3. sender 傳送 destination port 為未提供服務 port 的封包
  4. receiver 回傳 port unreachable error 的錯誤

不過經過 tcpdump 檢測封包的實測結果,第三第四個步驟並沒有相關訊息出現,因此研判有可能是 firewall 的關係。

2 則留言:

  1. 想請問一下如何能得到timestmap的完整時戳,在fedora系統下輸入指令icmpush -tstamp (ip)只能得到回傳時間,要如何才可以得到完整三個時間?謝謝

    回覆刪除