ICMP

TCP/UDP/IP 協定若有錯誤情形發生時,會利用 Internet Control Message Protocol(ICMP)協定來送錯誤訊息 。雖然 IP 用 ICMP 來送錯誤訊息,但是 ICMP 的封包卻是利用 IP 來包裝與傳送。

在 ICMP 的 type 中,目前約有 15 種。其中較重要的式:

  1. Echo Request/Reply:任何一台電腦可以送 echo request 給另一台電腦,如果網路正常 收到 echo request的電腦便會回 echo reply。目前我們常用的指令 ping 就是利用這兩個指令來做。Echo Request 與 Reply 的 type 及 code 分別是 (8,0)與(0.0)。

  2. Destination Unreachable:這類訊息的 type 值是 3。可能的訊息包括 network unreachable (code=0),host unreachable(code=1),protocol unreachable(code=2), port unreachable(code=3),source route fail(code=5) ,destination network unknown (code=6), destination host unknown(code = 7 ) 等 。

  3. Source Quench:當 router 的 buffer 已滿,無法再接收並轉送封包時,router 必須丟掉再傳來的的封包 。 此時,router 要送 source quench(type=4)的 ICMP 訊息給此封包之 source。

  4. Routing redirect:如果一區域網路有兩台以上之 router,那麼有時工作站會將封包交給不對的 router 來轉送。此時 router 會將封包轉給正確的 router,並送 一個 redirect( type=5, code=0 or 1, (network host))的 ICMP 訊息給 source。

  5. Time Exceeded:IP header 中的 TTL 表示可經過多少的 router。如果 router 拿到一封包,將其 TTL 減一後是零,router 便將封包丟掉,並送給 source 一 Time Exceeded(type=11 )的 ICMP 訊息。我們常用的 traceroute 指令便是利用此 ICMP 訊息來知道路徑。

  6. IP header error:若封包的 IP header 有錯(如 option 設錯或無法進行)則送此 ICMP 訊息(type=12)。

  7. Address Mask Request/Reply:一台電腦可以廣播 Address Mask Request(type = 17, code = 0 ) 之ICMP 訊 息以詢問 subnet mask 之值。Router 收到後,會 回 Address Mask Reply(type=18, code=0)訊息。

【 遠端主機連通測試 -- Ping 】

ICMP最常使用ICMP的是「封包網際網路groper程式」,也就是一般所稱ping(Packet InterNet Groper)會命令你的IP堆疊送出一個ICMP Echo請求(型態8),然後等待ICMP Echo回應(型態0)。假如ICMP封包的目的地有開機且具有IP堆疊,同時不再阻擋ICMP echo的裝置(防火牆)之後,你的IP堆疊就會收到ICMP Echo回應,並於ping程式中展示出,那代表遠端系統有開機而且可到達。i

ping 與其他的 Internet 服務程式不太相同,大部份的 TCP/IP 系統都將 ping 的 Server 端的reply功能直接設計在kernel內,而不像其他的服務,另外還必須執行一個 Server 端的 Daemon 應用程式。

ping 除了可以用來測試與遠端主機間的網路是否暢通外,從它顯示的 round-trip time,RTT,也可以提供我們一些其他的訊息,比如該主機到底離我們有多遠、或是彼此間的傳輸速率.是快是慢。由傳回的封包數目的遺失率,也可用來判斷目前彼此間的網路情況是否正常或忙碌。

我發現這篇文章,有關ICMP的應用及 OS 偵測技術的文章,最主要是探討作業系統對於 TOS(Type-of-Service)位元所做的回應,當你使用 Ping 送出 一個 ICMP ECHO請求時,對方機器的 ECHO Reply回應裡面,不同作業系統對於 TOS位元所設定的 IP TTL 欄位值,都不一樣,我們可以用它來作為作業系統的判斷。

EX. ping -v 1 -n 1 www.hinet.net
Reply from 202.39.225.89: byte=32 time=55ms TTL=245
用NETcraft查
The site www.hinet.net is running Apache/1.3.12 (Unix) on Solaris.

EX. ping -v 1 -n 1 www.seednet.net.tw
Reply from 192.72.80.36: byte=32 time=42ms TTL=250
The site www.seednet.net.tw is running Netscape-Enterprise/3.6 SP2 on Solaris.

大體上整理出來
一、Linux、Solaris....這些 Linux/Unix 的機器,它們的 TTL 值大約都在 240∼254 之間
二、Windows系列的機器,它們的 TTL 值大約都在 110∼128 之間。

# OS VERSION PLATFORM TTL WINDOS DF TOS
DC-OSx 1.1-95 Pyramid/NILE 30 8192 n 0
Windows 9x/NT Intel 32 5000-9000 y 0
NetApp OnTap 5.1.2-5.2.2 54 8760 y 0
HPJetDirect ? HP_Printer 59 2100-2150 n 0
AIX 4.3.x IBM/RS6000 60 16000-16100 y 0
AIX 4.2.x IBM/RS6000 60 16000-16100 n 0
Cisco 11.2 7507 60 65535 y 0
DigitalUnix 4.0 Alpha 60 33580 y 16
IRIX 6.x SGI 60 61320 y 16
OS390 2.6 IBM/S390 60 32756 n 0
Reliant 5.43 Pyramid/RM1000 60 65534 n 0
Freebsd 3.x Intel 64 17520 y 16
JetDirect G.07.x J3113A 64 5804-5840 n 0
Linux 2.2.x Intel 64 32120 y 0
OpenBSD 2.x Intel 64 17520 n 16
OS/400 R4.4 AS/400 64 8192 y 0
SCO R5 Compaq 64 24820 n 0
Solaris 8 Intel/Sparc 64 24820 y 0
FTX(UNIX) 3.3 STRATUS 64 32768 n 0
Netware 4.11 Intel 128 32000-32768 y 0
Windows 9x/NT Intel 128 5000-9000 y 0
Windows 2000 Intel 128 17000-18000 y 0
Cisco 12.0 2514 255 3800-5000 n 192
Solaris 2.x Intel/Sparc 255 8760 y 0

【 路由追蹤 -- traceroute 】

每次封包由某一個同樣的出發點,到達某一個同樣的目的地,所走的路由有可能會不一樣,但是基本上來說,大部份的時候所走的路由會是相同的。

traceroute 程式的設計是利用到 ICMP 及 IP header 的 TTL (Time To Live)欄位(field);首先 traceroute 送出一個 TTL 是 1 的 IP datagram 到目的地,當路徑上的第一個路由器(router)收到這個 datagram 時,它將 TTL 減 1,此時 TTL 變為 0 了,所以該路由器會將此一 datagram 丟掉,並送回一個 「ICMP time exceeded」 訊息;traceroute 收到這個訊息後,便知道這個路由器存在於這個路徑上;接著 traceroute 再送出另一個 TTL 是 2 的 datagram,發現第 2 個路由器...;traceroute 每次將送出的 datagram 的 TTL 加 1,來發現另一個路由器;這個重覆的動作一直持續到某個 datagram 抵達目的地。當 datagram 到達目的地後,該主機並不會送回 ICMP time exceeded 訊息,因為它已是目的地了;那麼 traceroute 如何得知目的地到達了呢?

traceroute 在送出 UDP datagrams 到目的地時,它所選擇送達的 port number 是一個一般應用程式都不會用的號碼(30000 以上);所以當此一 UDP datagram 到達目的地後,該主機會送回一個「ICMP port unreachable」的訊息,而當 traceroute 收到這個訊息時,便知道目的地已經到達了;所以 traceroute 在 Server 端亦是沒有所謂的 Daemon 程式。

UDP標頭裡包含的是來源和目的地連接阜號, traceroute客戶端設定其UDP來源阜號為其處理程序ID( process ID)與32768的Logical-OR運算值,目的地端阜號以33435開始在每當datagram被送出去時加一,(起始阜號可藉由命令列的選項參數變更),如果traceroute 在同一台主機上被執行過很多次,則每一個程序都會檢查被ICMP傳回來的UDP datagram來源阜號,並且只會處理回復自己所送出去作探測的datagram。

1st: send UDP(Dst Port=33435)+IP(TTL=1), receive ICMP(Time Exceeded)
2nd: send UDP(Dst Port=33436)+IP(TTL=2), receive ICMP(Time Exceeded)
3rd: send UDP(Dst Port=33437)+IP(TTL=3), receive ICMP(Time Exceeded)
.....
last: send UDP(Dst Port=33XXX)+IP,
Dst Host收到但沒有port=33XXX之application (Daemon),
所以Dst Host回ICMP(Unreachable Port)