ARPテーブルを探求する [ColdFire V2]
そろそろ、複数の付録基板同士で通信をさせてみたくなりました。 付録基板もネットワーク機器としての当然の機能としてARP (Address Resolution Protocol) テーブルを持っています。 ちょっと、のぞいてみましょう。
ARPテーブル表示プログラム
ARPテーブルは、0x20000440番地から6エントリ分あります。 もちろん、ダンプ・リストで見ることもできますが、せっかくだから表示させるプログラムを作りました。
show(){ long i, j, *plong; char *p; p=0x20000440; for(i=0;i<6;i++,p+=16){ if (p[0]==0) continue; plong=p+12; PrAdrs(*plong);PrStr(" "); for(j=0;j<6;j++){ if(j>0) PrChar('-'); PrHexByte(p[j+4]); } PrStr("\r\n"); } }
これを"arp"という名前のファイルとして保存して使います。
OK arp::show 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.2 00-15-c5-5b-**-38 OK
桁そろえ関数は、装備されていないんだよな。
複数のホストにUDPパケットを送るプログラム
ここからが、本日の本題です。 一枚の付録基板から複数の付録基板およびPCにUDPパケットを送ります。 ひとつのプログラムで送り先の数を可変できるようにプログラムを工夫してみました。
main(int n){ arp::show(); PrStr("\r\n"); switch(n){ case 7: send("192.168.1.10"); case 6: send("192.168.1.102"); case 5: send("192.168.1.103"); case 4: send("192.168.1.104"); case 3: send("192.168.1.105"); case 2: send("192.168.1.106"); default: send("192.168.1.2"); } PrStr("\r\n"); arp::show(); } send(char *host){ char soc, err_code; long ip; soc=CreateSocket(0); ip=GetHostByName(host); err_code=SendTo(soc, ip, 30049, host, StrLen(host)+1); CloseSocket(soc); PrStr(host);PrStr(" : err_code="); PrNum(err_code);PrStr("\r\n"); }
最後のIPアドレス以外は、すべて付録基板です。 受け側のポートは開いていないので、送りっぱなしになります。
6個のホストにパケットを送る
自分自身(192.168.1.106)も含めて、6個のホストに対してパケットを送ります。
Main::main(6) 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.102 : err_code=0 192.168.1.103 : err_code=0 192.168.1.104 : err_code=0 192.168.1.105 : err_code=0 192.168.1.106 : err_code=22 192.168.1.2 : err_code=0 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.102 ff-ff-ff-ff-ff-ff 192.168.1.103 00-1f-e8-49-**-79 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.2 00-15-c5-5b-**-38 OK
最初は、ARPテーブルには、自分自身だけが登録されてるので、その他のホストに対してはARP要求だけが発信されます。 このため、これらのホストについては、"err_code=0"が返されます。 パケット送信後は、ほとんどのホストのMACアドレスについては解決していますが、"192.168.1.102"だけは応答が返ってきていないらしく、暫定値ff-ff-ff-ff-ff-ffが入っています。 パケット・モニタで見ると、こうなりました。
#1 0.000000 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.103? Tell 192.168.1.106 #2 0.000017 Kurusuga_49:**:79 Kurusuga_49:**:d4 ARP 192.168.1.103 is at 00:1f:e8:49:**:79 #3 0.013762 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.104? Tell 192.168.1.106 #4 0.013820 Kurusuga_49:**:e8 Kurusuga_49:**:d4 ARP 192.168.1.104 is at 00:1f:e8:49:**:e8 #5 0.027552 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.105? Tell 192.168.1.106 #6 0.027649 Kurusuga_49:**:bf Kurusuga_49:**:d4 ARP 192.168.1.105 is at 00:1f:e8:49:**:bf #7 0.041418 192.168.1.106 192.168.1.106 UDP Source port: 1024 Destination port: 30049 #8 0.055215 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.2? Tell 192.168.1.106 #9 0.055231 Dell_5b:**:38 Kurusuga_49:**:d4 ARP 192.168.1.2 is at 00:15:c5:5b:**:38 #10 2.157876 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.102? Tell 192.168.1.106 #11 2.157917 Kurusuga_49:**:76 Kurusuga_49:**:d4 ARP 192.168.1.102 is at 00:1f:e8:49:**:76
プログラム上、"192.168.1.102"が一番にパケットの送信を要求したはずなのですが、これを見るとARP要求は後回しにされちゃったのですね。
Main::main(6) 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.102 00-1f-e8-49-**-76 192.168.1.103 00-1f-e8-49-**-79 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.2 00-15-c5-5b-**-38 192.168.1.102 : err_code=22 192.168.1.103 : err_code=22 192.168.1.104 : err_code=22 192.168.1.105 : err_code=22 192.168.1.106 : err_code=22 192.168.1.2 : err_code=20 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.102 00-1f-e8-49-**-76 192.168.1.103 00-1f-e8-49-**-79 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.2 00-15-c5-5b-**-38 OK
二回目の実行は、全てのホストのMACアドレスが解決しているので、すんなりと実行されます。
#12 11.107054 192.168.1.106 192.168.1.102 UDP Source port: 1024 Destination port: 30049 #13 11.120758 192.168.1.106 192.168.1.103 UDP Source port: 1024 Destination port: 30049 #14 11.134493 192.168.1.106 192.168.1.104 UDP Source port: 1024 Destination port: 30049 #15 11.148224 192.168.1.106 192.168.1.105 UDP Source port: 1024 Destination port: 30049 #16 11.162056 192.168.1.106 192.168.1.106 UDP Source port: 1024 Destination port: 30049 #17 11.175863 192.168.1.106 192.168.1.2 UDP Source port: 1024 Destination port: 30049
パケットの送受信もきれいです。 三回目の実行も同様でしたので、ここでは省略します。
7個のホストにパケットを送る
さらにホストの数を7個に増やします。
Main::main(7) 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.102 00-1f-e8-49-**-76 192.168.1.103 00-1f-e8-49-**-79 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.2 00-15-c5-5b-**-38 192.168.1.10 : err_code=0 192.168.1.102 : err_code=22 192.168.1.103 : err_code=0 192.168.1.104 : err_code=0 192.168.1.105 : err_code=0 192.168.1.106 : err_code=22 192.168.1.2 : err_code=20 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.103 00-1f-e8-49-**-79 192.168.1.10 00-1f-e8-49-**-2d 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.2 00-15-c5-5b-**-38 OK
7個中4個について失敗したという実行結果ですが、実際にはそれだけではありません。 "192.168.1.10"への送信時に長時間待たされてしまいました。
#24 61.166842 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.2? Tell 192.168.1.106 #25 61.166860 Dell_5b:**:38 Kurusuga_49:**:d4 ARP 192.168.1.2 is at 00:15:c5:5b:**:38 #26 61.166874 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.10? Tell 192.168.1.106 #27 61.166935 Kurusuga_49:**:2d Kurusuga_49:**:d4 ARP 192.168.1.10 is at 00:1f:e8:49:**:2d #28 61.180441 192.168.1.106 192.168.1.102 UDP Source port: 1024 Destination port: 30049 #29 61.194215 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.103? Tell 192.168.1.106 #30 61.194231 Kurusuga_49:**:79 Kurusuga_49:**:d4 ARP 192.168.1.103 is at 00:1f:e8:49:**:79 #31 61.208001 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.104? Tell 192.168.1.106 #32 61.208016 Kurusuga_49:**:e8 Kurusuga_49:**:d4 ARP 192.168.1.104 is at 00:1f:e8:49:**:e8 #33 64.167279 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.105? Tell 192.168.1.106 #34 64.167296 Kurusuga_49:**:bf Kurusuga_49:**:d4 ARP 192.168.1.105 is at 00:1f:e8:49:**:bf #35 64.181126 192.168.1.106 192.168.1.106 UDP Source port: 1024 Destination port: 30049 #36 64.194973 192.168.1.106 192.168.1.2 UDP Source port: 1024 Destination port: 30049
パケット・モニタで見ると原因が分かりました。 ARP要求が発行されずに待ち時間が発生したようです。 どうやら、ARPテーブルに空きが無くなった場合、古いエントリを削除するのではなく、いずれかのエントリが時間切れになるのを待っているようです。 有効期限は実験的に60秒と判断しました。
Main::main(7) 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.103 00-1f-e8-49-**-79 192.168.1.10 00-1f-e8-49-**-2d 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.2 00-15-c5-5b-**-38 192.168.1.10 : err_code=21 192.168.1.102 : err_code=0 192.168.1.103 : err_code=0 192.168.1.104 : err_code=0 192.168.1.105 : err_code=22 192.168.1.106 : err_code=22 192.168.1.2 : err_code=20 192.168.1.106 00-1f-e8-49-**-d4 192.168.1.105 00-1f-e8-49-**-bf 192.168.1.103 00-1f-e8-49-**-79 192.168.1.102 ff-ff-ff-ff-ff-ff 192.168.1.104 00-1f-e8-49-**-e8 192.168.1.2 00-15-c5-5b-**-38
二回目の実行でも待ち時間が発生しました。
#37 81.911598 192.168.1.106 192.168.1.10 UDP Source port: 1024 Destination port: 30049 #38 122.175817 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.2? Tell 192.168.1.106 #39 122.175834 Dell_5b:**:38 Kurusuga_49:**:d4 ARP 192.168.1.2 is at 00:15:c5:5b:**:38 #40 122.175848 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.102? Tell 192.168.1.106 #41 122.175957 Kurusuga_49:**:76 Kurusuga_49:**:d4 ARP 192.168.1.102 is at 00:1f:e8:49:**:76 #42 122.189641 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.103? Tell 192.168.1.106 #43 122.189730 Kurusuga_49:**:79 Kurusuga_49:**:d4 ARP 192.168.1.103 is at 00:1f:e8:49:**:79 #44 122.203479 Kurusuga_49:**:d4 Broadcast ARP Who has 192.168.1.104? Tell 192.168.1.106 #45 122.203496 Kurusuga_49:**:e8 Kurusuga_49:**:d4 ARP 192.168.1.104 is at 00:1f:e8:49:**:e8 #46 122.217283 192.168.1.106 192.168.1.105 UDP Source port: 1024 Destination port: 30049 #47 122.231076 192.168.1.106 192.168.1.106 UDP Source port: 1024 Destination port: 30049 #48 122.244911 192.168.1.106 192.168.1.2 UDP Source port: 1024 Destination port: 30049
#38のARP要求がいずれかのエントリ(この場合は、192.168.1.10)が時間切れになるまで待たされたようです。
本日の考察
- 付録基板のARPテーブル長は、自身も含めて6エントリである。
- ARPテーブルが足りなくなったら、いずれかのエントリの有効期限が切れて欠員が出るまで待つ。
いわゆる"arp"コマンドのように、SilentCから積極的にARPテーブルを操作することは、できないようです。 私が考える最終形態は、付録基板7枚とPCという構成だから、6エントリじゃ足りません。 ネットワークを工夫するしかないかな。
参考文献
Interface (インターフェース) 2008年 09月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2008/07/25
- メディア: 雑誌
とにかく現状でUDPで7台以上通信するならば、現在ブロードバンドルーターに繋がっているネットワークの中に、中古で良いのでもう一台ルーターを追加して新しくネットワークを作り、そっちに幾つかの付録基板を移すとか。
それでブロードバンドルーターのルーティングテーブルを編集して、付録基板がもう一つのネットワーク向けのパケットを送って来たら、追加したルーターに向けて流す!と。
これでARPテーブルの不足は解決ですね、、、するかな?。
by hamayan (2008-10-08 22:51)
まだ、試してはいないのですが、ルータの向こう側の自ネットワーク外へのパケットであれば、ARPテーブルは消費しないはずですよね。まさか、ARPテーブルにルータのMACアドレスを書き込んだりはしないですよね。
リピータハブに親ルータ一台のLAN側、子ルータ二台のWAN側、PC一台をつないで、子ルータのLAN側に付録基板を3枚と4枚に分けてつなげば、ネットワークの分離が出来ますね。独立ネットワークにするなら、親ルータは必要ないか。
すると、子ルータは、サブネットワークにしなきゃいけないから、ネットワークマスクも別々に設定して、デフォルトルータも個別に設定して、えらく大変じゃあありませんか。
いまや、ルータも3000円なので、新品を買っちゃってもいいとは思いますが、いったい、私は何を作っているんだろう。
by noritan (2008-10-09 08:43)
> まさか、ARPテーブルにルータのMACアドレスを書き込んだりはしないですよね。
ここは微妙だと思います。少なくともルーターのMACアドレスをテーブルに追加はする筈です。
問題は、別ネットワークのデバイスのIPアドレスと、ルーターのMACアドレスを対にして、やはりARPテーブルに保存する可能性が有ります。
ちなみにNavajoではそうしていますから。
別のネットワークグループのIPアドレスなので、ARPテーブルに頼らず、自動的にデフォルトゲートウエイに飛ばす様なロジックなら、ARPテーブルを消費しない可能性が有ります。
うーん、実際のところ判りません。あそこにお問い合わせをするのが一番の
様な。
> いまや、ルータも3000円なので
Genoだと1499円から新品で!。
> 私は何を作っているんだろう。
すでにネットワークの深淵に引きずり込まれています。もう自分が納得行く所まで行かないと、逃げられませんです(笑)。
by hamayan (2008-10-09 09:09)
http://www.geno-web.jp/
中古パソコンとパソコンパーツの通販ショップGENO
まずは、ルータで解決するかを確認せねば。
今、思いついたこと。
ARPテーブルに空きが無い状態で、ARPテーブルに登録されていないノードから話しかけられたら、どう応答するんだろう?
1) ARPテーブル・エントリの有効期限が切れて欠員が出るまで、パケットの受信(RecvFrom関数またはAccept関数)はブロックされる。
2) 知らない人に声をかけられたので、無視する。
3) パケットの受信には、ARPテーブルの登録を必要としない。
TCP通信であれば、いずれARPエントリを埋めなきゃいけないので、外部から攻撃を受けたら、ひとたまりもありませんね。
by noritan (2008-10-09 12:02)