三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学
新年快樂,繼續來部分粘貼復制我的這一系列文章啦,如果對和程序員有關的計算機網絡知識,和對計算機網絡方面的編程有興趣,歡迎去gitbook(https://rogerzhu.gitbooks.io/-tcp-udp-ip/content/)star我的這一系列文章,雖然說現在這種“看不見”的東西真正能在實用中遇到的機會不多,但是我始終覺得無論計算機的語言,熱點方向怎么變化,作為一個程序員,很多基本的知識都應該有所了解。而當時在網上搜索資料的時候,這方面的資料真的是少的可憐,所以,我有幸前兩年接觸了這方面的知識,我覺得我應該把我知道的記錄下來,雖然寫的不一定很好,但是希望能給需要幫助的人多個參考。我的計劃是用半年時間來寫完這一系列文章,這個標題也是我對太多速成文章的一種態度,好了,廢話不再多扯了,下面是其中的一節內容,更多內容可以去gitbook上找到。
?
TraceRoute 是另外一個利用ICMP的程序,目的為了找到一個端點到另一個端點的路線,其設計理念我個人是覺得十分的巧妙。而且這個程序在windows和linux上還使用了稍微有點點不同的方法,但是卻可以看到有異曲同工之妙的地方。
TraceRoute的起源
TraceRout這個網絡工具主要是由一個叫Van Jacobson的大牛完成的,這位大牛應該算是互聯網名人堂級人物,他最出名的應該是提出了TCP里面的Jacobson算法用以解決擁塞問題,而這個算法在今天百分之九十的TCP終端上面都在運用。 1987年,他在另外一位大牛Steve Deering的建議下寫了這樣一個探測網絡路徑的工具。同樣,在第二大部分,程序的時候,我會用raw socket寫一個玩具版的traceroute程序,來闡述其基本原理。
TTL和ICMP在windows上的結合
在介紹IP頭格式的時候,里面有一個字段叫TTL,Time to live,這個字段起初是規定一個IP數據包在網絡中的生存周期的,防止一個數據包無限制占用網絡資源,畢竟要想一切有秩序,一個上限是不可避免要設置的,所謂的紅線就是這個道理。而隨著網絡基礎設施的升級和網絡規模的增長,連接每個網絡的路由器處理一個數據包的時間基本都遠遠小于1秒鐘,而數據包在路由器之間的網線的上的傳輸時間更是可以忽略不計,所以這個字段就演化成了經過多少個路由器的計數器。每經過一個路由器,TTL的值就會減1,當這個值為0的時候,也就是這個IP數據包消亡的時候。
比如舉個例子,如果某個IP包中TTL設置為1,那么這個數據包就只能在這個一個子網內傳輸,因為一旦經過了一個路由器,TTL就會變成0,該數據包就會消失了。而當這個數據包消失的時候,一個ICMP消息就會被產生,在上個部分里表里,ICMP頭里的Type值為11的時候表示超時,而這個就是當TTL為0的時候被回復的ICMP消息。Windows 的TraceRoute程序就是利用了這個原理,先還是來看一下windows上運行traceroute是啥樣的,不過windows的traceroute程序真名叫tracert,其運行結果如下:
?
?
我尋找的是從我這里到局域網的某一個路由器的地址,可以看到,從我的主機到這個路由器要經過三個路由器,所以有三行輸出,而每行有三個往返時間,這是因為traceroute會發三次ICMP的echo消息,而這個輸出值得我們逐行分析一下。
第一行是到我的局域網路由器(熱點),往返時間是6-8ms之間,這個時候TTL被設置成1,從下面抓到的數據包中可以看到其具體的數據:
從截圖中可以看出,第一個數據包TTL是1,雖然dest IP是100.97.2.9,但實際上在192.168.8.1這個路由器中這個數據包就已經消失了,因為這個時候該IP數據包中的TTL的值已經減為0,192.168.8.1隨即回復一個ICMP消息報告超時。上一節中介紹了ICMP echo的格式,非常簡單,而ICMP超時的數據包的格式比Echo稍微多一點點信息,但是依然是并不復雜,其格式如下:
?
?
?
其中前4個字節和echo是一樣的,只不過這里type變成了11(十進制)標識超時錯誤消息,code為0表示ttl為0發生了超時。接下來4個字節作為保留字節根本沒有用處,目的是和所有ICMP報文格式統一并兼容。而接著后面的數據部分就和echo不同了,而這些被選擇中的數據也是這個數據頭格式的精妙之所在。ICMP的超時消息會把發送方的IP數據頭和IP數據包中頭64個bit作為數據部分傳回給發送方。其作用是可以讓發送方的更上層的進程在如有需要的時候篩選出自己需要的信息和數據包。比如說,有了這個部分,里面就有了IP頭中的TTL信息,發送端就知道是第幾個TTL到期,數據包消失的。而接著的64個bit的數據在特定情況下更是有妙用,特別是在后面要介紹的端口不可達的ICMP消息之中。
第二行就是TTL為2的回復,而這一行全是星號,這是因為有的網關/路由器不會返回ICMP超時報文,甚至為了安全考慮,很多帶有防火墻的路由器不返回各種ICMP報文,所以你會看到上面輸出的星號,而這種暫時的不返回并不妨礙繼續向更深的一層探測,所以在三次沒有返回后,traceroute會將TTL遞增1,繼續發送ICMP的echo報文。
第三行就是TTL為3的結果,而這個時候數據包已經到達目標網絡,由于探測的時候發的是ICMP echo request的消息,所以這個時候發送端可以得到ICMP echo reply消息,具體請參見上一節(你到底在ping什么)。所以發送端就能知道他的數據包已經到達了目的地,也就不會再繼續增加TTL,探測活動停止,這個從抓獲的數據包中也能得到體現。
?
TTL和ICMP在linux上的結合
前面說過traceroute這個程序在linux上和windows上采用一個有一點點不一樣的設計,但是都是利用了ICMP消息和TTL。
Linux上traceroute程序就是使用traceroute這個命令,看起來像句廢話,而linux上追蹤數據包路徑的方法是采用的UDP,而不是ICMP的echo消息。這樣的一個不同點就是,使用UDP的時候,如果對方的端口是沒有的,那么ICMP就會返回端口不可達消息,type是3。而在linux上會在這個UDP消息中使用一個30000以上端口號,這樣當時數據包到達目的主機的時候,由于對方主機并沒有打開這個UDP端口,所以ICMP會返回一個端口不可達的消息,這樣發送端收到端口不可達的時候就知道不需要繼續探測le。其格式和超時的格式是一模一樣的,不同點只是type的數值是3,code的數值3標識端口不可達。
其余中間的探測過程和windows一樣,都是使用ICMP的超時消息。
這里我想要稍微更多的介紹一下端口不可達的ICMP消息之中的data部分了,這個部分包含IP數據頭和IP數據包的前8個字節,那么如果發送端發送的是UDP消息的話,回一下前面介紹的UDP頭的格式,前8個字節正好UDP的頭部,其中含有發送端的Port的到達端的Port,而UDP是IP的data部分,所以說發送端就可以從這個ICMP的錯誤消息中得到更多的信息。從下面這個抓包中可以看出這樣一個data的返回(忽略port號,哈哈):
?
?
傳統的traceroute利用ICMP消息有很多弊端,其中之一就是前面說的有很多網關或者路由器由于安全的設置不會返回任何ICMP錯誤消息,所以現在也有很多探測方法是利用TCP,有興趣可以去搜索一下。
轉載于:https://www.cnblogs.com/ZXYloveFR/p/8204026.html
總結
以上是生活随笔為你收集整理的三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql的配置和启动命令
- 下一篇: [Egret]长按截屏分享、分享截屏图片