SSブログ

ARPテーブルを探求する [ColdFire V2]このエントリーを含むはてなブックマーク#

2047506

そろそろ、複数の付録基板同士で通信をさせてみたくなりました。 付録基板もネットワーク機器としての当然の機能として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)が時間切れになるまで待たされたようです。

本日の考察

  1. 付録基板のARPテーブル長は、自身も含めて6エントリである。
  2. ARPテーブルが足りなくなったら、いずれかのエントリの有効期限が切れて欠員が出るまで待つ。

いわゆる"arp"コマンドのように、SilentCから積極的にARPテーブルを操作することは、できないようです。 私が考える最終形態は、付録基板7枚とPCという構成だから、6エントリじゃ足りません。 ネットワークを工夫するしかないかな。

参考文献

Interface (インターフェース) 2008年 09月号 [雑誌]

Interface (インターフェース) 2008年 09月号 [雑誌]

  • 作者:
  • 出版社/メーカー: CQ出版
  • 発売日: 2008/07/25
  • メディア: 雑誌

nice!(0)  コメント(4)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 4

hamayan

とにかく現状でUDPで7台以上通信するならば、現在ブロードバンドルーターに繋がっているネットワークの中に、中古で良いのでもう一台ルーターを追加して新しくネットワークを作り、そっちに幾つかの付録基板を移すとか。

それでブロードバンドルーターのルーティングテーブルを編集して、付録基板がもう一つのネットワーク向けのパケットを送って来たら、追加したルーターに向けて流す!と。

これでARPテーブルの不足は解決ですね、、、するかな?。

by hamayan (2008-10-08 22:51) 

noritan

まだ、試してはいないのですが、ルータの向こう側の自ネットワーク外へのパケットであれば、ARPテーブルは消費しないはずですよね。まさか、ARPテーブルにルータのMACアドレスを書き込んだりはしないですよね。

リピータハブに親ルータ一台のLAN側、子ルータ二台のWAN側、PC一台をつないで、子ルータのLAN側に付録基板を3枚と4枚に分けてつなげば、ネットワークの分離が出来ますね。独立ネットワークにするなら、親ルータは必要ないか。

すると、子ルータは、サブネットワークにしなきゃいけないから、ネットワークマスクも別々に設定して、デフォルトルータも個別に設定して、えらく大変じゃあありませんか。

いまや、ルータも3000円なので、新品を買っちゃってもいいとは思いますが、いったい、私は何を作っているんだろう。

by noritan (2008-10-09 08:43) 

hamayan

> まさか、ARPテーブルにルータのMACアドレスを書き込んだりはしないですよね。

ここは微妙だと思います。少なくともルーターのMACアドレスをテーブルに追加はする筈です。
問題は、別ネットワークのデバイスのIPアドレスと、ルーターのMACアドレスを対にして、やはりARPテーブルに保存する可能性が有ります。
ちなみにNavajoではそうしていますから。

別のネットワークグループのIPアドレスなので、ARPテーブルに頼らず、自動的にデフォルトゲートウエイに飛ばす様なロジックなら、ARPテーブルを消費しない可能性が有ります。

うーん、実際のところ判りません。あそこにお問い合わせをするのが一番の
様な。

> いまや、ルータも3000円なので

Genoだと1499円から新品で!。

> 私は何を作っているんだろう。

すでにネットワークの深淵に引きずり込まれています。もう自分が納得行く所まで行かないと、逃げられませんです(笑)。
by hamayan (2008-10-09 09:09) 

noritan

http://www.geno-web.jp/
中古パソコンとパソコンパーツの通販ショップGENO

まずは、ルータで解決するかを確認せねば。


今、思いついたこと。
ARPテーブルに空きが無い状態で、ARPテーブルに登録されていないノードから話しかけられたら、どう応答するんだろう?

1) ARPテーブル・エントリの有効期限が切れて欠員が出るまで、パケットの受信(RecvFrom関数またはAccept関数)はブロックされる。
2) 知らない人に声をかけられたので、無視する。
3) パケットの受信には、ARPテーブルの登録を必要としない。

TCP通信であれば、いずれARPエントリを埋めなきゃいけないので、外部から攻撃を受けたら、ひとたまりもありませんね。

by noritan (2008-10-09 12:02) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。