一覧NW-06-1 · ARPとICMP

ARPと近隣テーブル

同一リンクの次ホップを解決し、保存した対応の変化を確認します。

説明

EthernetでIPv4パケットを送るには、同じリンク上の次ホップのMACが必要です。ARPはIPv4アドレスとMACの対応を問い合わせ、その結果を近隣表へ保存するために使います。

同一ネットワークと遠隔ネットワークの宛先を比べ、ARPが誰を問い合わせるかをPCAPとバイト列で確認します。保存後の状態変化と、同じIPが別MACを通知した記録も調べます。

1経路がARPの問合せ先を決める

端末は192.0.2.10/24で、default gatewayは192.0.2.1です。routes.txtはこの条件の経路表を保存した教材記録です。

cat routes.txt直結経路と次ホップ

同じ192.0.2.0/24内の宛先は直接送り、それ以外は192.0.2.1へ渡します。ARPはIP宛先を無条件に問い合わせるのではなく、経路で決まった同一リンク上の次ホップのMACを解決します。

2同じネットワークの端末へ問い合わせる

192.0.2.20へ送る前のARP要求と応答を読みます。

tcpdump -n -tt -eARPとEthernet宛先 -r local-arp.pcap同一ネットワークの解決

要求はEthernetブロードキャストで、192.0.2.20のMACを尋ねています。応答は末尾14のMACを通知し、要求元の末尾0aへ返しています。IP通信の前に、同じリンクで使う宛先MACが得られます。

3ARP本体の各欄

arp-request.binはARP本体28バイトです。Ethernetヘッダーは含みません。先ほどの表示のlength 46にはEthernetのパディング18バイトが含まれます。

xxd -g 1 -c 16ARPを1バイトずつ表示 arp-request.binARP本体

00 01はEthernet、08 00はIPv4、06と04は各アドレスの長さ、次の00 01は要求を表します。送信元MACとIP、対象MACとIPが続きます。対象MACはまだ不明なので、この要求では0を入れています。

4ARPの対象IPをバイトから読む

固定長欄を復号し、送信元IPと対象IPを取り出します。

python3 -cARPの欄を復号 'from pathlib import Path; import struct,ipaddress; a=Path("arp-request.bin").read_bytes(); print(struct.unpack("!HHBBH",a[:8])); print(a[8:14].hex(":"),ipaddress.ip_address(a[14:18]),ipaddress.ip_address(a[24:28]))'長さと送信元・対象のIP

アドレス長6・4と要求opcode1が確認できます。送信元は192.0.2.10、対象は192.0.2.20です。Ethernet宛先は全員宛てでも、ARPが尋ねているIPは一つです。異なる欄の「宛先」を混同しないようにします。

5別ネットワークへ送る場合

次に198.51.100.20へ送る前のARPを読みます。この経路では192.0.2.1を次ホップにします。

tcpdump -n -tt -e問合せ先と応答 -r gateway-arp.pcap遠隔宛先の送信前

問い合わせているのは遠隔端末ではなく192.0.2.1です。IPパケットの最終宛先は198.51.100.20のままですが、最初のEthernet配送先にはゲートウェイのMACを使います。

6近隣表へ保存した対応

二つの解決後に保存された近隣表を読みます。

cat neighbors.txt解決後の近隣表

近隣端末.20とゲートウェイ.1のMACが残っています。遠隔IP198.51.100.20のMACをこのLANで保存する必要はありません。次の送信では保存済みの対応を使えるため、毎パケット必ずARPを出すわけではありません。

7STALEは直ちに消えた状態ではない

neighbor-events.csvは同じ対応の状態変化を整理した教材例です。時刻はこの例の秒であり、全環境の固定タイマーではありません。

cat neighbor-events.csv対応と到達性確認の変化

35秒時点でSTALEでもMACは残っています。使用をきっかけにDELAY、PROBEへ進み、確認できればREACHABLEへ戻る流れです。STALEだけで相手の停止を断定せず、確認状態と保持されている対応を分けて読みます。

8同じIPが新しいMACを通知した場合

ゲートウェイのMACが末尾99へ変わった通知と、その通知を採用する設定で更新された表を読みます。

tcpdump -n -tt -e -r announcement.pcap新しいMACの通知; cat neighbors-updated.txt通知を採用した後の表

ARP Announcementでは送信元IPと対象IPがどちらも192.0.2.1です。通知を受けて既存の対応が更新される例ですが、ARP自体に送信者を暗号的に認証する仕組みはありません。正当な切替かを判断するには、機器の変更記録やネットワーク側の制御も確認します。

まとめ

経路で次ホップを決め、その同一リンク上のIPに対してARPを行います。

Ethernetの宛先とARPが問い合わせる対象IPは別の欄です。

近隣表のMACと到達性状態、通知による変更をそれぞれ確認します。

操作履歴と解説を振り返れます。

シェル / PCAPと通信の記録

1
cat routes.txt
192.0.2.0/24 dev eth0 scope link src 192.0.2.10
default via 192.0.2.1 dev eth0
2
tcpdump -n -tt -e -r local-arp.pcap
reading from file local-arp.pcap, link-type EN10MB (Ethernet)
0.000000 02:00:00:00:00:0a > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.0.2.20 tell 192.0.2.10, length 46
0.001000 02:00:00:00:00:14 > 02:00:00:00:00:0a, ethertype ARP (0x0806), length 60: Reply 192.0.2.20 is-at 02:00:00:00:00:14, length 46
3
xxd -g 1 -c 16 arp-request.bin
00000000: 00 01 08 00 06 04 00 01 02 00 00 00 00 0a c0 00  ................
00000010: 02 0a 00 00 00 00 00 00 c0 00 02 14              ............
4
python3 -c 'from pathlib import Path; import struct,ipaddress; a=Path("arp-request.bin").read_bytes(); print(struct.unpack("!HHBBH",a[:8])); print(a[8:14].hex(":"),ipaddress.ip_address(a[14:18]),ipaddress.ip_address(a[24:28]))'
(1, 2048, 6, 4, 1)
02:00:00:00:00:0a 192.0.2.10 192.0.2.20
5
tcpdump -n -tt -e -r gateway-arp.pcap
reading from file gateway-arp.pcap, link-type EN10MB (Ethernet)
0.000000 02:00:00:00:00:0a > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.0.2.1 tell 192.0.2.10, length 46
0.001000 02:00:00:00:00:01 > 02:00:00:00:00:0a, ethertype ARP (0x0806), length 60: Reply 192.0.2.1 is-at 02:00:00:00:00:01, length 46
6
cat neighbors.txt
192.0.2.20 dev eth0 lladdr 02:00:00:00:00:14 REACHABLE
192.0.2.1 dev eth0 lladdr 02:00:00:00:00:01 REACHABLE
7
cat neighbor-events.csv
TIME,IP,STATE,MAC
0,192.0.2.20,REACHABLE,02:00:00:00:00:14
35,192.0.2.20,STALE,02:00:00:00:00:14
40,192.0.2.20,DELAY,02:00:00:00:00:14
45,192.0.2.20,PROBE,02:00:00:00:00:14
46,192.0.2.20,REACHABLE,02:00:00:00:00:14
8
tcpdump -n -tt -e -r announcement.pcap; cat neighbors-updated.txt
reading from file announcement.pcap, link-type EN10MB (Ethernet)
0.000000 02:00:00:00:00:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Announcement 192.0.2.1, length 46
192.0.2.1 dev eth0 lladdr 02:00:00:00:00:99 STALE

演習完了