[面試∙網路] TCP/IP(二):IP協議

bestswifter發表於2017-12-12

IP協議處於OSI參考模型的第三層——網路層,網路層的主要作用是實現終端節點間的通訊。IP協議是網路層的一個重要協議,網路層中還有ARP(獲取MAC地址)和ICMP協議(資料傳送異常通知)

資料鏈路層的作用在於實現同一種資料鏈路下的包傳遞,而網路層則可以實現跨越不同資料鏈路的包傳遞。比如主機A通過Wi-Fi連線到路由器B,路由器B通過乙太網連線到路由器C,而路由器C又通過Wi-Fi與主機D保持連線。這時主機A向D傳送的資料包就依賴於網路層進行傳輸。

這篇文章主要介紹IP協議的基本知識和IP首部,IP協議可以分為三大作用模組:IP定址、路由和IP分包。

IP地址

IP地址是一種在網路層用於識別通訊對端資訊的地址。它有別於資料鏈路層中的MAC地址,後者用於標識同一鏈路下不同的計算機。

舉一個形象的例子,我要從鎮江的家裡去瀋陽的東北大學,通訊兩端的地址分別是家和學校,他們相當於IP地址。然而沒有交通工具可以讓我從家直接去學校,所以我先要叫車去火車站,然後坐高鐵到瀋陽站,再轉公交去學校。這三次中轉分別屬於三種交通方式(資料鏈路),每一次中轉都有起點和終點,他們就相當於MAC地址。每次中轉可以稱為一跳(Hop)

IP地址由32位正整數表示,為了直觀的表示,我們把它分成4個部分,每個部分由8位整陣列成,對應十進位制的範圍就是0-255。

比如172.20.1.1可以表示為:10101100 00010100 00000001 00000001。轉換規則很簡單,就是分別把四個部分的十進位制(0-255)與8位二進位制數字進行轉換。

從功能上看,IP地址由兩部分組成:網路標識和主機標識。

網路標識用於區分不同的網段,相同段內的主機必須擁有相同的網路表示,不同段內的主機不能擁有相同的網路標識。

主機標識用於區分同一網段下不同的主機,它不能在同一網段內重複出現。

32位IP地址被分為兩部分,到底前多少位是網路標識呢?一般有兩種方法表示:IP地址分類、子網掩碼。

IP分類

IP地址分為四個級別,分別為A類、B類、C類和D類。分類的依據是IP地址的前四位:

A類IP地址是第一位為“0”的地址。A類IP地址的前8位是網路標識,用十進位制標識的話0.0.0.0-127.0.0.0是A類IP地址的理論範圍。另外我們還可以得知,A類IP地址最多隻有128個(實際上是126個,下文不贅述),每個網段內主機上限為2的24次方,也就是16,777,214個。

B類IP地址是前兩位為“10“的地址。B類IP地址的前16位是網路標識,用十進位制標識的話128.0.0.0-191.255.0.0是B類IP地址的範圍。B類IP地址的主機標記長度為16位,因此一個網段內可容納主機地址上限為65534個。

C類IP地址是前三位為“110”的地址。C類IP地址的前24位是網路標識,用十進位制標識的話192.0.0.0-223.255.255.0是C類IP地址的範圍。C類地址的後8位是主機標識,共容納254個主機地址。

D類IP地址是前四位為“1110”的地址。D類IP地址的網路標識長32位,沒有主機標識,因此常用於多播。

子網掩碼

IP地址總長度32位,它能表示的主機數量有限,大約在43億左右。而IP地址分類更是造成了極大的浪費,A、B類地址一共也就一萬多個,而世界上包含主機數量超過254的網段顯然不止這麼點。

我們知道IP地址分類的本質是區分網路標識和主機標識,另一種更加靈活、細粒度的區分方法是使用子網掩碼。

子網掩碼長度也是32位,由一段連續的1和一段連續的0組成。1的長度就表示網路標識的長度。以IP地址172.20.100.52為例,它本來是一個B類IP地址(前16位是網路標識),但通過子網掩碼,它可以是前26為為網路標識的IP地址:

子網掩碼

路由控制

路由控制(Routing)是指將分組資料傳送到目標地址的功能,這個功能一般由路由器完成。(不要與家裡用的小型無線路由器混為一談)

路由器中儲存著路由控制表,它在路由控制表中查詢目標IP地址對應的下一個路由器地址。下圖描述了這一過程:

路由控制

主機A的地址是10.1.1.30,要把資料發往地址為10.1.2.10的主機。在主機A的路由表中,儲存了兩個欄位,由於目標地址10.1.2.1010.1.1.0/24段不匹配,所以它被髮往預設路由10.1.1.1也就是圖中路由器1的左側網路卡的IP地址。

路由器1繼續在它自己的路由控制表中查詢目標地址10.1.2.10,它發現目標地址屬於10.1.2.0/24這一段,因此將資料轉發至下一個路由器10.1.0.2,也就是路由器2的左側網路卡的地址。

路由器2在自己的路由控制表中查詢目標地址10.1.2.10,根據表中記錄將資料發往10.1.2.1介面,也就是自己的右側網路卡的IP地址。主機B檢查目標IP地址和自己相同,於是接收資料。

路由控制表

路由控制的關鍵在於路由控制表,路由控制表可以由管理員手動設定,稱為靜態路由控制,但是估計大部分人沒這麼幹過。這是因為路由器可以喝其他路由器互換資訊比即使自動重新整理路由表,這個資訊交換的協議並沒有在IP協議中定義,而是由一個叫做“路由協議”的協議管理。

環路

上圖中,假設主機A向一個不存在的IP地址傳送資料,並且路由器1、2、3設定的預設路由形成了一個迴圈,那麼資料將在網路中不斷轉發最終導致網路擁堵。這個問題將在下文分析IP首部時得到解決。

IP報文分割重組

在資料鏈路層中,我們已經提到過不同的資料鏈路有不同的最大傳輸單元(MTU)。因此IP協議的一個任務是對資料進行分片和重組。分片由傳送端主機和路由器負責,重組由接收端主機負責。

路徑MTU發現

分片會加重路由器的負擔,因此只要條件允許,我們都不希望路由器對IP資料包進行分片處理。另外,如果一個分片丟失,整個IP資料包都會作廢。

解決以上問題的技術是“路徑MTU發現”。主機會首先獲取整個路徑中所有資料鏈路的最小MTU,並按照整個大小將資料分片。因此傳輸過程中的任何一個路由器都不用進行分片工作。

為了找到路徑MTU,主機首先傳送整個資料包,並將IP首部的禁止分片標誌設為1.這樣路由器在遇到需要分片才能處理的包時不會分片,而是直接丟棄資料並通過ICMP協議將整個不可達的訊息發回給主機。

主機將ICMP通知中的MTU設定為當前MTU,根據整個MTU對資料進行分片處理。如此反覆下去,直到不再收到ICMP通知,此時的MTU就是路徑MTU。

以UDP協議傳送資料為例:

路徑MTU發現

重組

接收端根據IP首部中的標誌(Flag)和片偏移(Fragment Offset)進行資料重組。具體內容將在分析IP首部時詳細解釋。

IP首部(IPv4)

IP首部是一個有些複雜的結構,我們不用記憶它的結構,只需瞭解每個部分的作用即可,這樣可以加深對IP協議的理解。

IP首部

其中幾個重要的部分介紹如下:

  • 總長度(Total Length):表示IP首部與資料部分總的位元組數,該段長16位元,所以IP包的最大長度為65535位元組(2^16)。雖然不同資料鏈路的MTU不同,但是IP協議遮蔽了這些區別,通過自己實現的資料分片功能,從上層的角度來看,IP協議總是能夠以65535為最大包長進行傳輸。

  • 標識(ID:Identification):用於分片重組。屬於同一個分片的幀的ID相同。但即使ID相同,如果目標地址、源地址、上層協議中有任何一個不同,都被認為不屬於同一個分片。

  • 標誌(Flags):由於分片重組,由三個位元構成。

    第一個位元未使用,目前必須是0。

    第二個位元表示是否進行分片,0表示可以分片,1表示不能分片。在路徑MTU發現技術中就用到了這個位。

    第三個位元表示在分片時,是否表示最後一個包。1表示不是最後一個包,0表示分配中最後一個包。

  • 片偏移(FO: Fragment Offset):由13位元組成,表示被分片的段相對於原始資料的位置。它可以表示8192(2^13)個位置,單位為8位元組,所以最大可以表示8 x 8192 = 65536位元組的偏移量。

  • 生存時間(TTL: Time To Live):表示包可以經過多少個路由器的中轉。每經過一個路由器,TTL減1。這樣可以避免前文提到的無限傳遞包的問題。

  • 協議: 表示IP首部的下一個首部屬於哪個協議。比如TCP協議的編號為6,UDP編號為17.

  • 首部校驗和:用於檢查IP首部是否損壞

  • 可選項:僅在試驗或診斷時用,可以沒有。如果有,需要配合填充(Padding)佔滿32位元。

相關文章