ICMP-IPのサポート役

 TCP/IPプトロコルスイートのネットワーク層を見るとIP、ARP、RARPなどとともにICMPが載っています。しかし、Powershellで"c:\Windows\System32\drivers\etc\protocol"を確認すると(type、あるいはcatコマンド)、"icmp 1"と表示されます。これはどういうことでしょうか?プロトコル番号を持っているのはTCP(6番)やUDP(17番)などのトランスポート層のプロトコルではないのかと思った人もいるのではないでしょうか?
 プロトコル番号を持っているのはネットワーク層のプロトコル(実装)に対してサービス提供を依頼するプロトコルです。逆に言うとネットワーク層のプロトコルがサービスを提供する相手はプロトコル番号を持っていなくてはなりません。プロトコル番号を持っていないとネットワーク層からサービスを提供してもらえないのです。それはネットワーク層のプロトコルとその上のトランスポート層のプロトコルを連携させる鍵が「プロトコル番号」だからです。

 IPがどんな機能を持っているかについては既に学んでいると思います。IPがインターネットで果たしている役割は非常に重要で、インターネットの根幹にかかわるような仕事です。しかし、何でもやっているというわけではありません。IPの仕事は「Best Effort」型と呼ばれています。ベストエフォートというと聞こえはいいのですが、自分の果たすべき役割を何が何でもやり遂げるぞというようなものではありません。一旦試してみてだめなら、それっきりというものです。下位の物理ネットワークを構成しているイーサネットも実はベストエフォート型です。ベストエフォート型の上に、IPのベストエフォート型のサービスが積みあがっているというわけです。これでは何とも頼りないですね。エラーが発生しても、知らんぷりでは困ります。でも、IPは本当に忙しいので、そんなことを言われても困ります。私は、頑張っているんですと言い張るでしょう。そこで、エラー処理などを担当してIPを助けてくれるプロトコルが必要だということになりました。このプロトコルがICMP(Internet Control Message Protocol)です。ICMPはRFC792で規定されていますが、その後何度が追加のRFCが規定されています。



1 ICMPとは

 ICMPはIPを助けるためのプロトコルです。IPが提供するサービスは「ベスト・エフォート」型ですので、データグラムの途中での紛失、遅延、配信順の乱れなどがあってもそれに対応できません。受信側のIPはヘッダチェックサムで送信途中でのデータグラムの破損についてはチェックできますが、どこが破損しているかまでは分かりません。送信元に連絡しようにも、もしかしたら破損している部分は送信元データフィールドかも知れません。こうなるとエラー情報を返しても無理で、破棄するしかありません。

 ICMPはトラブルが発生しているが、ヘッダは損傷していないという程度の時に、IPを助けようとするプロトコルです。例えば、ネットワークの障害があって宛先までパケットを届けることが出来なかった場合などに送信元に知らせるなどの機能を持っています。

 ICMPはエラーメッセージと問い合わせメッセージに大きく分類されます。各メッセージはタイプ番号で識別されます(大分類での識別はされていません)。


2 ICMPヘッダ

 ICMPはIPと相互扶助の関係にあります。助け助けられるという関係です。IPを助けるためのプロトコルですが、配送自体はIPに依頼します。IPに運んでもらうわけですので、ICMPヘッダは次のようになります。

イーサネットヘッダ IPヘッダ ICMPヘッダ データ・・・

 ICMPヘッダフォーマットは次のようになります。

8 8 16
タイプ コード チェックサム
データ

 最初のフィールドのタイプ番号はICMPの種別を表す数字になります。同じタイプの中で更にコード番号で分類されています。いくつかのタイプは、ICMP通知が必要になった元のパケット(データグラム)の先頭部分をコピーしている場合があります。この種のタイプでは次のようなヘッダフォーマットを使います。タイプ番号でどちらのタイプのフォーマットを使うかが判別できます。

8 8 16
タイプ コード チェックサム
未使用 長さ 未使用
IPヘッダ+元のデータグラムの先頭部分



3 メッセージタイプ

 ICMPのメッセージはタイプ番号によっていくつかに分類されます。主なものは次の通りです。

Type番号  Type 状態 説明
 0 Echo Reply Message エコー応答通知(ping)
 1,2 未割当 予約済み
 3 Destination Unreachalbe Message 宛先到達不可能通知
 4 Source Quench Message 非推奨 送出抑制要求通知
 5 Redirect Message 経路変更要求通知
 6 非推奨 Alternate Host Address
 7 未割当 予約済み
 8 Echo Message エコー要求通知(pingで使用)
 9 Router Advertisement Message ルータ広告通知
 10 Router Solicitation Message ルータ請願通知
 11 Time Exceeded Message 時間超過通知
 12 Parameter Problem Message 不正引数通知
 13 Timestamp Message タイムスタンプ要求通知
 14 Timestamp Reply Message タイムスタンプ応答通知
 15 Information Request Message 非推奨 情報要求通知
 16 Information Reply Message 非推奨 情報応答通知
 17 Address Mask Request Message 非推奨 アドレスマスク要求通知
 18 Address Mask Reply Message 非推奨 アドレスマスク応答通知
 19 予約済 セキュリティ向けに予約済み
 以下省略



4 各種のメッセージ

4.1 エコー要求通知・エコー応答通知

 エコー要求通知とエコー応答通知はネットワーク診断用のpingなどで使われています。pingはネットワークにほとんど負荷をかけずにネットワークの到達性を判定することが出来ます。

8 8 16
タイプ(0or8) コード(0) チェックサム
識別子 シーケンス番号
データ(可変長)

 エコー要求はタイプ番号8、エコー応答はタイプ番号0で送信されます。現在定義されているコード番号は0だけです。識別子は適当な番号を送信側で決めています。要求したプロセスのIDなどが使われています。シーケンス番号は同じ識別子で繰り返しエコー要求した場合の通し番号です。
 宛先ホストがエコー要求を受け取ると、発信元と宛先のアドレスを入れ替え、タイプを0に書き換え、チェックサムを再計算します。識別子とシーケンス番号はエコー要求で指定されたものをそのまま返します。これで、どの要求に対応する応答なのかが分かります。データフィールドの値もそのまま返します。






4.2 宛先到達不可能メッセージ

 ルータあるいは宛先ホストのICMPはパケット(データグラム)を宛先まで届けることが出来ないと判断した場合は、パケットの送信元へ宛先到達不可能メッセージを送信します。

 8  8  16
タイプ(3) コード チェックサム
未使用 長さ 次hopのMTU
IPヘッダ+元のデータのデータグラム先頭部分

 宛先まで届けることが出来ない理由はそれぞれの場合ごとに違うでしょうから、それをコード番号を使って表します。宛先到達不可能メッセージのコード番号は次の通りです。

コード番号 内容
0 ネットワーク到達不能
1 ホスト到達不能
2 プロトコル到達不能
3 ポート到達不能
4 断片化が必要だがDFフラグがセットされている
5 送信元ルーティング失敗
6 宛先ネットワーク不明
7 宛先ホスト不明
8 宛先ホストが孤立している
9 宛先ネットワークとの通信が管理上禁止
10 宛先ホストとの通信が管理上禁止
11 Type of Serviceに対してネットワーク到達不能
12 Type of Serviceに対してホスト到達不能
13 通信が管理上禁止
14 ホスト優先度違反
15 優先度が低すぎる

 コード「0」はネットワークにまで到達できない場合です。そもそも、そのようなネットワークがないのか、あるいはルートがとぎれてしまっているのか?コード「1」は宛先ネットワークまでは到達できたけれども、ホストまで到達できないという場合です。そもそもホストの電源がOFFになっているのか、あるいはファイアウォールなどでブロックされているのか?「2」のプロトコル到達不能はホストにまでは辿り着いたが、そこでtcpd、udpdなどが動いていなかったか?「3」のポート到達不能はサービスが起動していないのか、あるいはファイアウォールでブロックされているのかなどが考えられます。「4」は断片化が必要なのにDFフラグがセットされているために断片化できないという場合です。

 ルータは経路途中にMTUが転送不能なほど狭いネットワークに遭遇することがあります。このような場合はDFフラグがセットされていない限りフラグメント化が行われます。これはルータにとっては手間のかかることです。経路途中の最低限のMTUが予め分かっていればルータを煩わせることはありません。そこで必要なのが経路MTU探索という手法です。これは、ICMPタイプ3の宛先到達不可能メッセージのコード4を使って実現されます(RFC1192)。この手法では、大きなメッセージをフラグメント化不可ビットをセットして(DFフラグのセット)して送ります。ICMP宛先到達不可能メッセージを受け取ったら、メッセージを少し小さくして再度試みます。これが成功したら、次のネットワークのMTUを調査するという具合に、宛先までのMTUを調査していくと経路の最低のMTUを調べることが出来ます。

 コード0~5までは最初のRFC792で規定されたものです。6~12はRFC1122で、13~15はRFC1812で追加されたものです。


4.3 送出抑制要求通知

8 8 16
タイプ(4) コード(0) チェックサム
未使用 長さ 未使用
IPヘッダ+元データのデータグラムの先頭部分

 ルータやホストは受信能力を超える速さでデータが届いたときにはデータを破棄し、送出抑制通知を送信元に返します。

4.4 経路変更要求通知

8 8 16
タイプ(5) コード チェックサム
ゲートウェイのIPアドレス
IPヘッダ+元データのデータグラムの先頭部分

 通常ルータにはルーティングプロトコル(の実装、ripdやospfdなど)が動いていて、同じルーティングプロトコル同士でルート情報の交換を行っています。ルータはそれを元にしてルーティングテーブルを管理してます。ルータは経路について非常によく知っています。というより、それがルータのメインの仕事です。ところが一般的なホスト(パソコン)にはルーティングプロトコルが動いていることはあまりありません(特にWindowsクライアントマシン)。したがって、ホストはルートのことはあまりよく知りません。今使っているよりもいい経路があるのにホストが知らないという場合がありますので、そのような場合にルータが経路変更要求通知を使って知らせます。ルータといってもインターネットの内部で稼動しているルータではなく、ローカルネットワークの出口を制御しているいわゆるデフォルトゲートウエイです。デフォルトゲートウエイはもっといい出口を知っているときは、次回以降の通信では他のゲートウェイを使うように指示します。経路変更要求通知を受け取ったホストは、自分のルーティングテーブルに追記し、該当する次のデータグラムからは指示されたゲートウエイに送ります。

コード番号 説明
0 ネットワークに関する経路変更要求
1 ホストに関する経路変更要求
2 Type of Serviceとネットワークに関する経路変更要求
3 Type of Serviceとホストに関する経路変更要求

 自分のルーティングテーブル?と思ったかもしれませんが、通常のパソコンでもルーティングテーブルは持っています。Windowsの場合はpowershellで"route print"とコマンドを打ってみてください。





4.5 ルータ広告通知

 ルータ広告通知(Router Advertisement Message、タイプ9)と次のルータ請願通知(Router Solicitation Message、タイプ10)はRFC 1256で追加された拡張機能です。2つを合わせてルータ発見プロトコル(Router Discovery Protocol)などと呼ばれています。
 ルータにはルーティングプロトコルと呼ばれるプロトコル(の実装)がインストールされていてルータ同士で会話をし、経路情報を交換しています。したがって、ネットワークに新たにルータが追加されて、ルートが変わったとしてのルータにとっては何の問題もありません。ホストにはルーティングプロトコルの実装はあまりインストールされていません。ホストにはルーティングプロトコルはあまり必要ありません。。何故かというとホストにとっては出口が1つという場合がほとんどだからです。この1つは通常はデフォルトゲートウェイと呼ばれます。しかし、ホストが利用できる出口(ゲートウエイ)が複数の場合はどうでしょうか。ホストがルーティングプロトコルをしゃべることができれば好都合です。しかし、ことはそんなに簡単ではありません。

 ルータ上でRIP(実装はripd)やOSPF(実装はospfd)などの標準のルーティングプロトコルを動かせば済むなら問題は小さいのですが、Cisco Systemsなどのネットワーク機器のベンダは自社独自開発の非標準のルーティングプロトコル(IGRP、EIGRPなど)を開発し、ネットワーク構築者はそれを好んで利用するという傾向にあります。こうなると、ホストにはルータが発信するルート情報を理解することができません。更にたとえ、言葉を理解できたとしても、日々高機能化されるルータから大量にしかも高速に吐き出される情報を読み取り、理解するだけでも大変な作業量となってしまいます。ホストは本来の仕事とは異なるルーティング情報の処理に忙殺されて、本来の仕事がおろそかになっては本末転倒です。

 ホストが欲している情報は簡単なもので、インターネット上のルータネットワークの構造に関する情報など要りません。ホストはゲートウエイを簡単に発見したいだけなのです。そうだとすれば、それにだけ特化した標準のプロトコルを定義すればよいということになりました。このような経緯で開発されたプロトコルがICMPの拡張機能として開発されたルータ発見プロトコルです。

 ルータ発見プロトコルはルータベンダとは関わりのない標準プロトコルですので、ホストとルータがRDPを使って会話することも可能です。 ルータ発見プロトコルを実装したルータは動作中一定間隔で、ルータ広告通知(メッセージ)をマルチキャストします。マルチキャストアドレスはサブネット内の全てのシステムが受け取れるようなものとなっています。ホストはこの広告を聴取することでサブネットワーク内で稼動しているルータを発見することができます。ホストがサブネットに加わったばかりの場合はすぐにルート情報がほしいということがあるかもしれません。このような場合はホストから積極的に要請するメッセージも欲しくなります。このような場合に利用されるのがルータ請願通知です。

8 8 16
タイプ(9) コード(0) チェックサム
ルータアドレス数 1エントリ当りの長さ 有効期限
ルータアドレス その1
優先度 その1
ルータアドレス その2
優先度 その2
・・・

 デフォルトゲートウエイのアドレスを通知します。ルータアドレス数フィールドで指定した数だけ列挙することができます。優先度の数が大きなものほど優先度が高くなります。優先度は2の補数表現が使われています。


※マルチキャストは決められた特定の複数の相手に同時にパケットを送信する通信方式です。

4.6 ルータ請願通知

8 8 16
タイプ(10) コード(0) チェックサム
未使用


4.7 時間超過通知

8 8 16
タイプ(11) コード チェックサム
未使用 長さ 未使用
IPヘッダ+元データのデータグラムの先頭部分

 タイプ11の時間超過メッセージはコード0とコード1が使われます。

 コード0はTTLがゼロになっても宛先ホストに到達できなかったことを通知します。TTLはパケット(データグラム)がルータをホップすることを許された回数です。ルータはパケットを転送させる際にTTL値から1を引いていきます。そして、TTLが0になったら、ルータはパケットの転送を止め、破棄します。

 コード1は断片(フラグメント)の再統合を行う際に、制限時間内に断片がそろわなかったことを通知します。宛先ホストは最初のフラグメントパケットを受信するとタイマーをセットし、タイムアップする前に全部にフラグメントを受け取れなかったときには、それまで到着している全てのフラグメントを破棄し、時間超過メッセージを送信元に送ります。

 インターネットの経路探索(診断用)ツールとしてtracerouteというプログラムがありますが、これはタイプ11コード0の時間超過メッセージと、タイプ3の宛先到達不可能メッセージを組み合わせて作成されています。


TTLを1から順に増やして、最後に間違いのポートを指定

 上の図で分かる通り宛先ホストに到達するまではICMP時間超過メッセージを使い、宛先に到達したらICMP宛先到達不可能メッセージを使っています。宛先到達不可能メッセージは、実際に定義されていないポート番号を指定することで強制的に返答させています。届けられたICMPメッセージの送信元のIPアドレスを上から並べて表示すれば、経路の表示になります。

 Windowsのpowershellの画面から、"tracert google.co.jp"を実行すれば、どのような経路でgoogle.co.jpまでたどっていくのかが分かります。



4.8 不正引数通知

8 8 16
タイプ(12) コード(0) チェックサム
ポインタ 長さ 未使用
IPヘッダ+

 不正引数(パラメータ)通知は、タイプ番号12で知らされます。ルータやホストはデータグラムのヘッダのパラメータに以上を発見したら、元のデータグラムを破棄し、不正引数通知で送信元に知らせます。ポインタは元のデータのうち問題となった箇所を、先頭からのオクテット数で指定します。



4.9 タイムスタンプ要求通知・タイムスタンプ応答通知

8 8 16
タイプ(13、14) コード(0) チェックサム
識別子 シーケンス番号
起点タイムスタンプ
受信タイムスタンプ
送信タイムスタンプ

 タイムスタンプ要求通知はタイプ13です。タイムスタンプ要求通知の識別子は送信元で適当に決めます(要求元プロセスのプロセスIDなどが使われます)。シーケンス番号は、同じ識別子で繰り返しタイムスタンプ要求をした場合の通し番号です。起点タイムスタンプは要求時のタイムスタンプです。

 宛先となったホストはタイプ14で応答します。識別子、シーケンス番号、起点タイムスタンプは要求にセットされていたものをそのままコピーします。受信タイムスタンプは要求を受信した際のタイムスタンプを、送信タイムスタンプは応答を送信する際のタイムスタンプをセットします。

 起点タイムスタンプと応答メッセージの受信時間の差分からメッセージの往復時間を割り出すことができます。これによってネットワークが輻輳しているか判断することができます。また、受信タイムスタンプと、送出タイムスタンプの差分から、装置のバッファ内の輻輳をある程度想像することもできます。更に、往復時間と、輻輳時間から、メッセージが伝送媒体を伝わる時間(ただし、ルータやスイッチの遅延も含む)も分かります。



 

4.10 情報要求通知・情報応答通知

8 8 16
タイプ(15,16) コード(0) チェックサム
識別子 シーケンス番号


 使われていません。自分のIPアドレスを知らないホストがそれを解決するために利用することを想定していたようですが、RARP、BootP、DHCPなどが次々に開発されていますので、今は利用されていません。

4.11 アドレスマスク要求通知・アドレスマスク応答通知

8 8 16
タイプ(17,18) コード(0) チェックサム
識別子 シーケンス番号
アドレスマスク

 RFC950で追加されたメッセージです。





更新履歴

2016/02/10 作成


















































































 ページの先頭