前述の例1で、 ノードAはノードBが同一サブネット上にあることがわかるので、 ノードBに直接パケットを送信しようとします。 ところがLANのところでお話したように、 イーサネット上にパケットを送出するためには、 宛先のMACアドレスを知らなければなりません。 ここで、IPアドレスからMACアドレスを知るためのしくみが必要となります。 IPネットワークでは、これをARP (Address Resolution Protocol --- アドレス解決プロトコル) により実現しています。
ARPは単純なプロトコルで、知りたいIPアドレスをパケットにセットして、 ブロードキャスト(*1)を行うというものです。 パケットは同一サブネット上にあるすべてのノードが受信しますが、 (設定ミスがない限り)該当のIPアドレスを持つノードは 1つしかないはずなので、そのノードが自分のMACアドレスをセットして、 送信元のノードに対して答えを返します。
(*1)…ただしここでいうブロードキャストは、IPレベルのブロードキャストではなく、MACレベルのブロードキャストです。MACレベルのブロードキャストは、単にイーサネット・ヘッダ中の宛先MACアドレスを 'ff:ff:ff:ff:ff:ff' にして送信するというものです。同一ネットワーク上の全ノードがこれを受信します。
送信元ノードA | 宛先ノードB | その他のノード | |
あるIP(ノードB)にパケットを送信したいが、 対応するMACアドレスが分からない | |||
ARP要求 (このIPに対応するMACは誰?) | ====> (ブロードキャスト) | ||
<−−−− | ARP応答 (私です) | 無視(*1) | |
返ってきたMACに対して パケットを送信 | −−−−> | 受信 | ここには来ない(*2) |
(*1)…MACアドレスがブロードキャストだったので受信を行い、そのパケットがARP要求であることを認識しますが、問いあわせの対象が自分でないので無視します。このように、IPレベルでは一般的に否定応答などはありません。ノードAは、誰からも応答が返らない(応答タイムアウト)場合は、そのIPは同一ネットワークには(現時点では)存在しないものとして、上位に「Request timed out」のエラーを返します。(*2)…物理的には(低レベルでは)受信していますが、MACアドレスがブロードキャストでもなく自分宛てでもないので、単に無視します(上位レベルにパケットの受信を知らせない)。(*1)のパターンとは、無視するレベルが違うことに注意してください。
なおARPパケットは、一般的なIPパケットとは形式が異なるのですが、ここでは割愛します。
パケットを送信するたびに毎回ARP要求を出していたのでは無駄ですし、ネットワークのトラフィックを増やすだけです。そこで各ノードは、いったんMACアドレスの解決が行われると、MACアドレスとIPアドレスの対応表(ARPテーブル)をメモリ上に保持(キャッシング(caching)といいます)し、宛先のIPアドレスがARPテーブルに登録されていない場合のみ、ARPリクエストを出すように実装されているのがふつうです。
以下に、ARPテーブルを表示した例を示します。
例1)ARPテーブル(Windows 95/NT)
C:\>arp -a | ||
Interface: 192.168.0.15 on Interface 2 | ||
Internet Address | Physical Address | Type |
192.168.0.17 | 00-20-af-f5-8a-30 | dynamic |
192.168.0.23 | 00-40-c7-57-92-ef | dynamic |
例2)ARPテーブル(Linux 2.0.30)
server2:~# arp -a | ||||
Address | HW type | HW address | Flags | Mask |
192.168.0.17 | 10Mbps Ethernet | 00:20:AF:F5:8A:30 | C | * |
192.168.0.23 | 10Mbps Ethernet | 00:40:C7:57:92:EF | C | * |