EN JA
GETNAMEINFO(3)
GETNAMEINFO(3) FreeBSD Library Functions Manual GETNAMEINFO(3)

名称

getnameinfoホスト名とサービス名へのソケットアドレス構造体

書式

#include < sys/types.h>
#include < sys/socket.h>
#include < netdb.h>

int
getnameinfo( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);

解説

getnameinfo() 関数は、 sockaddr 構造体を 1 組のホスト名とサービス文字列に変換するために使用されます。それは、 gethostbyaddr(3)getservbyport(3) 関数を置き換えるために、より多くの柔軟性を提供しており、 getaddrinfo(3) 関数の逆です。

リンクレイヤアドレスが getnameinfo() に渡されるなら、その ASCII 表現は、 host に格納されます。 serv によって指される文字列は、NULL でないなら、空の文字列が設定されます。 flags は、常に無視されます。これは、古い link_ntoa(3) 関数の置き換えを目的としています。

sockaddr 構造体 sa は、 salen バイトの長さがある sockaddr_in, sockaddr_in6 または sockaddr_dl 構造体 (それぞれ、IPv4、IPv6 またはリンクレイヤ) のいずれかを指すべきです。

sa に関連しているホストとサービス名は、長さのパラメータが hostlenservlen がある hostserv に格納されます。 hostlen のための最大値は、 NI_MAXHOST で、 servlen のための最大値は、 NI_MAXSERV であり、< netdb.h>で定義されています。長さのパラメータが 0 であるなら、文字列は、格納されません。そうでなければ、ヌル文字で終了するバイトも含めて、ホスト名やサービス文字列を格納するための十分な空間を提供しなければなりません。

flags 引数は、次の値を論理和 (OR) することによって形成されます。

NI_NOFQDN
完全な形でのドメイン名は、ローカルホストに必要ではありません。完全な形でのドメイン名のローカル部分が代わりに返されます。
NI_NUMERICHOST
まるでホスト名の代わりに inet_ntop(3) の呼び出すかのように数値形式でアドレスを返します。
NI_NAMEREQD
名前が必要です。ホスト名が DNS で見つけることができなくて、このフラグが設定されているなら、 0 でないエラーコードが返されます。ホスト名が見つけらなくて、このフラグが設定されていないなら、数値形式でアドレスを返します。
NI_NUMERICSERV
ポート番号を表す数字文字列としてサービス名を返します。
NI_DGRAM
検索されるサービスがデータグラムサービスであると指定して、 getservbyport(3) は、デフォルトの“tcp”代わりに“udp”の 2 番目の引数で呼び出されます。これは、 UDP と TCP で異なったサービスを持っているいくつかのポート (512-514) で必要です。

この実装は、RFC 4007 の第 11 章に文書化されているようにスコープ識別子がある数値 IPv6 アドレス記法を許します。 IPv6 リンクローカルアドレスは、“ fe80::1%ne0”のような文字列として現れます。詳しい情報については、 getaddrinfo(3) を参照してください。

戻り値

getnameinfo() は、成功すれば 0 を、エラーが発生するなら gai_strerror(3) に記載されたエラーコードの 1 つを返します。

使用例

次のコードは、与えられたソケットアドレスで、数値ホスト名およびサービス名を得ようと試みます。特別のアドレスファミリへの決め打ちされた参照がないことに注意してください。

struct sockaddr *sa; /* input */ 
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; 
 
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, 
    sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { 
 errx(1, "could not get numeric hostname"); 
 /* NOTREACHED */ 
} 
printf("host=%s, serv=%s\n", hbuf, sbuf);

次のバージョンは、ソケットアドレスが逆のアドレスマッピングを持っているかどうかチェックします。

struct sockaddr *sa; /* input */ 
char hbuf[NI_MAXHOST]; 
 
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, 
    NI_NAMEREQD)) { 
 errx(1, "could not resolve hostname"); 
 /* NOTREACHED */ 
} 
printf("host=%s\n", hbuf);

関連項目

gai_strerror(3), getaddrinfo(3), gethostbyaddr(3), getservbyport(3), inet_ntop(3), link_ntoa(3), resolver(3), hosts(5), resolv.conf(5), services(5), hostname(7), named(8) R. Gilligan, S. Thomson, J. Bound, J. McCann, and W. Stevens, Basic Socket Interface Extensions for IPv6, RFC 3493, February 2003. S. Deering, B. Haberman, T. Jinmei, E. Nordmark, and B. Zill, IPv6 Scoped Address Architecture, RFC 4007, March 2005. Craig Metz, Protocol Independence Using the Sockets API, Proceedings of the freenix track: 2000 USENIX annual technical conference, June 2000.

規格

getnameinfo() 関数は、 IEEE Std 1003.1-2004 (“POSIX.1”) によって定義され、 RFC 3493, “Basic Socket Interface Extensions for IPv6”で文書化されています。

警告

getnameinfo() は、数値と sa で指定されたアドレスの FQDN (完全な形でのドメイン名) 形式の両方を返すことができます。 host で返された文字列が数値テキスト変換 ( inet_ntop(3) のような) へのバイナリの結果、または DNS の逆の検索の結果であるかどうかを示す返り値は、ありません。そのような訳で、悪意がある者は、次のように PTR レコードをセットアップすることもあり得ます:

1.0.0.127.in-addr.arpa. IN PTR  10.1.1.1

そして、 sa が実際は、 127.0.0.1 であるとき、それが 10.1.1.1 であると信じるように getnameinfo() の呼び出し側をだまします。

そのような攻撃を防ぐために、 getnameinfo() の結果がアクセス管理目的に使用されるとき、 NI_NAMEREQD を使用することはお勧めです:

struct sockaddr *sa; 
socklen_t salen; 
char addr[NI_MAXHOST]; 
struct addrinfo hints, *res; 
int error; 
 
error = getnameinfo(sa, salen, addr, sizeof(addr), 
    NULL, 0, NI_NAMEREQD); 
if (error == 0) { 
 memset(&hints, 0, sizeof(hints)); 
 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 
 hints.ai_flags = AI_NUMERICHOST; 
 if (getaddrinfo(addr, "0", &hints, &res) == 0) { 
  /* 悪意がある PTR レコード */ 
  freeaddrinfo(res); 
  printf("bogus PTR record\n"); 
   /* にせの PTR レコード */ 
  return -1; 
 } 
 /* addr は、PTR 検索結果の FQDN です */ 
} else { 
 /* addr 数値文字列です */ 
 error = getnameinfo(sa, salen, addr, sizeof(addr), 
     NULL, 0, NI_NUMERICHOST); 
}
February 14, 2013 FreeBSD