TTl=time to live
這應當從網路的層次講起:
首先,PING命令是屬於ICMP協議規定的,而ICMP是內嵌於IP層的,因此,可以說,PING是網路層的命令。
PING的實現過程很簡單,命令將引發IP層發送一個簡單的IP包,而目的方收到這個包之後,將源和目的地址做一下交換,重新發出這個包即可,當然還要加一些逾時的機制。
簡單來說,為了避免資料包在網路上的傳送路徑造成死迴圈或者無休止的投遞下去,每個ip資料包都包含樂一個壽命計數器,這個就是資料包的的存留時間TTL,也叫hop count,只要一個路由器處理過這個資料包,它就遞減這個資料包的壽命計數,當壽命計數遞減到0的時候,路由器就丟棄該包.
TTL在一定程度上反應了一個IP資料包經過的路由器的多少,但是也不完全是這樣,因為資料包在網路上傳播的時候,其傳播時間和頻寬有一定關係,有時候協議會把傳播時間的長短摺合在TTL裡,能比較客觀的反應網路的狀況。
簡單來說,TTL全程Time to Live,意思就是生存周期。首先要說明ping命令是使用的網路層協議ICMP,所以TTL指的是一個網路層的網路資料包(package)的生存周期,這句話不懂的先回去複習OSI7層協議去。
第一個問題,為什麼要有生存周期這個概念。
很顯然,一個package從一台機器到另一台機器中間需要經過很長的路徑,顯然這個路徑不是單一的,是很複雜的,並且很可能存在環路。如果一個資料包在傳輸過程中進入了環路,如果不終止它的話,它會一直迴圈下去,如果很多個資料包都這樣迴圈的話,那對於網路來說這就是災難了。所以需要在包中設定這樣一個值,包在每經過一個節點,將這個值減1,反覆這樣操作,最終可能造成2個結果:包在這個值還為正數的時候到達了目的地,或者是在經過一定數量的節點後,這個值減為了0。前者代表完成了一次正常的傳輸,後者代表包可能選擇了一條非常長的路徑甚至是進入了環路,這顯然不是我們期望的,所以在這個值為0的時候,網路裝置將不會再傳遞這個包而是直接將他拋棄,並發送一個通知給包的源地址,說這個包已死。
第二個問題,通過TTL值我們能得到什麼
其實TTL值這個東西本身並代表不了什麼,對於使用者來說,關心的問題應該是包是否到達了目的地而不是經過了幾個節點後到達。但是TTL值
還是可以得到有意思的資訊的。每個作業系統對TTL值得定義都不同,這個值甚至可以通過修改某些系統的網路參數來修改,例如Win2000預設為128,通過註冊表也可以修改。而Linux大多定義為64。不過一般來說,很少有人會去修改自己機器的這個值的,這就給了我們機會可以通過ping的回顯TTL來大體判斷一台機器是什麼作業系統。
以我公司2台機器為例
看如下命令
D:/Documents and Settings/hx>ping 61.152.93.131
Pinging 61.152.93.131 with 32 bytes of data:
Reply from 61.152.93.131: bytes=32 time=21ms TTL=118
Reply from 61.152.93.131: bytes=32 time=19ms TTL=118
Reply from 61.152.93.131: bytes=32 time=18ms TTL=118
Reply from 61.152.93.131: bytes=32 time=22ms TTL=118
Ping statistics for 61.152.93.131:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss
Approximate round trip times in milli-seconds:
Minimum = 18ms, Maximum = 22ms, Average = 20ms
D:/Documents and Settings/hx>ping 61.152.104.40
Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.104.40: bytes=32 time=28ms TTL=54
Reply from 61.152.104.40: bytes=32 time=18ms TTL=54
Reply from 61.152.104.40: bytes=32 time=18ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Ping statistics for 61.152.104.40:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss
Approximate round trip times in milli-seconds:
Minimum = 13ms, Maximum = 28ms, Average = 19ms
第一台TTL為118,則基本可以判斷這是一台Windows機器,從我的機器到這台機器經過了10個節點,因為128-118=10。而第二台應該是台Linux
,理由一樣64-54=10。
瞭解了上面的東西,可能有人會有一些疑問,例如以下:
1,不是說包可能走很多重路徑嗎,為什麼我看到的4個包TTL都是一樣的,沒有出現不同?
這是由於包經過的路徑是經過了一些最優選擇演算法來定下來的,在網路拓撲穩定一段時間後,包的路由路徑也會相對穩定在一個最短路徑上。
具體怎麼算出來的要去研究路由演算法了,不在討論之列。
2,對於上面例子第二台機器,為什麼不認為它是經過了74個節點的Windows機器?因為128-74=54。
對於這個問題,我們要引入另外一個很好的ICMP協議工具。不過首先要聲明的是,一個包經過74個節點這個有些恐怖,這樣的路徑還是不用為
好。
要介紹的這個工具是tracert(*nix下為traceroute),讓我們來看對上面的第二台機器用這個命令的結果
D:/Documents and Settings/hx>tracert 61.152.104.40
Tracing route to 61.152.104.40 over a maximum of 30 hops
1 13 ms 16 ms 9 ms 10.120.32.1
2 9 ms 9 ms 11 ms 219.233.244.105
3 12 ms 10 ms 10 ms 219.233.238.173
4 15 ms 15 ms 17 ms 219.233.238.13
5 14 ms 19 ms 19 ms 202.96.222.73
6 14 ms 17 ms 13 ms 202.96.222.121
7 14 ms 15 ms 14 ms 61.152.81.86
8 15 ms 14 ms 13 ms 61.152.87.162
9 16 ms 16 ms 28 ms 61.152.99.26
10 12 ms 13 ms 18 ms 61.152.99.94
11 14 ms 18 ms 16 ms 61.152.104.40
Trace complete.
從這個命令的結果能夠看到從我的機器到伺服器所走的路由,確實是11個節點(上面說10個好像是我犯了忘了算0的錯誤了,應該是64-54+1,
嘿嘿),而不是128的TTL經過了70多個節點。
既然已經說到這裡了,不妨順便說說關於這兩個ICMP命令的進階一點的東西。
首先是ping命令,其實ping有這樣一個參數,可以無視作業系統預設TTL值而使用自己定義的值來發送ICMP Request包。
例如還是用那台Linux機器,用以下命令:
D:/Documents and Settings/hx>ping 61.152.104.40 -i 11
Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.104.40: bytes=32 time=10ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Reply from 61.152.104.40: bytes=32 time=10ms TTL=54
Reply from 61.152.104.40: bytes=32 time=13ms TTL=54
Ping statistics for 61.152.104.40:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 10ms, Maximum = 13ms, Average = 11ms
D:/Documents and Settings/hx>
這個命令我們定義了發包的TTL為11,而前面我們知道,我到這台伺服器是要經過11個節點的,所以這個輸出和以前沒什麼不同。現在再用這個
試試看:
D:/Documents and Settings/hx>ping 61.152.104.40 -i 10
Pinging 61.152.104.40 with 32 bytes of data:
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Reply from 61.152.99.94: TTL expired in transit.
Ping statistics for 61.152.104.40:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 0ms, Maximum = 0ms, Average = 0ms
D:/Documents and Settings/hx>
可以看到,結果不一樣了,我定義了TTL為10來發包,結果是TTL expired in transit.就是說在到達伺服器之前這個包的生命週期就結束了。
注意看這句話前面的ip,這個ip恰好是我們前面tracert結果到伺服器之前的最後1個ip,包的TTL就是在這裡減少到0了,根據我們前面的討論
,當TTL減為0時裝置會丟棄包並發送一個TTL到期的ICMP反饋給源地址,這裡的結果就是最好的證明。
通過這裡再次又證明了從我機器到伺服器是經過了11個節點而不是70多個,呵呵。
最後再鞏固一下知識,有人可能覺得tracer這個命令很神奇,可以發現一個包所經過的路由路徑。其實這個命令的原理就在我們上面的討論中
。
想象一下,如果我給目的伺服器發送一個TTL為1的包,結果會怎樣?
根據前面的討論,在包港出發的第一個節點,TTL就會減少為0,這時這個節點就會回應TTL失效的反饋,這個回應包含了裝置本身的ip地址,這樣我們就得到了路由路徑的第一個節點的地址。因此,我們繼續發送TTL=2的包,也就受到第二個節點的TTL失效回應.依次類推,我們一個一個的發現,當最終返回的結果不是TTL失效而是ICMP Response的時候,我們的tracert也就結束了,就是這麼簡單。
順便補一句ping命令還有個-n的參數指定要發包的數量,指定了這個數字就會按照你的要求來發包了而不是預設的4個包。如果使用-t參數的話,命令會一直發包直到你強行中止它。