Try   HackMD

IPv4 - Fragmentation

課程影片

第 7F 講 路由器運作原理以及網路互連技術 L07 6

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

術語:MTU

每一種傳輸介質或協定,其單一封包的大小都有上限。這個單一封包的大小上限,稱為 MTU (Maximun Transmission Unit)。舉例來說,乙太網路單一封包最大只能傳輸 1,518 位元組,而 802.11 的傳輸上限則為 2,312 位元組。

問題:L3 封包擠不進 L2 的 MTU

這時候就產生了一個問題:當一個 IP 封包大小太大,以致於無法在 L2 以單一封包傳輸時,這樣該怎麼處理呢?

解法:Fragmentation

這時候,就要想辦法把 IP 封包裡面的資料分割,每一個分割後的資料各被包裝成一系列的封包,分別傳送。等這一系列封包到了目的地之後,再組裝起來。

注意是「到目的地之後」才會組裝起來。所以被分割的封包就是被分割了。

例子

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在這個例子中,假定

H5 的封包得經由
R1R3
三個路由器轉送到
H8
。則分個的

H5 到 R1

H5 藉由 WiFi 將封包傳輸給 R1

R1 到 R2

R1R2 使用乙太網路連接。這時候乙太網路的單一封包仍然裝得下,因此就不分割。僅僅是把表頭從 802.11 換成乙太網路的。

R2 到 R3

這時候,因為 PPP 的單一封包最多只能傳輸 512 位元組,所以封包被分割成 3 份:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

R3 到 H8

三個被分割的小封包藉由乙太網路傳送給 H8。注意 封包的組裝是發生在接收方,路由器不會把已經分割的封包重新組裝。因此,儘管 R3H8 使用的是乙太網路,可以一個封包就能傳輸 1,400 位元組,R3 也不會因為這樣就把這 3 個小封包重新組裝起來。

分割封包

沒分割的封包 - MFfrag_off 同時為 0

對於一個沒有分割的封包,它的 MFfrag_off 會同時是 0。這是因為 frag_off0,表示它是一系列分割後的封包中,最前面的封包; 但是這時 MF 又是 0,表示這一系列的封包中,已經沒有更多封包了。因此這樣的封包 MFfrag_off 同時為 0。

對於這樣的封包,MFfrag_off 至少有一者不是 0。所以有三三種狀況。

分割的第一部分 - MF 非 0,frag_off 為 0

這表示這個封包是一系列分割後產生的封包的第一個,而且因為 MF 不是 0,所以表示它不是這一系列封包的最後一個。舉例來說,上圖的第一個封包就是這個例子。

分割的中間 - MF 非 0,frag_off 非 0

因為 MF 非零,表示這不是這一系列封包的最後一個。而這時這個封包的 frag_off,表示這是原先封包的資料中的起始位置。注意起始位置其實是 (frag_off*8)

舉例來說,上圖第二個封包中,frag_off64,表示這個封包當中的資料,是原先封包第

648=512 位元組開始的資料。而這也跟第一個封包所含的資料大小一樣,恰好就是 512 位元組。

又比如說,上面第三個封包的 frag_off128,表示這個封包中的資料,是原封包中第

1288=1,024 位元組開始算起的資料。這也而這個 1,024 恰好就是前 2 個封包資料量的總和。

分割的最後一個封包 - MF 為 0,frag_off 非 0

DF0 表示這一系列沒有其他封包了。

組合封包 - 由 (frag_off*8, tot_len) 組合

那拿到封包之後,要怎麼把它們組合起來呢?對於一系列具有相同 id 的封包:

  1. 每拿到一個封包,就可以知道它表示原先資料的「從 (frag_off*8) 開始的 tot_len 位元組」。
  2. 直到收集到該 id 下, MF0 的那個封包為止。

這眾多的 (frag_off*8, tot_len) 集合起來,就可以像拼拼圖那樣拼出完整的資料。而如果中間有少的話,那該怎麼辦?答案是直接丟棄,因為 IP 是不可靠傳輸。