メインコンテンツへスキップ
  1. ネットワーク 記事一覧/
  2. IPv4記事一覧/

ICMP Destination Unreachable

目次

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パケットの一部が格納されます。

フィールド名サイズ説明
Type1 バイト3固定。
Code1 バイト届けられなかった理由を示す値。詳細は下表を参照。
Checksum2 バイトICMPメッセージ全体を対象とした誤り検出用の値。
Unused / Next-Hop MTU4 バイトCode 4以外では未使用(0埋め)。Code 4の場合、上位2バイトは未使用、下位2バイトに次のホップへ転送可能な最大MTU値が入る(Path MTU Discoveryで使用)。
Data可変長破棄された元のIPパケットの一部(一般的にはIPヘッダー+先頭8バイト)。

Codeの一覧

代表的なCode値と、それぞれがどこで発生するかをまとめます。

Code名称発生元の例
0Network Unreachable宛先ネットワークへの経路情報を持たないルータ
1Host Unreachable宛先ネットワーク内で、その特定のホストへの経路が見つからないルータ(ARP解決失敗時など)
2Protocol Unreachable宛先ホストが、指定された上位プロトコル(IPヘッダーのProtocolフィールド)に対応していない場合
3Port Unreachable宛先ホストの指定UDPポートで待ち受けているプロセスが存在しない場合
4Fragmentation Needed and DF SetパケットサイズがリンクのMTUを超えているが、IPヘッダーのDFビットが立っているため分割できないルータ
5Source Route FailedIPオプションで指定されたソースルートに従って転送できないルータ
13Communication Administratively ProhibitedファイアウォールやACLによって明示的に遮断された場合
Code 3(Port Unreachable)はUDPに特有の挙動です。TCPの場合、閉じたポートへの接続要求(SYN)に対しては、通常ICMPではなくTCP RST(リセット)パケットが返されます。tracerouteがUDPプローブを用いて宛先到達を検知できるのは、このPort Unreachableの仕組みを利用しているためです。

発生パターンの例

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)と呼びます。

経路上のファイアウォールでICMPが一律に遮断されていると、このCode 4メッセージが送信元に届かず、PMTUDが正常に機能しなくなることがあります(いわゆるPMTUDブラックホール)。この場合、DFビットが立った大きめのパケットが特定の経路でのみ黙って失われるという、原因の特定が難しい通信障害につながることがあります。

全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
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の実行結果

Linux1 ping -c 5 172.16.1.1
$ 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 4008ms

5回とも、宛先の172.16.1.1自身からではなく、経路上のR2(10.1.2.2)から「Destination Host Unreachable」の応答が返っています。

パケットキャプチャ

1回目(Sequence Number 1)のキャプチャです。

Echo Request(Linux1→172.16.1.1、R1宛に送信)
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)
ICMP Destination Unreachable(R2→Linux1、Host Unreachable)
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へ返送しています。

分類上はCode 0(Network Unreachable:宛先ネットワークへの経路がない)が該当しそうな状況ですが、実際にCisco IOS XEが返したのはCode 1(Host Unreachable)でした。クラスレスアドレッシング(CIDR)が前提の現代のIOSでは、経路表に一致するエントリが1つも無い場合は「宛先ホストへの経路が不明」として一律Host Unreachableを返す実装になっており、Network UnreachableはCIDR以前の設計を引き継いだ値として、実際に返されることはまれです。RFCの定義上はCode 0/1が区別されていても、実装依存でどちらか一方しか使われないケースがある点に注意が必要です。

icmp_host-unreachable.pcap をダウンロード

Port Unreachableの検証

Linux2(192.168.2.2)の5000番ポートでは、UDPで待ち受けているプロセスが存在しません。Linux1からこのポート宛にUDPデータを送信し、Port Unreachableの動作をパケットキャプチャで確認しました。

ncの実行結果

Linux1 nc -u 192.168.2.2 5000
cisco@linux1:~$ echo "test" | nc -u -w1 192.168.2.2 5000
cisco@linux1:~$

nc側には特にエラーは表示されませんが、-w1のタイムアウトまで応答を待って終了しています(UDPには応答の有無をnc自身が判定する仕組みがないため)。実際には後述のとおりICMP Port Unreachableが返っています。

パケットキャプチャ

UDPデータグラム(Linux1→Linux2、宛先ポート5000)
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")
ICMP Destination Unreachable(Linux2→Linux1、Port Unreachable)
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自身から発せられたものであることが確認できます。

Host UnreachableはR2(経路上のルータ)が送信元でしたが、Port Unreachableは宛先ホストであるLinux2自身が送信元になっている点が異なります。Port Unreachableは「宛先には到達できたが、指定ポートで待ち受けるプロセスが存在しない」ことを示すエラーであり、ルーティングの問題ではなく宛先ホスト側の問題であるため、発生元も宛先ホスト自身になります。

また、元のデータグラムの引用部分には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 792Internet Control Message ProtocolICMPの原典。Destination Unreachableの基本フォーマットとCode 0〜5を定義。
RFC 1191Path MTU DiscoveryCode 4とNext-Hop MTUフィールドを用いたPMTUDの仕組みを定義。

関連記事