在 ICMP 的 type 中,目前約有 15 種。其中較重要的式:
【 遠端主機連通測試 -- 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)