(2015-03-04)
注意事項など
このページは、出力結果を見やすくするために画面が横長になってしまっています。あらかじめご了承ください。
また、今回の実験では同一ネットワークにNICを2枚接続していますが、こんなことはめったにやらないことだと思います。
(冗長化もしくはbondingはまた別の話)。
興味本位での実験ですので、もし真似されるような場合は十分ご注意ください。
(どうなっても知りませんよ~ということで)。

実験の趣旨

Linuxでは、1つのマシン上にNICが複数し、同一ネットワークに接続している場合に、
ARPへの応答の際にIPアドレスとMACアドレスの組み合わせを誤って回答してしまうことがあります。
この現象は下記のようなLinuxの仕様によるものです。

Linuxカーネルの仕様
ARPの問い合わせを受信し、自分が持っているIPアドレスのどれかにマッチする場合に、
ARPを「受信した」ネットワークデバイスのMACアドレスを返す。
(IPアドレスにマッチするネットワークデバイスのMACアドレスかどうかは区別しない)

今回、簡単な実験を行い上記の現象を確認してみます。
また、あわよくば「正しいMACアドレスを返す」ことができないか探ってみることにします。

なお、これらが何かの役に立つかどうかはまったくもってわかりませんのであしからず(^^;)。

目次

実験の前提環境

例によってRaspberry Piを使います。
MACアドレスは実際のものではありません(伏字の代わりに下記を使います)。

装置deviceIP AddressMAC Address備考
マシンAeth0192.168.1.2111:11:11:11:11:11LANは有線
wlan0192.168.1.5122:22:22:22:22:22無線LAN。手動起動
マシンBbr0192.168.1.2099:99:99:99:99:99確認用マシン
  • ネットワークアドレス 192.168.1.0/24
  • 有線LANインターフェース:Raspberry Pi 本体のもの
  • 無線LANインターフェース:USB接続の GW-USNANO2A
  • 無線LANの設定方法は Raspberry Pi/無線LAN を参照。
  • マシンBのネットワークデバイス名が br0 になっているのはブリッジを構成しているため(実験とは無関係、多分)

大まかな接続図としてはこんな感じ。

                      [NTTルーター]
                           | 192.168.1.0/24
           +------(有線)---+-----------+------------+
           |                           |            |
           |                           |            |
     192.168.1.21                 192.168.1.20      |
[マシンA (eth0)  (wlan0)]    [マシンB (br0)]    [無線アクセスポイント]
              192.168.1.51                          :
                    :                               :
                    :                               :
                    :..............(電波)...........:

シナリオ

複数NIC搭載マシンへのARP問い合わせのシナリオとしてはだいたいこんな感じかと。

マシンBがマシンAのIPアドレスを問い合わせるケース

  1. マシンBがARPにて IPAddr=192.168.1.20 に対するMACアドレスの問い合わせをブロードキャスト。
  2. マシンAはマシンBからのIPアドレス問い合せのブロードキャストを eth0 で受信(補足 eth0で受けるか
    eth1で受けるかの優先順位は不明。タイミングにより異なるのかもしれない。未確認)。
    マシンAは、IPAddr=192.168.1.20を所有しているので、ARPに対する応答を返す。
    この時のMACアドレスは、ブロードキャストを受信した eth0 のMACアドレスを返す。
  3. マシンBはARPの応答として、IPAddr=192.168.1.20 ,MAC=11:11:11:11:11:11 という内容を取得する。
    これは実際のマシンAでのネットワークインターフェースの構成と異なる。
    マシンBはこの応答結果を使ってとりあえず通信することはできる
    (マシンAでeth0側でパケットフィルタリング等していなければ)
    このとき、マシンBでは、IPAddrとしては192.168.1.20に対して通信しているつもりになっているが、
    実際の通信ではMAC=11:11:11:11:11:11すなわちマシンAのeth0側と通信することになる。
    このとき、マシンA側も拒否することなく通信できてしまう。

実験1:現象確認

まずは現象を確認してみます。

ネットワークインターフェースはすべて起動済みとしておきます。

準備

マシンBでARPテーブルをクリアし、マシンAのIPアドレス、MACアドレスの組み合わせを削除します。

root@Machine-B # arp -d 192.168.1.21
root@Machine-B # arp -d 192.168.1.51
root@Machine-B # arp -n | egrep '192.168.1.[25]1 '
アドレス               HWタイプ  HWアドレス         フラグ マスク インタフェース
192.168.1.51                     (不完全)                               br0
192.168.1.21                     (不完全)                               br0

pingによる確認

マシンBからマシンAに向けて ping コマンドを発行し、ARPの実行結果を確認します。
ARPテーブルをクリアしてから ping を発行することで、IPアドレス->MACアドレス解決のためにARPが発行されることになります。
結果の確認には arp, tcpdump を使います。

マシンB:ping

root@Machine-B # ping -c 1 192.168.1.51
PING 192.168.1.51 (192.168.1.51) 56(84) bytes of data.
64 bytes from 192.168.1.51: icmp_req=1 ttl=64 time=2.36 ms

--- 192.168.1.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.361/2.361/2.361/0.000 ms

マシンB:tcpdump

root@Machine-B # tcpdump -i br0 -n -e arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:43:48.100167 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:43:48.101192 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46
15:43:48.101434 99:99:99:99:99:99 > 11:11:11:11:11:11, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7628, seq 1, length 64
15:43:48.102417 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7628, seq 1, length 64

マシンB:ping後のARPテーブル

root@Machine-B # arp -n
アドレス               HWタイプ  HWアドレス         フラグ マスク インタフェース
192.168.1.51             ether   11:11:11:11:11:11   C                     br0
192.168.1.21                     (不完全)                               br0

実験1の結果のまとめ

マシンBからのARP(IPアドレス192.168.1.51に対するMACアドレスの問い合わせ)のブロードキャスト:

15:43:48.100167 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28

に対して、マシンAの eth0(MACアドレス 11:11:11:11:11:11)が応答:

15:43:48.101192 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46

を返している。
IPアドレス192.168.1.51の割当インターフェースはwlan0なので、パケットの送信元MACアドレスは
22:22:22:22:22:22 となってほしいところではあるが、そうはならない、ということが確認できる。
その後の下記パケット (ICMP echo すなわちping)で、IPアドレスとMACアドレスがずれた状態でも、
通信自体はうまくいっているのがわかる。

15:43:48.101434 99:99:99:99:99:99 > 11:11:11:11:11:11, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7628, seq 1, length 64
15:43:48.102417 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7628, seq 1, length 64

つまりは、192.168.1.51 を指定して通信をしても、実際にはwlan0=無線LANではなく、eth0=有線LAN側を
使って通信を行ってしまう、ということになるのでした。

実験2:正しいインターフェースで通信可能か

実は無線LANの増設を紹介しているホームページ等で説明されているのですが、
「無線LANインターフェースを指定した通信の場合は無線LAN側からパケットを送信せよ」
という指定ができるらしいので、さっそく試してみます。
(というより、無線LANの構築の際に /etc/network/interfaces に記載しておくべきものらしい。
NICが1つしかない場合はこの設定は不要です。)
こちらを参考にさせていただきました。

準備

具体的には、マシンAのルーティングに対して下記のルールを追加します。
意味としては、192.168.1.51から来たものに対しては、192.168.1.51へ返事せよ、ということらしいです。

root@Machine-A # ip rule add from 192.168.1.51 table 100 prio 200
root@Machine-A # ip route add dev wlan0 src 192.168.1.51 table 100

それと、実験1と同じく マシンBのARPテーブルからIPアドレスを削除しておきます。

root@Machine-B # arp -d 192.168.1.21
root@Machine-B # arp -d 192.168.1.51

pingによる確認

マシンBからマシンAに向けて ping コマンドを発行し、ARPの実行結果を確認します。
今回はマシンAの tcpdump の結果を、ネットワークインターフェースごとに取得します。
tcpdumpでは ARP および ICMP echo(=ping) のパケットを表示してみます。

マシンB:ping

root@Machine-B # ping -c 1 192.168.1.51
PING 192.168.1.51 (192.168.1.51) 56(84) bytes of data.
64 bytes from 192.168.1.51: icmp_req=1 ttl=64 time=4.37 ms

--- 192.168.1.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 4.377/4.377/4.377/0.000 ms

マシンB:tcpdump

root@Machine-B # tcpdump -i br0 -n -e arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:16:25.851843 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:16:25.853188 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46
15:16:25.853415 99:99:99:99:99:99 > 11:11:11:11:11:11, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7586, seq 1, length 64
15:16:25.856669 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7586, seq 1, length 64

マシンB:ping後のARPテーブル

root@Machine-B # arp -n
アドレス               HWタイプ  HWアドレス         フラグ マスク インタフェース
192.168.1.51             ether   22:22:22:22:22:22   C                     br0
192.168.1.21                     (不完全)                               br0

マシンA:tcpdump(インターフェース eth0)

root@Machine-A # tcpdump -n -e -i eth0 arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:16:25.854860 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.51 tell 192.168.1.20, length 46
15:16:25.855135 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 42: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 28
15:16:25.856431 99:99:99:99:99:99 > 11:11:11:11:11:11, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7586, seq 1, length 64

マシンA:tcpdump(インターフェース wlan0)

root@Machine-A # tcpdump -n -e -i wlan0 arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:16:25.856811 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7586, seq 1, length 64

実験2の結果のまとめ

マシンBからのARP発行の部分および、ICMP echoの1行(下記3行)までは実験1と同じです。

15:16:25.851843 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:16:25.853188 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46
15:16:25.853415 99:99:99:99:99:99 > 11:11:11:11:11:11, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7586, seq 1, length 64

すなわち、IPアドレス192.168.1.51に対応するMACアドレス11:11:11:11:11:11を取得し、ICMP echoのパケットを 11:11:11:11:11:11 に対して投げるところまでです。

異なるのは、マシンBの tcpdump の4行目:

15:16:25.856669 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7586, seq 1, length 64

の部分で、マシンBからマシンAの MAC=11:11:11:11:11:11 に対して投げたICMP echoパケットの応答が、
マシンAのMAC=22:22:22:22:22:22から帰ってくるようになりました。
この結果、マシンBのARPテーブルには、マシンAのIPアドレスとMACアドレスが正しい組み合わせで保持されています。

今回、マシンAでもパケットを出力してみましたが、最後のICMP echoの応答は確かに wlan0 インターフェースから
出力されているのがわかります。

実験3:初回のARPで正しい回答をしたい

さて、実験2の設定により、通信開始時のIPアドレス->MACアドレス変換さえ我慢すれば、
とりあえず通信自体は wlan0(無線LAN)でもできるようになりました。
実験3では、通信開始時のARPの応答を wlan0 で返すようにできないか、試してみることにします。
(実は結論としては、2015-02-25現在、管理人の力量では「実現できておりません」
惜しいところまで行ってると思うんだけど・・orz)

具体的には、実験1,2での下記の部分:

15:16:25.851843 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:16:25.853188 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46

これが下記:

15:16:25.851843 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:16:25.853188 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 46

のようにならないかな~、ということです。

いろいろとあさってみた結果、arptables というパッケージがあり、なんか使えそうな雰囲気なので、
さっそくやってみます。(iptables の ARP版というものらしいです。何しろ日本語の情報が少なくて・・・)

準備

まずはマシンAの設定。
実験2の設定を一旦ご破算にします。

root@Machine-A # ip route del default table 100
root@Machine-A # ip rule del table 100

arptableパッケージのインストール。デフォルトではインストールされていませんので。

root@Machine-A # apt-get install arptables

さらに、arptables のコマンドで下記のようなものを走らせます。

root@Machine-A # arptables -F
root@Machine-A # arptables -A OUTPUT -s 192.168.1.21 -j mangle -l 6 --mangle-mac-s 11:11:11:11:11:11
root@Machine-A # arptables -A OUTPUT -s 192.168.1.51 -j mangle -l 6 --mangle-mac-s 22:22:22:22:22:22

マシンBのARPテーブルからIPアドレスを削除しておきます。

root@Machine-B # arp -d 192.168.1.21
root@Machine-B # arp -d 192.168.1.51

これで準備完了です。

pingによる確認

実験2と同様、マシンBからマシンAに向けて ping コマンドを発行し、ARP,ICMP echo(=ping)の実行結果を確認します。

マシンB:ping

root@Machine-B # ping -c 1 192.168.1.51
PING 192.168.1.51 (192.168.1.51) 56(84) bytes of data.
64 bytes from 192.168.1.51: icmp_req=1 ttl=64 time=103 ms

--- 192.168.1.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 103.255/103.255/103.255/0.000 ms

マシンB:tcpdump

root@Machine-B # tcpdump -i br0 -n -e arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on br0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:52:08.702370 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
16:52:08.703887 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 46
16:52:08.704138 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7794, seq 1, length 64
16:52:08.805478 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7794, seq 1, length 64

マシンB:ping後のARPテーブル

root@Machine-B # arp -n
アドレス               HWタイプ  HWアドレス         フラグ マスク インタフェース
192.168.1.51             ether   22:22:22:22:22:22   C                     br0
192.168.1.21                     (不完全)                               br0

マシンA:tcpdump(インターフェース eth0)

root@Machine-A # tcpdump -n -e -i eth0 arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:52:08.706401 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.51 tell 192.168.1.20, length 46
16:52:08.706702 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 42: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 28
16:52:08.708073 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7794, seq 1, length 64
16:52:08.808324 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 7794, seq 1, length 64
(以下の2行は不明。いつもセットで出力される。今後の課題)
16:52:10.936947 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.21 tell 192.168.1.20, length 46
16:52:10.937261 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 42: Reply 192.168.1.21 is-at 11:11:11:11:11:11, length 28

マシンA:tcpdump(インターフェース wlan0)

root@Machine-A # tcpdump -n -e -i wlan0 arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:52:08.807998 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7794, seq 1, length 64

実験3の結果のまとめ

マシンBからのARP発行の部分を実験2と比較してみます。 実験2:マシンBのtcpdump

15:16:25.851843 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
15:16:25.853188 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 11:11:11:11:11:11, length 46

実験3:マシンBのtcpdump

16:52:08.702370 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
16:52:08.703887 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 46

IPアドレス 192.168.1.51 に対するMACアドレスのマシンAからの回答として、

  • 実験2 では 11:11:11:11:11:11
  • 実験3 では 22:22:22:22:22:22 となっており、一見正しい回答を送信しているようですが、マシンAのパケット送信元MACアドレスが
    11:11:11:11:11:11 すなわち インターフェ-ス eth0 からの送信となっており、今一つの結果となりました。
    (管理人的にはここで手詰まりとなってしまいました。)

一方、ARPによりMACアドレスを取得したマシンBは、ICMP echo(=ping)を発行するのに、宛先MACアドレスとして
22:22:22:22:22:22 を使っているため、マシンBへは正しいMACアドレスが伝達できたことになります。

また、マシンA側でのICMP echo(=ping)パケット受信部分で怪しい部分があります。
マシンAのインターフェース eth0 と wlan0 で同じパケットを受信したような出力があり(下記)、
謎であります(^^;)。
マシンAのeth0

16:52:10.936947 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.21 tell 192.168.1.20, length 46

マシンAのwlan0

16:52:08.807998 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 7794, seq 1, length 64

マシンAからBへのICMP echo応答を返す部分は、実験2のルーティングをクリアしたので、まあこのログの通りの動作です。

16:52:10.937261 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 42: Reply 192.168.1.21 is-at 11:11:11:11:11:11, length 28

結局、ARPの初回応答をマシンAのwlan0からやりたーい、という野望は2015-03-02現在、達成できておりません。

実験4:実験2と実験3の組み合わせ

すでに100%うまくはいかないことは分かっているのでテンションかなり下がっていますが、実験2と3の組み合わせ技で、
一応試しておきます。

準備

マシンAのルーティングに対して下記のルールを追加します(実験2より)。

root@Machine-A # ip rule add from 192.168.1.51 table 100 prio 200
root@Machine-A # ip route add dev wlan0 src 192.168.1.51 table 100

さらに、マシンAにて rptables のコマンドで下記を走らせます(実験3より)。

root@Machine-A # arptables -F
root@Machine-A # arptables -A OUTPUT -s 192.168.1.21 -j mangle -l 6 --mangle-mac-s 11:11:11:11:11:11
root@Machine-A # arptables -A OUTPUT -s 192.168.1.51 -j mangle -l 6 --mangle-mac-s 22:22:22:22:22:22

マシンBのARPテーブルからIPアドレスを削除します(実験2,3共通)。

root@Machine-B # arp -d 192.168.1.21
root@Machine-B # arp -d 192.168.1.51

準備完了です。

pingによる確認

マシンBからマシンAに向けて ping コマンドを発行し、ARP,ICMP echo(=ping)の実行結果を確認します。

マシンB:ping

root@Machine-B # ping -c 1 192.168.1.51
PING 192.168.1.51 (192.168.1.51) 56(84) bytes of data.
64 bytes from 192.168.1.51: icmp_req=1 ttl=64 time=124 ms

--- 192.168.1.51 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 124.918/124.918/124.918/0.000 ms

マシンB:tcpdump

11:33:53.753791 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.51 tell 192.168.1.20, length 28
11:33:53.755293 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 60: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 46
11:33:53.755544 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800),length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 11123, seq 1, length 64
※a(11:33:53.875123 22:22:22:22:22:22 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.20 tell 192.168.1.51, length 46)
※b(11:33:53.875418 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype ARP (0x0806), length 42: Reply 192.168.1.20 is-at 99:99:99:99:99:99, length 28)
11:33:53.878559 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 11123, seq 1, length 64

マシンB:ping後のARPテーブル

root@Machine-B # arp -n
アドレス               HWタイプ  HWアドレス         フラグ マスク インタフェース
192.168.1.51             ether   22:22:22:22:22:22   C                     br0
192.168.1.21             ether   11:11:11:11:11:11   C                     br0

マシンA:tcpdump(インターフェース eth0)

11:33:53.755356 99:99:99:99:99:99 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.51 tell 192.168.1.20, length 46
11:33:53.755701 11:11:11:11:11:11 > 99:99:99:99:99:99, ethertype ARP (0x0806), length 42: Reply 192.168.1.51 is-at 22:22:22:22:22:22, length 28
11:33:53.757107 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 11123, seq 1, length 64
※c(11:33:53.876152 22:22:22:22:22:22 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 60: Request who-has 192.168.1.20 tell 192.168.1.51, length 46)

マシンA:tcpdump(インターフェース wlan0)

root@Machine-A # tcpdump -n -e -i wlan0 arp or icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:33:53.873355 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 11123, seq 1, length 64
※d(11:33:53.873745 22:22:22:22:22:22 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 192.168.1.20 tell 192.168.1.51, length 28)
※e(11:33:53.877781 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype ARP (0x0806), length 60: Reply 192.168.1.20 is-at 99:99:99:99:99:99, length 46)
11:33:53.878038 22:22:22:22:22:22 > 99:99:99:99:99:99, ethertype IPv4 (0x0800), length 98: 192.168.1.51 > 192.168.1.20: ICMP echo reply, id 11123, seq 1, length 64

上記の※a~eは、なぜかICMP echo request ~ reply の間にマシンAのwlan0から、192.168.1.20を持つ
MACアドレスを調べるためのARPがブロードキャストされています。

実験4の結果のまとめ

事象だけ追っかけるとおおよそ以下のようになりました。(テンション低いっす:-)

  1. マシンBの br0インターフェース(MACアドレス99:99:99:99:99:99)から、192.168.1.51 を誰が持っているかの
    問い合わせをARPでブロードキャスト。
  2. それに対して、マシンAの eth0インターフェース(MACアドレス11:11:11:11:11:11)が、
    「192.168.1.51を持っているのはMACアドレス22:22:22:22:22:22である」と回答。
    ここは本来、eth0(=11:11:11:11:11:11)ではなくwlan0(=22:22:22:22:22:22)から回答を送りたいところではありますが、
    やり方がわかりませんでした。
  3. マシンBの br0インターフェースから、MACアドレス22:22:22:22:22:22に対して、ICMP echo(=ping)を発行。
  4. マシンAの wlan0インターフェース(MACアドレス22:22:22:22:22:22)が、ICMP echo への応答を、
    マシンBの br0インターフェース(MACアドレス99:99:99:99:99:99)へ返す。

不可解なのは、マシンAの tcpdump の出力において、マシンBからのICMP echoリクエスト(下記の行)が
eth0 と wlan0 の両方に出力されていることです。

11:33:53.757107 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 11123, seq 1, length 64
11:33:53.873355 99:99:99:99:99:99 > 22:22:22:22:22:22, ethertype IPv4 (0x0800), length 98: 192.168.1.20 > 192.168.1.51: ICMP echo request, id 11123, seq 1, length 64

理由はよくわかりません。

それと、※a~eは、なぜかICMP echo request ~ reply の間にマシンAのwlan0から、192.168.1.20を持つMACアドレスを
調べるためのARPがブロードキャストされています。何かのつじつま合わせなのかもしれません。
ここでも、※cとdが重複していて、※cに記載のMACアドレスがwlan0のもの(=22:22:22:22:22:22)なのが不思議です。

まとめ

ネットワークカードを2枚挿し、それぞれに同一ネットワークアドレスの別IPアドレスを持たせる、という
変態的なことをやってみました。
実験4の設定をすれば、初回通信時はともかく、その後はまあ正常に通信できるようです。

ネットワーク設定ファイルの紹介(/etc/network/interfaces)

ネットワークの設定ファイルは最終的に下記のようになりました。
ただし、これは完全回答ではありませんので、ご参考程度にご覧ください。

$ cat /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.21
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1

#auto wlan0
iface wlan0 inet static
address 192.168.1.51
netmask 255.255.255.0
network 192.168.1.0
post-up arptables -A OUTPUT -s 192.168.1.21 -j mangle -l 6 --mangle-mac-s 11:11:11:11:11:11
post-up arptables -A OUTPUT -s 192.168.1.51 -j mangle -l 6 --mangle-mac-s 22:22:22:22:22:22
post-up ip rule add from 192.168.1.51 table 100 prio 2000
post-up ip route add dev wlan0 src 192.168.1.51 table 100
##########
# do not use following one line!! delete automatically when ifdown wlan0.
# post-down ip route del dev wlan0 src 192.168.1.51 table 100
##########
post-down ip rule del table 100 prio 2000
post-down arptables -D OUTPUT -s 192.168.1.21 -j mangle -l 6 --mangle-mac-s 11:11:11:11:11:11
post-down arptables -D OUTPUT -s 192.168.1.51 -j mangle -l 6 --mangle-mac-s 22:22:22:22:22:22
broadcast 192.168.1.255
#gateway 192.168.1.1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

簡単に解説しますと・・・

  • #auto wlan0 のコメントを有効化すると、OSブート時に自動でwlan0が起動します。
  • arptablesコマンドは、arptablesパッケージのインストールが必要です(apt-getで一発!!)。
  • # post-down ip route del dev wlan0 src 192.168.1.51 table 100 は指定しないこと。
    wlan0がシャットダウンすると、これは自動的に解除になるようです。
    その後、再度interfacesで明示的に実行しようとするとエラーとなり、ifdownスクリプトの実行が
    途中終了してしまうためです。

つぶやき:上記設定で tcpdump 見てると、なんだか余計なARPが発生したりしているような・・・謎。

終わりに

この実験はひとまずこれで終了ということにしますが、時間があればもう少し上記の問題点(wlan0についての
問い合わせの回答をeth0から返してしまう)をつついてみたいと思います。
(ん~多分やんないだろうな)。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-04-02 (月) 15:44:24 (109d)