ICMPについて勉強した

ICMPとは、IPレベル(ネットワーク層)での送達確認を行うためのプロトコルです。pingコマンドとtracerouteコマンドがICMPを利用しています。

目次

  • ICMPを含むIPパケット
  • ICMPエコー要求
  • ICMPエコー応答
  • 到達不能
  • 時間経過
  • tracerouteの仕組み
  • おまけ: 到達不能の検証方法のメモ

ICMPを含むIPパケット

ICMPはIPパケットに埋め込まれて送信されます。

ICMPエコー要求

pingコマンドの実行時、宛先ノードに対して送信されます。

ICMPエコー応答

正常に通信可能な場合、pingコマンドの宛先ノードから返信されます。

到達不能

経路上のルータが宛先ノードへの経路情報を保持しない場合、ルータから返信されます。

時間経過

宛先ノードに到達する前にTTLが0になると、ルータから返信されます。経路がループしている場合に発生することがあります。

tracerouteの仕組み

tracerouteコマンドを実行すると、宛先ノードまでの経路上にあるルータを見つけられます。
tracerouteは、まず宛先ノードに対してTTLが1のICMPエコー要求を送信します。すると、経路上の最初のルータでTTLが0になるため、ルータは『時間経過』を示すICMPパケットを返送します。このICMPパケットにより、最初のルータが見つかります。
次に、tracerouteはTTLが2のICMPエコー要求を送信します。すると、経路上の2番目のルータが『時間経過』を示すICMPパケットを返信するので、2番目のルータが見つかります。
その後も、tracerouteは宛先ノードに到達するまでTTLを増やしながらICMPエコー要求を送信します。その結果、宛先ノードまだの経路上にあるルータを見つけることができます。

おまけ: 到達不能の検証方法のメモ

ICMPパケット到達不能の状況を再現するため、Linuxマシンに「経路情報を保持しないルータ」のフリをさせました。
以下は、Windowsマシンでの「ping 203.216.235.201」の結果を『Destination host unreachable』とするための手順です。

(1)Windowsにて、経路情報を追加し、ICMPパケットがLinuxに送信されるようにする。

以下のコマンドを実行して経路情報を追加します。なお、192.168.1.21はLinuxマシンのIPアドレスです。

route add  203.216.235.0 mask 255.255.255.0 192.168.1.21
(2)Linuxにて、カーネルパラメータを変更してパケットフォワーディングを許可する。

/etc/sysctl.confを編集し、以下の行の値を1にします。

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
(3)Linuxにて、変更したカーネルパラメータを即座に反映する。

以下のコマンドを実行すると変更内容が反映され、パケットフォワーディングが行われるようになります。

/sbin/sysctl -p

これにより、Linuxマシンはルータのようにパケットを転送するようになります。

(4)Linuxにて、経路情報を明示的に削除する。

以下のコマンドを実行し、ネットワーク「203.216.235.0」への経路情報を明示的に削除します。

route add -net 203.216.235.0 netmask 255.255.255.0 reject

これにより、203.216.235.201向けのICMPエコー要求が到達した際に、Linuxマシンは『到達不能』を返信するようになります。