ICMP Destination Unreachableとは
ICMP Destination Unreachable(Type 3)は、送信されたIPパケットを宛先まで届けられなかったことを送信元に通知するエラーメッセージです。RFC 792で定義されています。
「届けられない理由」は経路上のどの段階で問題が発生したかによって様々であり、その違いはCodeフィールドで表現されます。単に「届かなかった」ことだけでなく、ネットワークが存在しないのか、宛先ホストが応答しないのか、あるいは宛先ホストのポートが閉じているのかといった、原因の切り分けに役立つ情報が含まれています。
パケットフォーマット
Destination Unreachableの「Rest of Header」は多くのCodeで未使用(0埋め)ですが、Code 4(Fragmentation Needed and DF Set)ではNext-Hop MTUフィールドとして使用されます。Dataには、破棄された元のIPパケットの一部が格納されます。
| フィールド名 | サイズ | 説明 |
|---|---|---|
| Type | 1 バイト | 3固定。 |
| Code | 1 バイト | 届けられなかった理由を示す値。詳細は下表を参照。 |
| Checksum | 2 バイト | ICMPメッセージ全体を対象とした誤り検出用の値。 |
| Unused / Next-Hop MTU | 4 バイト | Code 4以外では未使用(0埋め)。Code 4の場合、上位2バイトは未使用、下位2バイトに次のホップへ転送可能な最大MTU値が入る(Path MTU Discoveryで使用)。 |
| Data | 可変長 | 破棄された元のIPパケットの一部(一般的にはIPヘッダー+先頭8バイト)。 |
Codeの一覧
代表的なCode値と、それぞれがどこで発生するかをまとめます。
| Code | 名称 | 発生元の例 |
|---|---|---|
| 0 | Network Unreachable | 宛先ネットワークへの経路情報を持たないルータ |
| 1 | Host Unreachable | 宛先ネットワーク内で、その特定のホストへの経路が見つからないルータ(ARP解決失敗時など) |
| 2 | Protocol Unreachable | 宛先ホストが、指定された上位プロトコル(IPヘッダーのProtocolフィールド)に対応していない場合 |
| 3 | Port Unreachable | 宛先ホストの指定UDPポートで待ち受けているプロセスが存在しない場合 |
| 4 | Fragmentation Needed and DF Set | パケットサイズがリンクのMTUを超えているが、IPヘッダーのDFビットが立っているため分割できないルータ |
| 5 | Source Route Failed | IPオプションで指定されたソースルートに従って転送できないルータ |
| 13 | Communication Administratively Prohibited | ファイアウォールやACLによって明示的に遮断された場合 |
発生パターンの例
R1(192.168.0.1)が存在しないホストR9(192.168.9.9)宛にパケットを送信し、R1のデフォルトゲートウェイであるルータGWがそのネットワークへの経路を持たない場合の例です。
sequenceDiagram
participant R1 as R1
192.168.0.1
participant GW as GW
デフォルトゲートウェイ
R1->>GW: 宛先: 192.168.9.9 宛のパケット
Note over GW: 192.168.9.0/24への
経路情報が存在しない
GW-->>R1: ICMP Destination Unreachable
Type: 3, Code: 0 (Network Unreachable)
送信元: GWのIPアドレス
このように、Destination Unreachableは宛先ホスト自身ではなく、転送を断念した経路上のルータやホストが送信元となって返されます。応答の送信元アドレスを確認することで、経路上のどこで問題が発生したかを切り分けられます。
Path MTU Discoveryとの関係
Code 4(Fragmentation Needed and DF Set)は、IPv4のフラグメンテーションに関連する特別なCodeです。DFビット(Don’t Fragment)が立ったパケットが、転送先リンクのMTUを超えているためにルータで分割できない場合、ルータはパケットを破棄しこのメッセージを送信元に返します。
このとき返されるNext-Hop MTUフィールドの値を送信元が参照し、それ以降はそのMTU以下のサイズでパケットを送信するよう調整する仕組みをPath MTU Discovery(PMTUD)と呼びます。
全Code値の一覧はIANAで管理されています。
実機での検証
Linux1(192.168.1.1/24)— R1 — R2 — R3 — Linux2(192.168.2.2/24)を下図のとおり直列に接続し、各ルータに隣のルータ方向へのスタティックルートを設定しています。R2は192.168.1.0/24・192.168.2.0/24への経路のみを持ち、デフォルトルートを持たないため、それ以外の宛先(例: 172.16.1.1)へのパケットを受け取ると転送先が分からずICMP Destination Unreachableを返します。この環境でHost UnreachableとPort Unreachableの2パターンを実際に発生させ、パケットキャプチャで確認しました。
Host Unreachableの検証
R2のルーティングテーブル
R2#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2, m - OMP
n - NAT, Ni - NAT inside, No - NAT outside, Nd - NAT DIA
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
H - NHRP, G - NHRP registered, g - NHRP registration summary
o - ODR, P - periodic downloaded static route, l - LISP
a - application route
+ - replicated route, % - next hop override, p - overrides from PfR
& - replicated local route overrides by connected
Gateway of last resort is not set
10.0.0.0/8 is variably subnetted, 4 subnets, 2 masks
C 10.1.2.0/24 is directly connected, GigabitEthernet1
L 10.1.2.2/32 is directly connected, GigabitEthernet1
C 10.2.3.0/24 is directly connected, GigabitEthernet2
L 10.2.3.2/32 is directly connected, GigabitEthernet2
S 192.168.1.0/24 [1/0] via 10.1.2.1, GigabitEthernet1
S 192.168.2.0/24 [1/0] via 10.2.3.3, GigabitEthernet2「Gateway of last resort is not set」の通りR2にはデフォルトルートがなく、経路表には直接接続の10.1.2.0/24・10.2.3.0/24と、スタティックルートの192.168.1.0/24・192.168.2.0/24しか存在しません。172.16.1.1宛のパケットはこのいずれの経路にも一致しないため、R2はルーティング不能と判断してICMP Destination Unreachableを返します。
pingの実行結果
$ ping -c 5 172.16.1.1
PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data.
From 10.1.2.2 icmp_seq=1 Destination Host Unreachable
From 10.1.2.2 icmp_seq=2 Destination Host Unreachable
From 10.1.2.2 icmp_seq=3 Destination Host Unreachable
From 10.1.2.2 icmp_seq=4 Destination Host Unreachable
From 10.1.2.2 icmp_seq=5 Destination Host Unreachable
--- 172.16.1.1 ping statistics ---
5 packets transmitted, 0 received, +5 errors, 100% packet loss, time 4008ms5回とも、宛先の172.16.1.1自身からではなく、経路上のR2(10.1.2.2)から「Destination Host Unreachable」の応答が返っています。
パケットキャプチャ
1回目(Sequence Number 1)のキャプチャです。
Ethernet II, Src: 52:54:00:51:26:a0, Dst: 52:54:00:01:c6:d0
Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 172.16.1.1
Time to Live: 64
Flags: DF (Don't Fragment)
Protocol: ICMP (1)
Total Length: 84
Internet Control Message Protocol
Type: 8 (Echo (ping) request)
Code: 0
Checksum: 0xb1d0
Identifier: 0x053f (1343)
Sequence Number: 0x0001 (1)Ethernet II, Src: 52:54:00:01:c6:d0, Dst: 52:54:00:51:26:a0
Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.1.2.2, Dst: 192.168.1.1
Time to Live: 254
Protocol: ICMP (1)
Total Length: 56
Internet Control Message Protocol
Type: 3 (Destination Unreachable)
Code: 1 (Host Unreachable)
Checksum: 0x3dee
Unused: 0x00000000
[元のデータグラム]
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 172.16.1.1, Time to Live: 62
Internet Control Message Protocol, Type: 8, Code: 0, Identifier: 0x053f (1343), Sequence Number: 0x0001 (1)このキャプチャはLinux1・R1間のリンクで取得しているため、Ethernetヘッダーの宛先/送信元MACアドレスは、実際にはLinux1とR1(Gi2)のものです。R2はEcho RequestをLinux1宛にルーティングできないため、自身(10.1.2.2)を送信元としたICMP Destination Unreachableを、R1経由でLinux1へ返送しています。
icmp_host-unreachable.pcap をダウンロード
Port Unreachableの検証
Linux2(192.168.2.2)の5000番ポートでは、UDPで待ち受けているプロセスが存在しません。Linux1からこのポート宛にUDPデータを送信し、Port Unreachableの動作をパケットキャプチャで確認しました。
ncの実行結果
cisco@linux1:~$ echo "test" | nc -u -w1 192.168.2.2 5000
cisco@linux1:~$nc側には特にエラーは表示されませんが、-w1のタイムアウトまで応答を待って終了しています(UDPには応答の有無をnc自身が判定する仕組みがないため)。実際には後述のとおりICMP Port Unreachableが返っています。
パケットキャプチャ
Ethernet II, Src: 52:54:00:51:26:a0, Dst: 52:54:00:01:c6:d0
Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.2.2
Time to Live: 64
Flags: DF (Don't Fragment)
Protocol: UDP (17)
Total Length: 33
User Datagram Protocol, Src Port: 60717, Dst Port: 5000
Length: 13 (データ5バイト: "test\n")Ethernet II, Src: 52:54:00:01:c6:d0, Dst: 52:54:00:51:26:a0
Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.2.2, Dst: 192.168.1.1
Time to Live: 61
Protocol: ICMP (1)
Total Length: 61
Internet Control Message Protocol
Type: 3 (Destination Unreachable)
Code: 3 (Port Unreachable)
Checksum: 0x816f
Unused: 0x00000000
[元のデータグラム]
Internet Protocol Version 4, Src: 192.168.1.1, Dst: 192.168.2.2, Time to Live: 61
User Datagram Protocol, Src Port: 60717, Dst Port: 5000, Length: 13 (データ5バイト: "test\n")このキャプチャもLinux1・R1間のリンクで取得しているため、Ethernetヘッダーの宛先/送信元MACアドレスはLinux1とR1(Gi2)のものです。IPヘッダーのTTLに注目すると、往路のUDPデータグラム・復路のICMPメッセージともに61になっています。Linux2からLinux1までは3ホップ(R3・R2・R1)あるため、Linux側の既定TTL(64)から3減算された値と一致しており、このICMPメッセージが宛先ホストLinux2自身から発せられたものであることが確認できます。
また、元のデータグラムの引用部分にはIPヘッダー+UDPヘッダーに加えてペイロード(“test\n”)までそのまま含まれており、パケットフォーマットの表で「一般的にはIPヘッダー+先頭8バイト」と説明した最小構成よりも多くのデータが含まれています。RFC 792が定めるのはあくまで最小要件であり、パケット全体が収まる場合はより多くの内容を引用する実装も一般的です。
icmp-port_unreachable.pcap をダウンロード検証Config
R1 config(r1_icmp-unreachable.cfg) をダウンロード
R2 config(r2_icmp-unreachable.cfg) をダウンロード
R3 config(r3_icmp-unreachable.cfg) をダウンロード
検証環境およびshow結果
R1 show出力(r1_icmp-unreachable_show.txt) をダウンロード
R2 show出力(r2_icmp-unreachable_show.txt) をダウンロード
R3 show出力(r3_icmp-unreachable_show.txt) をダウンロード
参考
| RFC | タイトル | 概要 |
|---|---|---|
| RFC 792 | Internet Control Message Protocol | ICMPの原典。Destination Unreachableの基本フォーマットとCode 0〜5を定義。 |
| RFC 1191 | Path MTU Discovery | Code 4とNext-Hop MTUフィールドを用いたPMTUDの仕組みを定義。 |