要約

  • オフセット値32は、元のデータグラムの256バイト目を示すのであって、32バイト目を示すのではない。
  • MF=1のフラグメントはデータ長が8の倍数でなければならない。最後のフラグメントは例外である。

バイト番号を直接入れるフィールドではない

RFC 791は、Fragment Offsetを13ビット、8オクテット単位のフィールドとして定義する。受信側は値を8倍して、元のデータグラムにおけるデータ開始位置を得る。したがって32は256バイトに対応する。

この設計はヘッダーのビット配分から生まれた。13ビットは8192個の位置を表し、これを8オクテット単位にすると65,536オクテットを覆う。これは16ビットのTotal Lengthが扱う範囲に対応する。送信されない下位3ビットは、復号時にはゼロとして戻る。

省略したビットが境界を決める

次のフラグメントの開始位置も、8オクテット単位で表せなければならない。そのためMFが1なら、現在のフラグメントのデータ長は8の倍数である必要がある。対象はIPv4ヘッダーを含む全長ではなく、データ部分である。

最後のフラグメントには、後続の開始位置を用意する必要がない。したがってデータ長は8の倍数でなくてもよい。「すべてのフラグメントが8の倍数」という説明は正確ではない。

位置と終了を別々に読む

Fragment Offsetは開始位置を示し、MFは後続データの有無を示す。未分割データグラムはオフセット0、MF=0である。先頭フラグメントもオフセット0になり得るが、MF=1である。最後のフラグメントは非ゼロのオフセットとMF=0を持ち得る。

再構成では、オフセットを8倍した開始位置とデータ長から元のバイト区間を作る。RFC 815は、受信済み区間と不足しているホールを使ってこの処理を説明する。フラグメントはホールを埋めたり、片側を削ったり、二つに分けたりする。MF=0は末尾を知らせるが、それだけで再構成完了とはならない。

再分割でも座標は変わらない

フラグメントがさらに分割されても、オフセットは元の未分割データグラムを基準にする。局所的な番号付けは始まらない。この共通座標が、複数の機器による連続した分割を可能にする。

小さなフィールドで済ませた代償は、送信側の境界処理と受信側のバイト位置への復元に移されたのである。

出典