Introduction (はじめに)
インターネットプロトコル (Internet Protocol, IP) [1] は、カテネット (catenet) [2] と呼ばれる相互接続されたネットワークシステムにおいて、ホスト間のデータグラムサービスを提供するために使用されます。ネットワークを接続するデバイスはゲートウェイ (Gateway) と呼ばれます。これらのゲートウェイは、制御目的でゲートウェイ間プロトコル (Gateway to Gateway Protocol, GGP) [3,4] を介して相互に通信します。時折、ゲートウェイまたは宛先ホストが送信元ホストと通信する必要があります。例えば、データグラム処理におけるエラーを報告する場合などです。このような目的のために、インターネット制御メッセージプロトコル (Internet Control Message Protocol, ICMP) が使用されます。ICMPは、上位層プロトコルであるかのようにIPの基本サポートを使用しますが、実際にはICMPはIPの不可欠な部分であり、すべてのIPモジュールによって実装されなければなりません (MUST)。
ICMPメッセージは、いくつかの状況で送信されます。例えば、データグラムが宛先に到達できない場合、ゲートウェイがデータグラムを転送するための十分なバッファ容量を持っていない場合、およびゲートウェイがホストにより短い経路でトラフィックを送信するよう指示できる場合などです。
インターネットプロトコルは、絶対的に信頼性の高いプロトコルとして設計されていません。これらの制御メッセージの目的は、IPを信頼性の高いものにすることではなく、通信環境における問題に関するフィードバックを提供することです。データグラムが配信される保証や、制御メッセージが返される保証はありません。一部のデータグラムは、その損失に関する報告なしに配信されない可能性があります。信頼性の高い通信が必要な場合、IPを使用する上位層プロトコルは独自の信頼性手順を実装しなければなりません (MUST)。
ICMPメッセージは通常、データグラム処理におけるエラーを報告します。メッセージに関するメッセージなどの無限再帰を避けるため、ICMPメッセージに関するICMPメッセージは送信されません。また、ICMPメッセージは、フラグメント化されたデータグラムのフラグメントゼロの処理におけるエラーについてのみ送信されます。(フラグメントゼロは、フラグメントオフセットがゼロに等しいものです)。
主要な設計原則
1. IP層の一部
アプリケーション層
↓
トランスポート層 (TCP/UDP)
↓
ネットワーク層 (IP + ICMP) ← ICMPはIPの不可欠な部分
↓
データリンク層
ICMPはIPを使用する上位層プロトコルではなく、IP層自体の不可欠な部分です。
2. エラー報告、信頼性ではない
ICMPが行うこと:
- ✅ データグラム処理における問題を報告する
- ✅ ネットワーク状態に関するフィードバックを提供する
- ✅ ネットワーク診断を支援する
ICMPが行わないこと:
- ❌ メッセージ配信を保証する
- ❌ IPを信頼性の高いものにする
- ❌ エンドツーエンドの信頼性を提供する
- ❌ フロー制御を実装する
3. 無限再帰なし
ルール: ICMPメッセージに関するICMPメッセージは決して送信されません。
エラーのあるデータグラム
↓
ICMPエラーメッセージが送信される ✅
↓
エラーのあるICMPメッセージ
↓
ICMPエラーメッセージは送信されない ❌ (無限ループを防ぐ)
例:
1. TCPパケット → IPデータグラム → エラー発生
→ ICMP Destination Unreachableが送信される ✅
2. ICMP Destination Unreachable → エラー発生
→ ICMPメッセージは送信されない ❌
これによりエラーメッセージのカスケードを防ぐ
4. フラグメントゼロルール
ICMPエラーメッセージは、フラグメント化されたデータグラムの最初のフラグメント (フラグメントオフセット = 0) についてのみ送信されます。
元のデータグラム (フラグメント化):
┌─────────────┬─────────────┬─────────────┐
│ Fragment 0 │ Fragment 1 │ Fragment 2 │
│ offset=0 │ offset=500 │ offset=1000 │
└─────────────┴─────────────┴─────────────┘
↓ ↓ ↓
エラー エラー エラー
↓ ↓ ↓
ICMP送信 ✅ ICMP なし ❌ ICMP なし ❌
理由:
- 同じ元のデータグラムに対して複数のエラーメッセージが生成されるのを避ける
- エラー報告を管理可能にする
- 最初のフラグメントのみが完全な上位層プロトコル情報を含む
ICMPメッセージの一般的なシナリオ
シナリオ 1: 宛先到達不能
ホストA → ルーター → [ネットワークBがダウン]
↓
ICMP Type 3: 宛先到達不能
↓
ホストAがエラー通知を受信
シナリオ 2: リダイレクト
ホストA → ゲートウェイ1 → ゲートウェイ2 → 宛先
↓
ICMP Type 5: リダイレクト
「この宛先にはゲートウェイ2を直接使用してください」
↓
ホストAがルーティングテーブルを更新
シナリオ 3: 時間超過
TTL=1のパケット
↓
ルーターがTTLを0にデクリメント
↓
ICMP Type 11: 時間超過
↓
送信元ホストが通知を受信
シナリオ 4: 送信元抑制 (輻輳制御)
ゲートウェイバッファが満杯
↓
ICMP Type 4: 送信元抑制
↓
送信元ホストが送信レートを低下させる
注: 送信元抑制 (Source Quench) は現在非推奨 (RFC 6633) です。これは非効率性と悪用の可能性があるためです。
他のプロトコルとの関係
ICMPとIP
IPデータグラム:
┌─────────────┬──────────────────┐
│ IPヘッダー │ IPペイロード │
│ Protocol=1 │ ICMPメッセージ │
└─────────────┴──────────────────┘
IPヘッダー:
- Protocolフィールド = 1 (ICMPを示す)
- Source Address = ICMP送信者
- Destination Address = ICMP受信者
ICMPとGGP
ゲートウェイ間プロトコル (Gateway to Gateway Protocol, GGP):
- ゲートウェイは相互の制御通信にGGPを使用する
- ICMPはゲートウェイからホストへの通信に使用される
- 異なる目的を持つ補完的なプロトコル
ICMPと上位層プロトコル
アプリケーション (例: pingユーティリティ)
↓ ICMPメッセージを構築
ICMPモジュール付きIP層
↓ IPデータグラムでICMPを送信
ネットワークインターフェース
エラー報告の例
例 1: ホスト到達不能
ステップ1: ホストAがホストB (10.0.2.100) にパケットを送信
┌─────────────────────────────┐
│ Src: 10.0.1.10 │
│ Dst: 10.0.2.100 │
│ Data: "Hello" │
└─────────────────────────────┘
ステップ2: ルーターR1がホストBが到達不能であると判断
ルーターR1のルーティングテーブル: 10.0.2.0/24への経路なし
ステップ3: ルーターR1がICMP Destination Unreachableを送信
┌─────────────────────────────┐
│ ICMP Type: 3 │
│ Code: 1 (Host Unreachable) │
│ Contains: IPヘッダー + 64 │
│ ビットの元の │
│ データグラム │
└─────────────────────────────┘
ステップ4: ホストAがICMPを受信し、アプリケーションにエラーを報告
例 2: フラグメンテーションが必要だがDFが設定されている
ステップ1: ホストAがDon't Fragment (DF) フラグ付きの大きなパケットを送信
┌─────────────────────────────┐
│ Src: 192.168.1.10 │
│ Dst: 203.0.113.50 │
│ Flags: DF=1 (Don't Fragment)│
│ Length: 1500 bytes │
└─────────────────────────────┘
ステップ2: ルーターR1がパケットを受信
- 出力インターフェースのMTU = 1000バイト
- パケットサイズ = 1500バイト
- DFフラグが設定されている → フラグメント化できない
ステップ3: ルーターR1がICMP Destination Unreachableを送信
┌─────────────────────────────┐
│ ICMP Type: 3 │
│ Code: 4 (Fragmentation │
│ needed but DF set) │
│ Next-Hop MTU: 1000 │
└─────────────────────────────┘
ステップ4: ホストAがICMPを受信
- Path MTU Discoveryを実装
- パケットサイズを1000バイトに縮小
- データを再送信
これは、Path MTU Discovery (PMTUD) [RFC 1191] の重要なメカニズムです。
処理ルール
ICMP送信者向け
-
ICMPを送信すべきかどうかを判断する:
- これはエラー状態か?
- これはICMPメッセージに関するものか? (はいの場合、送信しない)
- これはフラグメントゼロに関するものか? (フラグメントゼロでない場合、送信しない)
-
ICMPメッセージを構築する:
- 適切なTypeとCodeを設定
- チェックサムを計算
- 元のIPヘッダー + 64ビットの元のデータを含める
-
IP経由で送信する:
- IPプロトコル1 (ICMP) を使用
- 適切なIPヘッダーフィールドを設定
ICMP受信者向け
-
メッセージを検証する:
- チェックサムを確認
- TypeとCodeの値をチェック
-
Typeに応じて処理する:
- エラーメッセージ: 上位層プロトコルに報告
- クエリメッセージ: 応答を生成
- 情報メッセージ: 適切に処理
-
適切なハンドラーに渡す:
- 元のデータグラム情報に基づいて多重化
- 影響を受けるプロトコルまたはアプリケーションに通知
歴史的背景: ICMPは、元のインターネットプロトコルスイートの一部として、RFC 792 (1981年9月) で定義されました。一部のメッセージタイプは非推奨となり、新しいものが追加されましたが、IPネットワーキングの基本的なコンポーネントであり続けています。