古澤です。お返事ありがとうございました。

> > 自宅でFreeBSD 8.0を使っています。 そのLANで arp(8) を使うと、以下のような結果になります。
> > ホスト名が「!」になってしまっています。
> 「?」の間違いではないでしょうか? arp.cには「!」を出すようなコー
> ドはないように見えます。

申し訳ありません。おっしゃるとおりです。
試行錯誤している最中に、動作を確認するために入れた変更を戻すのを
忘れたまま、結果を提示してしまいました。

ソースが更新されたようですが、私が調べていたときのバージョンは
以下の通りです。

$FreeBSD: src/usr.sbin/arp/arp.c,v 1.71.2.4 2010/01/12 18:47:40 jhb Exp $

IPアドレスからホスト名を求め、表示するロジックは次のようになっていました。

   567          if (nflag == 0)
   568                  hp = gethostbyaddr((caddr_t)&(addr->sin_addr),
   569                      sizeof addr->sin_addr, AF_INET);
   570          else
   571                  hp = 0;
   572          if (hp)
   573                  host = hp->h_name;
   574          else {
   575                  host = "?";
   576                  if (h_errno == TRY_AGAIN)
   577                          nflag = 1;
   578          }
   579          printf("%s (%s) at ", host, inet_ntoa(addr->sin_addr));

これに対して以下の変更を加えておりました。

diff -u arp.c.orig arp.c
--- arp.c.orig  2010-02-23 18:17:58.000000000 +0900
+++ arp.c       2010-02-23 18:19:04.000000000 +0900
@@ -573,8 +573,10 @@
                host = hp->h_name;
        else {
                host = "?";
-               if (h_errno == TRY_AGAIN)
+               if (h_errno == TRY_AGAIN) {
+                       host = "!";
                        nflag = 1;
+               }
        }
        printf("%s (%s) at ", host, inet_ntoa(addr->sin_addr));
        if (sdl->sdl_alen) {

[FreeBSD-users-jp 92835] で書いた「!」というのは「?」の誤りですので、
お詫びして訂正します。

このロジックを見て、
(1) gethostbyaddr()でホスト名を取得
(2) ホスト名を得られなければ「?」とする
(3) エントリを出力し、他のエントリのために(1)以降を繰り返す
だと考えました。

> resolv.conf の設定より、192.168.1.1 が DNS サーバのようですが、
> この DNS サーバは正しく返事を返すのでしょうか?

LAN の中のホストは数台なので /etc/hosts だけで管理しています。
/etc/nsswitch.conf では「hosts: files dns」としてあるので、
LAN 内のマシンについては /etc/hosts の段階で解決できるだろうと期待しています。

ただ 192.168.1.1 については、以下のような返事をします。

% nslookup 192.168.1.1
Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
1.1.168.192.in-addr.arpa        name = modemnv3-5b1294.

Authoritative answers can be found from:

先のメールで示した arp -a の表示結果では「adsl」というホスト名になっていて、
これは /etc/hosts で指定している名前です。

同様に他のホスト名も出ると期待したら「?」になってしまったというのが
疑問の発端です。

/etc/hosts に指定が無く、DNS でもホスト名が引けない場合、
つまり先のメールにおける 192.168.1.26 などの場合には結果が
「?」になってしまう事はわかります。

arp(8) の動作として各行を表示して行くとき、前後に依存性は無く、
それぞれの行が独立して、ホスト名が得られるか否かだと考えておりました。

従って、先のメールで示した表示結果を再掲すると、

> % arp -a
> adsl (192.168.1.1) at 00:0d:02:5b:12:94 on rl0 [ethernet]
> ! (192.168.1.26) at 00:19:d2:52:d7:07 on rl0 [ethernet]
> ! (192.168.1.221) at 00:0a:79:d1:29:4b on rl0 permanent [ethernet]
> ! (192.168.1.255) at (incomplete) on rl0 [ethernet]
> ! (192.168.1.241) at 08:00:2b:25:2d:52 on rl0 [ethernet]

ここで 192.168.1.26 のホスト名が出ないのは仕方ありませんが、
それ以外は /etc/hosts に書いてあるのに、
なぜ出て来ないのだろうと思ったのです。

この例なら、
192.168.1.1 は、/etc/hosts の段階でホスト名が取得できた
192.168.1.26 は、/etc/hosts を見ても取得できないので DNS を参照したが
それでも駄目だった
と、動作するのだろうと思います。

そして次の 192.168.1.221 は、/etc/hosts に書いてあるので
ホスト名が取得できる筈なのですが、それを使わずに DNS を見に行ってしまいます。

テスト的に作ったプログラムで gethostbyaddr("192.168.1.221") を試すと
/etc/hosts で指定したホスト名を返すので、
そこに問題は無いだろうと思っているのですが・・・

私の考えた道筋は上述したとおりですが、
何か思い違いをしている箇所や、考慮の不足している点が
あるんじゃないかと思います。

どなたかお気づきの方がいらっしゃいましたら、
ご指摘をお願いします。
-- 
FURUSAWA Kazumi <kaz...@mse.biglobe.ne.jp>

メールによる返信