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と通信の記録
cat routes.txt192.0.2.0/24 dev eth0 scope link src 192.0.2.10 default via 192.0.2.1 dev eth0
tcpdump -n -tt -e -r local-arp.pcapreading 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
xxd -g 1 -c 16 arp-request.bin00000000: 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 ............
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
tcpdump -n -tt -e -r gateway-arp.pcapreading 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
cat neighbors.txt192.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
cat neighbor-events.csvTIME,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
tcpdump -n -tt -e -r announcement.pcap; cat neighbors-updated.txtreading 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
演習完了