ネットワークプロトコルスタックの階層と封入
パケットキャプチャの1バイトずつが何の層のヘッダか即座に読めるようになる。各層が付ける封筒の構造とPDUの名前、実バイト列の並びを原理から押さえます。
- 1.送信時は上位層のデータに各層がヘッダを前置していく。L4でセグメント、L3でパケット、L2でフレームとPDUの呼び名が変わる。
- 2.実バイト列は外側から Ethernetヘッダ14B → IPv4ヘッダ20B → TCPヘッダ20B → アプリデータ の順に並び、末尾にFCS 4Bが付く。
- 3.各ヘッダの「次は何の層か」を示すフィールド(EtherType・Protocol・宛先ポート)を辿ると、受信側は復号順を一意に決められる。
カプセル化は「逆順に剥がせる」ことが本質
カプセル化(encapsulation)とは、ある層のPDU(Protocol Data Unit)全体を、すぐ下の層が自分のヘッダで包み、下層から見れば中身を解釈しない不透明なデータ(ペイロード)として扱う操作です。送信側はアプリのデータに L4 → L3 → L2 の順でヘッダを前置していき、受信側はワイヤから届いたバイト列を L2 → L3 → L4 の順で1枚ずつ剥がします。この対称性が成立する条件は、各層のヘッダが 「自分のペイロードがどの上位プロトコルか」を明示している ことです。これが無ければ受信側は次にどのヘッダ解析器へ渡すかを決められません。層の全体像は /network/osi/ と /network/tcp-ip/ を前提とします。
同じデータでも層によって呼称が変わります。L4(TCP)では セグメント、L4(UDP)では データグラム、L3 では パケット、L2 では フレーム、L1 では ビット(シンボル)。会話で「このパケットが」と言うとき、厳密にはL3視点であることを意識すると層の切り分けがぶれません。
層を下るごとに付く封筒
HTTPリクエストを例に、上から下へPDUがどう成長するかを追います。
| 層 | 付与するヘッダ | 結果のPDU | 識別キー(誰宛か) |
|---|---|---|---|
| L7 アプリ | なし(データ本体) | メッセージ / データ | URL・リソース |
| L4 トランスポート | TCP/UDPヘッダ | セグメント / データグラム | ポート番号 |
| L3 ネットワーク | IPヘッダ | パケット | IPアドレス |
| L2 データリンク | Ethernetヘッダ + FCS | フレーム | MACアドレス |
| L1 物理 | なし(符号化のみ) | ビット列 | — |
ここで重要なのは、各層が付けるのは「ヘッダ(前置)」が基本で、L2 だけはフレーム末尾にも FCS(4バイトのCRC-32) という後置(トレーラ)を付ける点です。つまり最終的なワイヤ上のバイト列は、ヘッダが外側から内側へ入れ子になり、末尾にL2のトレーラが付く構造になります。
[Ethernetヘッダ 14B][IPv4ヘッダ 20B][TCPヘッダ 20B][アプリデータ][FCS 4B]
└── L2 ──┘└──────── L2 ペイロード ────────┘└ L2 ──┘
└── L3 ─┘└──── L3 ペイロード ────┘
└ L4 ┘└─ L4 ペイロード ┘
L2 から見れば、IPヘッダ以降すべてが「ただのペイロード」です。L2 は中身がIPかARPかを EtherType で区別するだけで、IPの構造そのものは一切解釈しません。これが関心の分離の実体です。
実バイト列:3つのヘッダを並べて読む
代表的な IPv4 + TCP の最小構成(オプション無し)を、先頭からのバイトオフセットで追います。ここを正確に押さえると、パケットキャプチャの16進ダンプが読めます。手を動かす手順は /network/packet-capture/ を参照してください。
Ethernet II ヘッダ(先頭14バイト)
offset 0 : 宛先MAC 6B (次ホップのMAC)
offset 6 : 送信元MAC 6B
offset 12 : EtherType 2B (0x0800=IPv4, 0x0806=ARP, 0x86DD=IPv6)
EtherType が 0x0800 なら、受信側はオフセット14から先をIPv4解析器に渡します。MACは1ホップごとに書き換わる一方、IP以降は変わりません。この対比は /network/arp/ のIP↔MAC解決と合わせると腑に落ちます。
IPv4 ヘッダ(オフセット14から20バイト)
| フィールド | サイズ | 役割 |
|---|---|---|
| Version + IHL | 1B | 上位4bitが版(=4)、下位4bitがヘッダ長(4バイト単位、最小値5=20B) |
| DSCP + ECN | 1B | QoS用の優先度とふくそう通知 |
| Total Length | 2B | ヘッダ+ペイロードの総バイト数 |
| Identification / Flags / Offset | 4B | フラグメント再構築用の識別子と位置 |
| TTL | 1B | 残りホップ数。0で破棄 |
| Protocol | 1B | 上位プロトコル(6=TCP, 17=UDP, 1=ICMP) |
| Header Checksum | 2B | ヘッダのみの誤り検出 |
| 送信元IP / 宛先IP | 8B | L3の住所(各4B) |
Protocol フィールドが、L3 が次にどのL4解析器へ渡すかを決めます。6 ならTCP、17 ならUDPです。IHL(Internet Header Length)が4バイト単位なので、オプション無しの最小ヘッダは IHL=5、すなわち 20バイト。ここを足し込んでオフセット34からがTCPヘッダになります。
TCP ヘッダ(オフセット34から20バイト)
offset 34 : 送信元ポート 2B
offset 36 : 宛先ポート 2B (この値でL7アプリを特定)
offset 38 : シーケンス番号 4B
offset 42 : ACK番号 4B
offset 46 : Data Offset+予約+フラグ 2B (上位4bitがヘッダ長/4バイト単位)
offset 48 : ウィンドウサイズ 2B
offset 50 : チェックサム 2B
offset 52 : 緊急ポインタ 2B
offset 54 : (オプション無しならここからアプリデータ)
宛先ポート がL4からL7への分岐キーです。443 ならTLS/HTTPS、53 ならDNSへ渡す、という対応はポートとソケットの仕組み(/network/socket-port/)が前提になります。Data Offset が 5(=20バイト)ならオプション無しで、オフセット54からアプリ層のデータが始まります。
受信側の復号は決定的です。EtherType=0x0800 → IPv4、その Protocol=6 → TCP、その 宛先ポート=443 → TLS。各ヘッダが必ず「次は何か」を1フィールドで持つため、スタックは分岐表(ディスパッチテーブル)を引くだけで上位へ受け渡せます。この連鎖こそカプセル化の設計上の肝です。
オーバーヘッドとMTUの会計
カプセル化はヘッダの分だけ実効ペイロードを削ります。Ethernet の MTU 1500バイトを基準に、IPv4(20) + TCP(20) を引くと、TCPが1セグメントで運べるアプリデータは最大 1460バイト。これが標準的な MSS(Maximum Segment Size) です。
| 項目 | バイト数 | 備考 |
|---|---|---|
| MTU(Ethernetペイロード上限) | 1500 | FCSやEthernetヘッダ14Bは含まない |
| − IPv4ヘッダ | 20 | オプション無し(IHL=5) |
| − TCPヘッダ | 20 | オプション無し(Data Offset=5) |
| = MSS(実効データ) | 1460 | IPv6なら基本ヘッダ40Bで1440 |
VPNやトンネルではここに外側のヘッダが追加で被さるため、内側のMSSをさらに下げないと分割や無言の詰まりが起きます。MTU/MSSの会計と落とし穴は /network/mtu/ で深掘りできます。
小さいデータほどヘッダ比率が相対的に大きくなります。1バイトのデータでも Ethernet14 + IPv4 20 + TCP20 + FCS4 = 58バイトの封筒が付き、効率は約1.7%。TCPの確認応答(ACKのみ)パケットがほぼヘッダだけで構成されるのはこのためで、L7で小さなメッセージを大量送信する設計はヘッダオーバーヘッドで帯域を浪費しやすい点に注意します。
つまずきポイント
- ヘッダは前置、トレーラはL2だけ:IPやTCPは前にヘッダを付けるだけで末尾には何も足しません。誤り検出の後置(FCS)はL2フレームに固有です。
- 「パケット」を全層で使う誤用:厳密にはL3のPDUがパケット。L4はセグメント/データグラム、L2はフレーム。トラブル報告で層がぶれる原因になります。
- ヘッダ長が固定だと思い込む:IPv4の
IHLもTCPのData Offsetも可変です。オプション付きならオフセット計算が20バイト超になり、固定で読むとペイロード先頭を取り違えます。 - 次層識別フィールドの見落とし:
EtherType・Protocol・宛先ポートの連鎖を辿らずにオフセットだけで読むと、IPv6やVLANタグ(0x8100)が挟まった瞬間に解析がずれます。
ネットワーク Article
ネットワークプロトコルスタックの階層と封入を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
カプセル化
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 5
導入後に効く点
実バイト列は外側から Ethernetヘッダ14B → IPv4ヘッダ20B → TCPヘッダ20B → アプリデータ の順に並び、末尾にFCS 4Bが付く。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 5
判断チェックリスト
- 自社の用途が「カプセル化 / プロトコルスタック」に近いか確認する。
- 強みである「送信時は上位層のデータに各層がヘッダを前置していく。L4でセグメント、L3でパケット、L2でフレームとPDUの呼び名が変わる。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。