IP資料包的分片和組裝過程

ShawnLeex發表於2016-07-21

        一份資料從一個主機通過乙太網傳送到裡一個主機時,是要經過很多層路由轉發的。其中過程相對比較的複雜,在這裡我們要討論的是IP在路由中轉發時是以怎樣的形式轉發的和目的主機在接受到這寫資料包時又是怎樣處理的。

       首先我們需要了解的是整個IP資料包的格式



IP的轉發控制都是由IP資料包的頭部決定的。在這裡我們就不詳細的討論首部的所有欄位,我們就討論一下個分片有關的總長度欄位。

       在IP資料包中,總長度是16位的欄位,依次資料包的最大長度為2^16-1=65535位元組,雖然儘可能長的資料包可以提升傳輸速率,但是由於乙太網的普遍應用,實際上使用資料包長度很少超過1500個位元組的,所以在這裡,只要超過1500位元組,我們就認為此資料包應該分片了。

IP資料包被分片以後,各分片(fragment)分別組成一個具有IP首部的分組,並各自獨立地選擇路由,在其分別抵達目的主機後,目的主機的IP層會在傳送給傳輸層之前將接收到的所有分片重灌成一個IP資料包。可以怎麼理解,IP資料包是IP層端到端的傳輸單元(在分片之前和重組之後),分組是指在IP層和鏈路層之間傳送的資料單元。一個分組可以是一個完整的IP資料包也可以是IP資料包的一個分片。而分片對傳輸層是透明的。


一。IP分片

(一)IP分片的原理:

     分片和重新組裝的過程對傳輸層是透明的,其原因是當IP資料包進行分片之後,只有當它到達下一站時,才可進行重新組裝,且它是由目的端的IP層來完成的。分片之後的資料包根據需要也可以再次進行分片。
    IP分片和完整IP報文差不多擁有相同的IP頭,ID域對於每個分片都是一致的,這樣才能在重新組裝的時候識別出來自同一個IP報文的分片。在IP頭裡面,16位識別號唯一記錄了一個IP包的ID(ipid),具有同一個ID的IP分片將會重新組裝;而13位片偏移則記錄了某IP片相對整個包的位置;而這兩個表中間的3位標誌則標誌著該分片後面是否還有新的分片。這三個域就組成了IP分片的所有資訊, 接受方就可以利用這些資訊對IP資料進行重新組織。
    1、標誌欄位的作用
    標誌欄位在分片資料包中起了很大作用,在資料包分片時把它的值複製到每片中。標誌欄位的其中一個位元稱作“不分片”位,用其中一個位元來表示“更多的片”。除了最後一片外,其他每個組成資料包的片都要把該位元置1。片偏移欄位指的是該片偏移原始資料包開始處的位置。另外,當資料包被分片後,每個片的總長度值要改為該片的長度值。如果將標誌欄位的"不分片"位元置1,則IP將不對資料包進行分片。相反把資料包丟棄併傳送一個I C M P差錯報文並通知源主機廢棄的原因。如果不是特殊需要,則不應該置1;最右位元置1表示該報文不是最後一個IP分片。
    故意傳送部分IP分片而不是全部,則會導致目標主機總是等待分片消耗並佔用系統資源。某些分片風暴攻擊就是這種原理。
    這裡以乙太網為例,由於乙太網傳輸電氣方面的限制,每個乙太網幀都有最小的大小64bytes最大不能超過1518bytes, 拋去乙太網幀的幀頭(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和幀尾CRC校驗部分4Bytes,那麼剩下承載上層協議的地方也就是Data域最大就只能有1500Bytes,這就是前面所說的MTU的值。這個也是網路層協議非常關心的地方,因為網路層的IP協議會根據這個值來決定是否把上層傳達下來的資料進行分片。就好比一個盒子沒法裝下一大塊麵包,我們需要把麵包切成片,裝在多個盒子裡面一樣的道理。

     2、MTU原理
  當兩臺遠端PC互聯的時候,它們的資料需要穿過很多的路由器和各種各樣的網路媒介才能到達對端,網路中不同媒介的MTU各不相同,就好比一長段的水管,由不同粗細的水管組成(MTU不同 )通過這段水管最大水量就要由中間最細的水管決定。
  對於網路層的上層協議而言(這裡以TCP/IP協議族為例)它們對水管粗細不在意它們認為這個是網路層的事情。網路層IP協議會檢查每個從上層協議下來的資料包的大小,並根據本機MTU的大小決定是否作“分片”處理。分片最大的壞處就是降低了傳輸效能,本來一次可以搞定的事情,分成多次搞定,所以在網路層更高一層(就是傳輸層)的實現中往往會對此加以注意!有些高層因為某些原因就會要求我這個麵包不能切片,我要完整地面包,所以會在IP資料包包頭裡面加上一個標籤:DF(Donot Fragment)。這樣當這個IP資料包在一大段網路(水管裡面)傳輸的時候,如果遇到MTU小於IP資料包的情況,轉發裝置就會根據要求丟棄這個資料包。然後返回一個錯誤資訊給傳送者。這樣往往會造成某些通訊上的問題,不過幸運的是大部分網路鏈路MTU都是1500或者大於1500。
  對於UDP協議而言,這個協議本身是無連線的協議,對資料包的到達順序以及是否正確到達不甚關心,所以一般UDP應用對分片沒有特殊要求。
  對於TCP協議而言就不一樣了,這個協議是面向連線的協議,對於TCP協議而言它非常在意資料包的到達順序以及是否傳輸中有錯誤發生。所以有些TCP應用對分片有要求---不能分片(DF)。
    3、MSS的原理
  MSS就是TCP資料包每次能夠傳輸的最大資料分段。為了達到最佳的傳輸效能TCP協議在建立連線的時候通常要協商雙方的MSS值,這個值TCP協議在實現的時候往往用MTU值代替(需要減去IP資料包包頭的大小20Bytes和TCP資料段的包頭20Bytes)所以往往MSS為1460。通訊雙方會根據雙方提供的MSS值得最小值確定為這次連線的最大MSS值。
    當IP資料包被分片後,每一片都成為一個分組,具有自己的IP首部,並在選擇路由時與其他分組獨立。這樣,當資料包的這些片到達目的端時有可能會失序,但是在IP首部中有足夠的資訊讓接收端能正確組裝這些資料包片。
    儘管IP分片過程看起來是透明的,但有一點讓人不想使用它:即使只丟失一片資料也要重傳整個資料包。因為IP層本身沒有超時重傳的機制——由更高層來負責超時和重傳(T C P有超時和重傳機制,但UDP沒有。一些UDP應用程式本身也執行超時和重傳)。當來自T C P報文段的某一片丟失後,T C P在超時後會重發整個T C P報文段,該報文段對應於一份IP資料包。沒有辦法只重傳資料包中的一個資料包片。


(二)IP分片的步驟

       一個未分片的資料包的分片資訊欄位全為0,即多個分片標誌位為0,並且片偏移量為0。分片一個資料包,需執行以下幾個步驟:
 檢查DF標誌位,查明是否允許分片。如果設定了該位,則資料包將被丟棄,並將一個ICMP錯誤返回給源端。
 基於MTU值,把資料欄位分成兩個部分或者多個部分。除了最後的資料部分外,所有新建資料選項的長度必須為8個位元組的倍數。
 每個資料部分被放入一個IP資料包。這些資料包的報文頭略微修改了原來的報文頭。
 除了最後的資料包分片外,所有分片都設定了多個分片標誌位。
 每個分片中的片偏移量欄位設為這個資料部分在原來資料包中所佔的位置,這個位置相對於原來未分片資料包中的開頭處。
 如果在原來的資料包中包括了選項,則選項型別位元組的高位位元組決定了這個資訊是被複制到所有分片資料包,還是隻複製到第一個資料包。
 設定新資料包的報文頭欄位及總長度欄位。
 重新計算報文頭部校驗和欄位。
       此時,這些分片資料包中的每個資料包如一個完整IP資料包一樣被轉發。IP獨立地處理每個資料包分片。資料包分片能夠通過不同的路由器到達目的。如果它們通過那些規定了更小的MTU網路,則還能夠進一步對它們進行分片。
在目的主機上,資料被重新組合成原來的資料包。傳送主機設定的識別符號欄位與資料包中的源IP地址和目的IP地址一起使用。分片過程不改變這個欄位。



二。重組

       為了重新組合這些資料包分片,接收主機在第一個分片到達時分配一個儲存緩衝區。這個主機還將啟動一個計時器。當資料包的後續分片到達時,資料被複制到緩衝區儲存器中片偏移量欄位指出的位置。當所有分片都到達時,完整的未分片的原始資料包就被恢復了。處理如同未分片資料包一樣繼續進行。
如果計時器超時並且分片保持尚未認可狀態,則資料包被丟棄。這個計時器的初始值稱為IP資料包的生存期值。它是依賴於實現的。一些實現允許對它進行配置。在某些IP主機上可以使用netstat命令列出分片的細節。如TCP/IP for OS/2中的netstat-i命令。

重組的步驟

在接收方,一個由傳送方發出的原始IP資料包,其所有分片將被重新組合,然後才能提交到上層協議。每一個將被重組的IP資料包都用一個ipq結構例項來表示,因此先來看看ipq這個非常重要的結構。
為了能高效地組裝分片,用於儲存分片的資料結構必須能做到以下幾點:
1、快速定位屬於某一個資料包的一組分組
2、在屬於某一個資料包的一組分片中快速插入新的分片
3、有效地判斷一個資料包的所有分片是否已經全部接收
4、具有組裝超時機制,如果在重組完成之前定時器溢位,則刪除該資料包的所有內容

相關文章