# IPv4 - Fragmentation [TOC] ## 課程影片 ### 第 7F 講 路由器運作原理以及網路互連技術 L07 6 {%youtube zH4Ep41EgfI %} ## 術語:MTU 每一種傳輸介質或協定,其單一封包的大小都有上限。這個單一封包的大小上限,稱為 MTU (Maximun Transmission Unit)。舉例來說,乙太網路單一封包最大只能傳輸 1,518 位元組,而 802.11 的傳輸上限則為 2,312 位元組。 ### 問題:L3 封包擠不進 L2 的 MTU 這時候就產生了一個問題:當一個 IP 封包大小太大,以致於無法在 L2 以單一封包傳輸時,這樣該怎麼處理呢? ## 解法:Fragmentation 這時候,就要想辦法把 IP 封包裡面的資料分割,每一個分割後的資料各被包裝成一系列的封包,分別傳送。等這一系列封包到了目的地之後,再組裝起來。 > 注意是「到目的地之後」才會組裝起來。所以被分割的封包就是被分割了。 ## 例子 ![](https://i.imgur.com/YH5ieXH.jpg) 在這個例子中,假定 $H_5$ 的封包得經由 $R_1 \dots R_3$ 三個路由器轉送到 $H_8$。則分個的 ### H5 到 R1 `H5` 藉由 WiFi 將封包傳輸給 `R1`。 ### R1 到 R2 `R1` 與 `R2` 使用乙太網路連接。這時候乙太網路的單一封包仍然裝得下,因此就不分割。僅僅是把表頭從 802.11 換成乙太網路的。 ### R2 到 R3 這時候,因為 PPP 的單一封包最多只能傳輸 512 位元組,所以封包被分割成 3 份: ![](https://i.imgur.com/Z3CiyVk.jpg) ### R3 到 H8 三個被分割的小封包藉由乙太網路傳送給 `H8`。注意 ==封包的組裝是發生在接收方,路由器不會把已經分割的封包重新組裝==。因此,儘管 `R3` 到 `H8` 使用的是乙太網路,可以一個封包就能傳輸 1,400 位元組,`R3` 也不會因為這樣就把這 3 個小封包重新組裝起來。 ## 分割封包 ### 沒分割的封包 --- `MF` 與 `frag_off` 同時為 0 對於一個沒有分割的封包,它的 `MF` 與 `frag_off` 會同時是 `0`。這是因為 `frag_off` 為 `0`,表示它是一系列分割後的封包中,最前面的封包; 但是這時 `MF` 又是 `0`,表示這一系列的封包中,已經沒有更多封包了。因此這樣的封包 `MF` 與 `frag_off` 同時為 0。 對於這樣的封包,`MF` 與 `frag_off` 至少有一者不是 `0`。所以有三三種狀況。 ### 分割的第一部分 --- `MF` 非 0,`frag_off` 為 0 這表示這個封包是一系列分割後產生的封包的第一個,而且因為 `MF` 不是 `0`,所以表示它不是這一系列封包的最後一個。舉例來說,上圖的第一個封包就是這個例子。 ### 分割的中間 --- `MF` 非 0,`frag_off` 非 0 因為 `MF` 非零,表示這不是這一系列封包的最後一個。而這時這個封包的 `frag_off`,表示這是原先封包的資料中的起始位置。注意起始位置其實是 `(frag_off*8)`。 舉例來說,上圖第二個封包中,`frag_off` 是 `64`,表示這個封包當中的資料,是原先封包第 $64 \cdot 8 = 512$ 位元組開始的資料。而這也跟第一個封包所含的資料大小一樣,恰好就是 512 位元組。 又比如說,上面第三個封包的 `frag_off` 為 `128`,表示這個封包中的資料,是原封包中第 $128 \cdot 8 = 1,024$ 位元組開始算起的資料。這也而這個 1,024 恰好就是前 2 個封包資料量的總和。 ### 分割的最後一個封包 --- `MF` 為 0,`frag_off` 非 0 `DF` 為 `0` 表示這一系列沒有其他封包了。 ## 組合封包 --- 由 `(frag_off*8, tot_len)` 組合 那拿到封包之後,要怎麼把它們組合起來呢?對於一系列具有相同 `id` 的封包: 1. 每拿到一個封包,就可以知道它表示原先資料的「從 `(frag_off*8)` 開始的 `tot_len` 位元組」。 2. 直到收集到該 `id` 下, `MF` 為 `0` 的那個封包為止。 這眾多的 `(frag_off*8, tot_len)` 集合起來,就可以像拼拼圖那樣拼出完整的資料。而如果中間有少的話,那該怎麼辦?答案是直接丟棄,因為 IP 是不可靠傳輸。