前回は、ネットワークの向こう側にいる相手がIP的に到達可能かどうかを確認するためのpingコマンドを紹介しました。次は、ネットワークの向こうにいるホストまでの経路を知ることが出来るtracerouteコマンドです(UNIX系、Mac OS Xはtraceroute、Windowsではtracert)。
ここでは、ユーザ環境がWindowsであると想定して書いていますが、UNIX系OSやMac OS Xをご利用の場合は「tracert」の部分を「traceroute」に置き換えて読んで下さい。
インターネットには、特定のパケットが永遠にネットワーク内を徘徊しないように、各パケットに安全装置があります。安全装置は、IPヘッダ内にTTL(Time To Live)というフィールドを作ることによって実現しています。このTTLフィールドは、ルータによりパケットが転送されるたびに値が1引かれます。
IPパケットの転送が繰り返されると、TTLの値は転送ごとに減って行きます。最終的にIPパケットが宛先まで届けば良いのですが、宛先に届く前にTTLが0になってしまうとIPパケットは消滅します。しかし、単に消滅してしまうと何が起きたのかがわからない場合があるので、ルータはTTLが0のIPパケットを破棄するときにはIPパケットを送った送信元に対してICMP Time Exceededという種類のICMPパケットを送信します。
tracertは、このICMP Time Exceededを利用しています。意図的にTTLの値を小さくして、ICMP Time Exceedが発生する環境を作成しているのです。
では、実際のtracertの動作を見て行きましょう。
tracertは、まず最初にTTL=1でIPパケットを送信します。すると、パケットが一度転送された状態でTTLが0となり、tracertを実行した機器の隣のルータからICMP Time Exceedが返ってきます。
次に、TTL=2でIPパケットを送信します。今度は、隣の隣にいるルータがICMP Time Exceed を返してきます。
このようにTTLの値を利用して1ホップずつ把握していけるtracertですが、このままでは最終的な目的地に到達したときに困ります。本来の目的地についたということは、TTLとして十分な値が設定されたということだからです。ICMP Time Exceedが送信されるのはTTLが0となった場合であるため、パケットが目的地に到達した場合にはICMP Time Exceedは送信されません。
そのため、tracertは最後の1ホップだけはICMP Time Exceedを利用しません。最終的な目的地にIPパケットが到着したことを知る手段で一般的なものは2つあります。
2つめの方法は、tracertによって送信されるIPパケットをUDPにすることです。UDPの宛先ポート番号は、宛先でサービスが存在しないものを利用します。そうすることにより、宛先にUDPパケットが届いたときに、宛先ホストはICMP Port Unreachを送り返してくれます。 ICMP Port Unreachは、「そのポートは開いていないよ」と教えてくれるICMPメッセージです。