2.3. IPヘッダ

IP プロトコルの概要を示した前章でお分かりかと思うが、 IP パケットはヘッダに幾つかの部位を備えている。ヘッダ全体は性質毎に細分化され、オーバーヘッドを可能な限り抑えるという命題のために、それぞれの部位は機能できる必要最小限にまでサイズが切り詰められている。 IP ヘッダの諸元は、図「IPヘッダ」 にある。

Note

ヘッダの部位に関する説明は、ほんのさわりに過ぎず、この先もその基本骨子にしか触れないという点を、ご承知おきいただきたい。これから各ヘッダについて述べる中で、当該のヘッダのより細かい説明を提供してくれる適切な RFC は紹介していく。補足の補足として書いておくが、 RFC は、Request For Comments [訳者註:「インターネット規約」と訳されることが多い。直訳すると「回答伺い」あるいは「回答募集中」] の意味だが、今日のインターネットコミュニティにおいては、名称とは全く異なる意味合いを持つようになった。研究者達が RFC を書き始めた当初とは違って、今の RFC はインターネットそのものを規定したり標準化するものとなっている。遡れば RFC はその名の通りコメントを要望する文書であり、自分の意見に対して他の研究者達に見解を乞う手段だったのである。

IP プロトコルについての大部分は RFC 791 に書かれている。ただし、 この RFC は RFC 1349 - Type of Service in the Internet Protocol Suite によって一部改訂 (update) され、その RFC 1349 はまた RFC 2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers によって廃版 (obsolete) とされ、その RFC 2474 は RFC 3168 - The Addition of Explicit Congestion Notification (ECN) to IP および RFC 3260 - New Terminology and Clarifications for Diffserv により一部改訂された。

Tip

ご覧のように、こうした標準化文書は時として、追いかるのにかなり骨が折れる。関係する RFC 群を見つけるひとつの手は、 RFC-editor.org の備える検索機能を活用することだ。 IP の場合には、 RFC 791 が大元で、その他の RFC はそれを改訂したり変更を加えているに過ぎない。そうしたことについては、以降で扱うヘッダの中で、新しい RFC によって変更されたものが出てきた時に、その都度詳しく述べる。

ひとつ憶えておいてほしいのは、 RFC は廃版にされる (もう一切使われなくなる) ことがあるという点だ。そうなるのは大抵、その RFC が大幅に変わり、丸ごと置き換えたほうが得策だと判断された時。別の理由で廃版にされる場合もある。廃版となった RFC には、それに取って代わった新しい RFC を指し示す文言が書き添えられる。

バージョン (Version) - ビット 0-3。これは IP プロトコルのバージョンナンバーを 2進数で表している。 IPv4 は 0100、 IPv6 は 0110 で表される。このフィールドがフィルタリングに使われることはほとんど無い。 RFC 791 に書かれているのは IPv4 のほうだ。

IHL (インターネットヘッダ長 Internet Header Length) - ビット 4-7。このフィールドは IPヘッダ の長さを 32ビット毎のワード数で示したもの。お分かりの通り、 IP ヘッダの図はこれに倣って 1行当たり 32ビットとなるようヘッダを区切ってある。 Options フィールドは自由長なので、この IHL フィールド無しにはヘッダ全体の長さを特定することができない。このヘッダの長さは最小 5 ワードだ。

サービスタイプ (Type of Service), DSCP, ECN - ビット 8-15。ここは IPヘッダ の中でも最も難解な部分。というのも、3度にも渡って変更されてきたからだ。いずれの改訂でも基本的な用途こそ変わらなかったものの、実装方法が度々変更になった。まず最初、このフィールドはサービスタイプ (Type of Service) フィールドと呼ばれていた。このフィールドのうちビット 0 からビット 2 までは優先区分 (Precedence) フィールドと呼ばれた。ビット 3 は遅延の中/低 (Normal/Low delay)、ビット 4 はスループットの中/高 (Normal/High throughput)、ビット 5 は信頼性の中/高 (Normal/High reliability) であり、ビット 6 から 7 は将来の用途のための未使用域とされていた。このヘッダは、現在でも旧式なハードウェアを運用している場所ではかなり使われており、そして相変わらずインターネットに弊害をもたらし続けている。特に、ビット 6 からビット 7 がゼロにセットされていなくてはならないという規定が問題だ。 ECN の改訂 (RFC) でこれらのビットが使われるようになり、ゼロ以外の値にセットするケースが出てきたからだ。ところが、旧型のファイヤーウォールやルータの中には、これらのビットが 1 になっていないかのチェック機構を内蔵しているものがあり、それに引っ掛かったパケットを破棄してしまうのである。そうした挙動は今日の RFC に完全に抵触しているわけだが、我々にできることはといえば悪態をつくことくらいのもので、為す術がないのが実情だ。

2度目のでんぐり返しである RFC 2474 によって、このフィールドは DS フィールドと呼ばれることになった。 DSDifferentiated Services を表す。この規格によれば、ビット 8-13 は Differentiated Services Code Point (DSCP) となり、残りの 2 ビット (14-15) は引き続き未使用だった。 DSCP フィールドの利用法は ToS フィールドの時とさほど変わらない。つまり、区別ができるようルータを設定しておけば、このフィールドを目印にしてパケット毎に処遇を切り替えられるというものだ。この改訂で大きく変わったのは、 RFC 2474 準拠であるためには、デバイスは未使用のビットを無視しなければならなくなったという点。これによって、デバイスを作る側がこの RFC に従う限りは、前の規格で格闘を余儀なくされていた難解な設定とはおさらばできるようになった。

ToS フィールドの 3度目であり実質的に最後の変更となったのが FRC 3168。それによって、以前は未使用だったふたつのビットが ECN (Explicit Congestion Notification = 明示的輻輳通知) に使用されるようになった。 ECN は、ルータが輻輳を起こした際、実際にルータがパケットを取りこぼし始める前に、末端のノードに輻輳を知らせる役目を持つ。このおかげで、末端のノードは、ルータが実際にデータを取りこぼす前にデータの送信速度を落とすことができる。この規格ができるまでは、ルータにとっては、実際にデータを破棄するしか過負荷を知らせる術がなく、エンドノードはそれを見て速度を一旦がくんと落とし (slow restart)、破棄されたパケットをおもむろに送り直し、具合をみながら元のスピードまで上げていくという手段をとっていた。ふたつのビットは、 ECT (ECNCapable Transport) コードポイントと CE (Congestion Experienced) コードポイントと呼ばれる。

一連の堂々巡りの最後の変更は RFC 3260 で、 DiffServ 機構を使用する上での新しい用語の規定と、規格の明確化が行われた。この改訂は技術用語の類が主で、更新や変更はそれほど沢山盛り込まれていない。 RFC は開発者達の議論を経て要点を整理するという役割も持っているのだ。

全長 (Total Length) - ビット 16-31。このフィールドは、ヘッダをはじめ一切合切を含めたパケット全体のサイズをオクテット単位で示す。パケットひとつのサイズの上限は 65535 オクテット (=バイト)。到着した時点でパケットがフラグメントしているかどうかにかかわらず、最小サイズは 576 バイトだ [訳者註: フラグメントしている時の値は再構成後の合計サイズではなくフラグメント個々のサイズ]。 RFC 791 によれば、この制限を上回るサイズのパケットを送るのは、そのホストが必ず受け取れるという保証のある場合だけにすべきとされている (recommended)。ただし、今日ではほとんどのネットワークがパケットサイズを 1500 バイトにして運用している。ほぼ全てのイーサネット接続がそうだし、ほとんどのインターネットコネクションもそこに含まれる。

識別子 (Identification) - ビット 32-46。このフィールドはパケットフラグメントの再構成を手助けするためにある。

フラグ (Flags) - ビット 47-49。このフィールドはフラグメンテーションに関するその他のフラグを含んでいる。最初のビットは予約済みだが、まだ使用されておらず、ゼロになっていなければならない。 第2 ビットは、パケットをさらにフラグメンテーションしてもよい場合は 0 に、それ以上のフラグメンテーションを許さない場合には 1 にセットする。 3番目 (つまり最後) のビットは、これが最終フラグメントであれば 0 、同一パケットに属するフラグメントが他にもあるなら 1 にセットする。

フラグメントオフセット (Fragment Offset) - ビット 50-63。フラグメントオフセットは、そのパケットが元のデータグラムのどの位置にあたるのかを表す。フラグメントは 64 ビットで計算される。最初のフラグメントのオフセットは 0 である。

Time to live - ビット 64-72。 TTL フィールドが示すのは、そのパケットがどれだけ生きられるか。もう少し具体的に言うと、インターネットの中を何回 "ホップ" できるかだ。パケットに触れた各プロセスは TTL を必ず 1 ずつ奪い取っていき、もし TTL がゼロになったらそのパケットはかけらも残さず破棄されなくてはならない。この仕組みは、パケットがホスト間で制御不能のループを引き起こさないようにするための、一種の安全装置である。破棄の際には、ホストは送信者へ ICMPDestination Unreachable メッセージを送るべきとされている (should)。

プロトコル (Protocol) - ビット 73-80。このフィールドには上位レイヤーのプロトコルが記載される。一部を挙げれば TCP, UDP, ICMP などである。それらを示すナンバーは Internet Assigned Numbers Authority (IANA) で規定されている。ナンバーの全てはホームページ Internet Assigned Numbers Authority で調べることができる。

ヘッダチェックサム (Header checksum) - ビット 81-96。そのパケットのヘッダのチェックサムだ。ヘッダに変更を加えたホストはこのフィールドを必ず再構成しなければならない。実際のところ、パケットの通り道となったホストは TTL フィールドをはじめパケットのどこかをほぼ必ずいじるので、再計算はほとんどのホストで行われると思って間違いない。

送信元アドレス (Source address) - ビット 97-128。送信元アドレスを示すフィールド。我々が普段目にする時にはたいてい、2進数から 10進数に変換して間をドットでつないだ 4 オクテットの値として表される。例えば 127.0.0.1 といった具合だ。このフィールドはパケットがどこから来たのかを受信者に伝える。

宛先アドレス (Destination address) - ビット 129-160。 Destination address フィールドは宛先のアドレスを格納しているが、あらビックリ、フォーマットは送信元アドレスと同じだ。

オプション (Options) - ビット 161-192<>478。名前の響きとは裏腹に、オプションフィールドの存在は任意ではない。正直なところ、このフィールドは IP ヘッダの中でもかなり複雑な部類。オプションフィールドは、インターネットタイムスタンプ、SACK、レコードルートオプション (record route options) などといった様々なオプションセッティングを格納するヘッダだ。これらの値を持つかどうかは全て任意なので、オプションフィールドの長さも可変であり、結果として IP ヘッダ自体の長さも変化することになる。ただし IP ヘッダでは常に 32 ビットを 1 ワードとして扱うため、ヘッダは必ず 32 の倍数となる偶数で終わらなければならない。このフィールドは 0 個以上のオプションを持つことができる。

オプション フィールドは 8 ビット長の短いフィールドから始まり、その部分はパケットでどういったオプションが用いられているかを知らせる。付録 TCPオプションTCPオプション という表に全オプションを挙げておいた。各オプションの詳細を知りたければ、該当する RFC を読んでいただきたい。 IPオプション リストの最新情報は Internet Assigned Numbers Authority で調べるといいだろう。

パディング (Padding) - ビット可変。ここは、ヘッダが 32 ビット境界で終わるように調整するための詰め物。このフィールドは頭から終わりまでゼロばかりが並んでいなければならない。