書式
#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);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
getnameinfo(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
説明
getnameinfo() 関数は、 getaddrinfo(3) の逆の動作を行う。つまり、プロトコルに依存しないかたちで ソケットアドレスから対応するホスト名とサービスへの変換を行う。 この関数は gethostbyaddr(3) と getservbyport(3) の機能を一つにしたものだが、 これらの関数と違い、 getnameinfo(3) はリエントラントであり、IPv4 と IPv6 の差分に依存しないかたちで プログラムを書くことができる。sa 引き数は、 IP アドレスとポート番号の情報を保持している 汎用的なソケットアドレス構造体 (sockaddr_in 型または sockaddr_in6 型) へのポインタである。 salen は sa のサイズである。 host と serv 引き数は、(それぞれサイズが hostlen と servlen の) 呼び出し側で確保されたバッファへのポインタであり、 ホスト名とサービス名を含むヌル終端された文字列が それぞれのバッファに格納される。
ホスト名が不要であることをこの関数に伝えるには、 host に NULL を指定するか、 hostlen に 0 を指定する。同様に、サービス名が不要な場合は、 serv に NULL を指定するか、 servlen に 0 を指定する。 しかし、ホスト名とサービス名の両方を不要だと指定することはできない (いずれか一方は要求すること)。
flags 引き数で getnameinfo() の動作を変えることができる。指定できる値は以下の通り:
- NI_NAMEREQD
- 指定すると、ホスト名が決定できなかった場合にエラーを返す。
- NI_DGRAM
- 指定すると、ストリームベース (TCP) でなくデータグラムベース (UDP) のサービスを対象にする。数は少ないが、 UDP と TCP で違うサービスを提供しているポート (512-514) に対して必要となる。
- NI_NOFQDN
- 指定すると、ローカルなホストには fully qualified domain name (FQDN) の ホスト名の部分のみを返す。
- NI_NUMERICHOST
- 指定すると、数値形式のホスト名が返される。 (指定しなくても、ノードの名前が決定できない場合は数値形式が返ることがある)。
- NI_NUMERICSERV
- 指定すると、数値形式のサービス名 (例えばポート番号) が返される (指定しなくても、サービス名が決定できない場合は数値形式が返ることがある)。
国際化ドメイン名のための getnameinfo() の拡張
glibc 2.3.4 から、 getnameinfo() に拡張が行われ、ホスト名と 国際化ドメイン名 (Internationalized Domain Name; IDN) 形式との間で 透過的な変換ができるようになっている (IDN 形式については RFC 3490 の Internationalizing Domain Names in Applications (IDNA) を参照)。3つのフラグが新たに定義されている:
- NI_IDN
- このフラグを指定すると、必要であれば、検索処理で見つかった名前は IDN 形式からロケールに応じた符号化形式に変換される。 ASCII 文字だけの名前はこの変換では影響を受けない。このため、 既存のプログラムや環境でこのフラグを使うことができる。
- NI_IDN_ALLOW_UNASSIGNED, NI_IDN_USE_STD3_ASCII_RULES
- これらのフラグをセットすると、IDNA 処理で使用されるフラグ IDNA_ALLOW_UNASSIGNED (未割り当ての Unicode のコードポイントを許容) と IDNA_USE_STD3_ASCII_RULES (出力が STD3 準拠のホスト名かをチェックする) がそれぞれ有効になる。
返り値
成功すると 0 が返り、(要求されていれば) ノードとサービスの名前がヌル終端された文字列の形式でそれぞれの指定バッファに返される (バッファの長さにあうように縮められるかもしれない)。 エラーの場合は、以下の 0 以外のエラー・コードが返される:- EAI_AGAIN
- 指定された名前が現時点では解決できなかった。 後で再試行してみること。
- EAI_BADFLAGS
- flags 引き数に不正な値が与えられた。
- EAI_FAIL
- 回復できないエラーが発生した。
- EAI_FAMILY
- 指定したアドレスファミリーが認識できなかった。 あるいはアドレスの長さが指定されたファミリーに合うものでなかった。
- EAI_MEMORY
- メモリが足りない。
- EAI_NONAME
- 与えられたパラメータでは名前が解決できない。 NI_NAMEREQD が設定されていたがホスト名が決定できなかったか、 ホスト名もサービス名も要求されなかった。
- EAI_OVERFLOW
- host または serv が指しているバッファが小さすぎた。
- EAI_SYSTEM
- システムエラーが起った。 エラーコードは errno に設定される。
gai_strerror(3) 関数を使うと、これらのエラー・コードを、エラー・レポートに適した 人間が読みやすい文字列に翻訳してくれる。
ファイル
/etc/hosts/etc/nsswitch.conf
/etc/resolv.conf
バージョン
getnameinfo() は、glibc バージョン 2.1 以降で提供されている。準拠
RFC 2553, POSIX.1-2001.注意
適切なバッファサイズを選択できるように、 <netdb.h> に以下の定数が定義されている。#define NI_MAXHOST 1025 #define NI_MAXSERV 32
glibc 2.8 以降では、機能検査マクロ _BSD_SOURCE, _SVID_SOURCE, _GNU_SOURCE のいずれかが定義された場合にのみ、これらの定義が公開される。
前者は、最近のバージョンの BIND のヘッダファイル <arpa/nameser.h> 中の定数 MAXDNAME と同じ値である。 後者は、割り当て済の数値について記した現在の RFC に 列挙されてサービスから推量した値である。
例
以下のコードは、指定されたソケットアドレスに対する ホストとサービスの数値表式を取得しようと試みる。 特定のアドレスファミリーに対する参照情報は 一切ハードコードされていないことに着目してほしい。
struct sockaddr *sa; /* input */ socklen_t len; /* input */ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; if (getnameinfo(sa, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) printf("host=%s, serv=%s\n", hbuf, sbuf);
以下ではソケットアドレスに 逆向きのアドレスマッピングが存在するかをチェックしている。
struct sockaddr *sa; /* input */ socklen_t len; /* input */ char hbuf[NI_MAXHOST]; if (getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) printf("could not resolve hostname"); else printf("host=%s\n", hbuf);
getnameinfo() を使ったプログラム例が getaddrinfo(3) に記載されている。
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。