古澤です。梅本さん、何度も丁寧に説明してくださって、ありがとうございました。

私が疑問を持ったことの解答は、

> gethostbyaddr() 自体が呼ばれなくなります。つまり、どちらも参照していま
> せん。

この事で説明できる訳ですね。
[FreeBSD-users-jp 92839] で arp.c の一部を示しましたが、

>   576                 if (h_errno == TRY_AGAIN)
>   577                         nflag = 1;

/etc/hosts も駄目、DNS でも引けない時に、577行目が実行され、
それ以降のエントリについては、

>   567         if (nflag == 0)
>   568                 hp = gethostbyaddr((caddr_t)&(addr->sin_addr),
>   569                     sizeof addr->sin_addr, AF_INET);

この 567行目によって、gethostbyaddr() を呼びに行かなくなるのだと
理解しました。

該当するソースを見ていた筈なのに、
gethostbyaddr() が呼ばれると思い込んでいたため、
認識が誤ってしまいました。

コマンドラインからは「arp -a」として実行しましたが、
DNS で引けないときに、あたかも「arp -an」として起動した動作に
切り替わってしまうという事ですね。

ただし、これは *今回私が指定していたDNSサーバ* に
限った現象なのだろうと思います。
それは DNSサーバが NXDOMAIN ではなく SERVFAIL を返すからです。

> PTR レコードがない IP アドレスを nslookup で引いたときにどのように出力
> されますか?

これについては、以下の結果を得ました。

% nslookup 192.168.1.221
nslookup 192.168.1.221
Server:         192.168.1.1
Address:        192.168.1.1#53

** server can't find 221.1.168.192.in-addr.arpa: SERVFAIL

確かに SERVFAIL が返ってきています。

試しに DNS サーバを変えてみました。
これは私が利用している ISP が BIGLOBE なので、
そこで公開されているものです。

% nslookup 192.168.1.221 210.147.235.3
nslookup 192.168.1.221 210.147.235.3
Server:         210.147.235.3
Address:        210.147.235.3#53

** server can't find 221.1.168.192.in-addr.arpa.: NXDOMAIN

こちらでは NXDOMAIN が返ってきました。

私が指定している DNS サーバの動作が怪しいことが分かりましたが、
これは ADSL 回線の契約でレンタルしている機器に組み込まれており、
ちょっと手を出すことができません。
どのように対応するかは、これから考えたいと思います。

ともかく状況が明瞭になりましたので、どうするかを検討します。
いろいろとご指導くださいまして、ありがとうございました。

最後に、今回のロジックについて NetBSD の場合の話題がありましたので、
参考までに、他の OS での該当箇所を示しておきます。

OpenBSD の場合、確認したソースは以下のとおりです。
$OpenBSD: arp.c,v 1.49 2009/09/27 12:07:15 deraadt Exp $ */

   477          if (hp)
   478                  host = hp->h_name;
   479          else {
   480                  host = "?";
   481                  if (h_errno == TRY_AGAIN)
   482                          nflag = 1;
   483          }

こちらは FreeBSD と同じです。

NetBSD の場合、確認したソースは以下のとおりです。
$NetBSD: arp.c,v 1.48 2009/04/02 21:02:06 christos Exp $

   451                  host = hp ? hp->h_name : "?";

この行だけしかありませんので、シンプルですね。
元々は NetBSD も FreeBSD と同じだったとの事ですので、
NetBSD だけがオリジナルの BSD のロジックを変更しているのだと認識しました。
-- 
FURUSAWA Kazumi <kaz...@mse.biglobe.ne.jp>

メールによる返信