Manpages

名 前

getaddrinfo, freeaddrinfo, gai_strerror − ネ ッ ト ワ ー ク の ア ド レ ス と サ ー ビ ス を 変 換 す る

書 式

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

int getaddrinfo(const char *node, const char *service,
const struct addrinfo *
hints,
struct addrinfo **
res);

void freeaddrinfo(struct addrinfo *res);

const char *gai_strerror(int errcode);

glibc 向 け の 機 能 検 査 マ ク ロ の 要 件 (feature_test_macros(7) 参 照 ):

getaddrinfo(), freeaddrinfo(), gai_strerror():

_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE

説 明

getaddrinfo() は 、 (イ ン タ ー ネ ッ ト の ホ ス ト と サ ー ビ ス を 識 別 す る ) nodeservice を 渡 す と 、 一 つ 以 上 の addrinfo 構 造 体 を 返 す 。 そ れ ぞ れ の addrinfo 構 造 体 に は 、 bind(2)connect(2) を 呼 び 出 す 際 に 指 定 で き る イ ン タ ー ネ ッ ト ア ド レ ス が 格 納 さ れ て い る 。 getaddrinfo() 関 数 は 、 gethostbyname(3)getservbyname(3) の 機 能 を ま と め て 一 つ の イ ン タ ー フ ェ ー ス に し た も の で あ る が 、 こ れ ら の 関 数 と 違 い 、 getaddrinfo() は リ エ ン ト ラ ン ト で あ り 、 getaddrinfo() を 使 う こ と で プ ロ グ ラ ム は IPv4 と IPv6 の 違 い に 関 す る 依 存 関 係 を な く す こ と が で き る 。

getaddrinfo() が 用 い る addrinfo 構 造 体 は 以 下 の フ ィ ー ル ド を 含 む 。

struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next; };

hints 引 き 数 は addrinfo 構 造 体 を 指 し 示 し 、 こ の 構 造 体 を 用 い て res が 指 す リ ス ト に 入 れ て 返 す ソ ケ ッ ト ア ド レ ス 構 造 体 を 選 択 す る た め の 基 準 を 指 定 す る 。 hints が NULL で な い 場 合 、 hintsaddrinfo 構 造 体 を 指 し 示 し 、 そ の 構 造 体 の フ ィ ー ル ド ai_family, ai_socktype, ai_protocolgetaddrinfo() が 返 す ソ ケ ッ ト ア ド レ ス 集 合 に 対 す る 基 準 を 指 定 す る 。

ai_family こ の フ ィ ー ル ド は 返 さ れ る ア ド レ ス の 希 望 の ア ド レ ス フ ァ ミ リ ー を 指 定 す る 。 こ の フ ィ ー ル ド に 指 定 で き る 有 効 な 値 と し て は

AF_INETAF_INET6 が あ る 。 ま た 、 値 AF_UNSPEC を 指 定 す る と 、 getaddrinfo() は nodeservice で 使 用 で き る い ず れ か の ア ド レ ス フ ァ ミ リ ー (例 え ば IPv4 か IPv6) の ソ ケ ッ ト ア ド レ ス を 返 す こ と を 求 め ら れ る 。

ai_socktype こ の フ ィ ー ル ド は 推 奨 の ソ ケ ッ ト 型

(例 え ば SOCK_STREAM

SOCK_DGRAM) を 指 定 す る 。 こ の フ ィ ー ル ド に 0 を 指 定 す る と 、 任 意 の ソ ケ ッ ト 型 の ソ ケ ッ ト ア ド レ ス を getaddrinfo() が 返 し て よ い こ と を 意 味 す る 。

ai_protocol こ の フ ィ ー ル ド は 返 さ れ る ソ ケ ッ ト ア ド レ ス の プ ロ ト コ ル を 指 定 す る 。 こ の フ ィ ー ル ド に

0 を 指 定 す る と 、 任 意 の プ ロ ト コ ル の の ソ ケ ッ ト ア ド レ ス を getaddrinfo() が 返 し て よ い こ と を 意 味 す る 。

ai_flags こ の フ ィ ー ル ド は 、 追 加 の オ プ シ ョ ン

(下 記 ) を 指 定 す る 。 複 数

の フ ラ グ を 指 定 す る 際 に は 、 そ れ ら の ビ ッ ト 単 位 の OR を と っ て 指 定 す る 。

hints が 指 し 示 す 構 造 体 の 他 の す べ て の フ ィ ー ル ド に は 0 か ヌ ル ポ イ ン タ ー を 適 切 に 入 れ な け れ ば な ら な い 。

hints に NULL を 指 定 す る の は 、 ai_socktypeai_protocol に 0 を 、 ai_familyAF_UNSPEC を 、 ai_flags(AI_V4MAPPED | AI_ADDRCONFIG) を 設 定 す る の と 等 価 で あ る (POSIX で は ai_flags に は 別 の デ フ ォ ル ト 値 が 規 定 さ れ て い る ; 「 備 考 」 を 参 照 )。 node に は 、 数 値 形 式 の ネ ッ ト ワ ー ク ア ド レ ス (IPv4 の 場 合 は inet_aton(3) で サ ポ ー ト さ れ て い る ド ッ ト 区 切 り の 数 字 に よ る 表 記 、 IPv6 の 場 合 は inet_pton(3) で サ ポ ー ト さ れ て い る 16 進 数 の 文 字 列 形 式 ) も し く は ネ ッ ト ワ ー ク ホ ス ト 名 を 指 定 す る 。 ネ ッ ト ワ ー ク ホ ス ト 名 を 指 定 し た 場 合 に は 、 そ の ネ ッ ト ワ ー ク ア ド レ ス が 検 索 さ れ 、 名 前 解 決 が 行 な わ れ る 。 hints.ai_flagsAI_NUMERICHOST フ ラ グ が 含 ま れ て い る 場 合 は 、 node は 数 値 形 式 の ネ ッ ト ワ ー ク ア ド レ ス で な け れ ば な ら な い 。 AI_NUMERICHOST フ ラ グ を 使 う と 、 時 間 の 掛 か る 可 能 性 の あ る ネ ッ ト ワ ー ク ホ ス ト ア ド レ ス の 検 索 は す べ て 抑 制 さ れ る 。

hints.ai_flagsAI_PASSIVE フ ラ グ が 指 定 さ れ 、 か つ node が NULL の 場 合 、 返 さ れ る ソ ケ ッ ト ア ド レ ス は コ ネ ク シ ョ ン を accept(2) す る た め の ソ ケ ッ ト を bind(2) す る の に 適 し た も の と な る 。 返 さ れ る ソ ケ ッ ト ア ド レ ス に は 「 ワ イ ル ド カ ー ド ア ド レ ス 」 (IPv4 ア ド レ ス の 場 合 は INADDR_ANY、 IPv6 ア ド レ ス の 場 合 は IN6ADDR_ANY_INIT) が 入 る 。 ワ イ ル ド カ ー ド ア ド レ ス は 、 任 意 の ホ ス ト の ネ ッ ト ワ ー ク ア ド レ ス で 接 続 を 受 け 付 け よ う と す る ア プ リ ケ ー シ ョ ン (通 常 は サ ー バ ー ) で 用 い ら れ る 。 node が NULL で な い 場 合 、 AI_PASSIVE フ ラ グ は 無 視 さ れ る 。

hints.ai_flagsAI_PASSIVE フ ラ グ が セ ッ ト さ れ て い な い 場 合 、 返 さ れ る ソ ケ ッ ト ア ド レ ス は connect(2), sendto(2), sendmsg(2) で の 使 用 に 適 し た も の と な る 。 node が NULL の 場 合 、 ネ ッ ト ワ ー ク ア ド レ ス に は ル ー プ バ ッ ク イ ン タ ー フ ェ イ ス の ア ド レ ス (IPv4 ア ド レ ス の 場 合 は INADDR_LOOPBACK IPv6 ア ド レ ス の 場 合 は IN6ADDR_LOOPBACK_INIT)が 設 定 さ れ る 。 こ れ は 同 じ ホ ス ト 上 で 動 作 し て い る 接 続 相 手 と 通 信 す る よ う な ア プ リ ケ ー シ ョ ン で 用 い ら れ る 。

service に よ り 、 返 さ れ る 各 ア ド レ ス 構 造 体 の ポ ー ト 番 号 が 決 ま る 。 こ の 引 き 数 が サ ー ビ ス 名 (services(5) 参 照 ) の 場 合 、 対 応 す る ポ ー ト 番 号 に 翻 訳 さ れ る 。 こ の 引 き 数 に は 10 進 数 も 指 定 す る こ と が で き 、 こ の 場 合 に は バ イ ナ リ へ の 変 換 だ け が 行 わ れ る 。 service が NULL の 場 合 、 返 さ れ る ソ ケ ッ ト ア ド レ ス の ポ ー ト 番 号 は 初 期 化 さ れ な い ま ま と な る 。 hints.ai_flagsAI_NUMERICSERV が 指 定 さ れ 、 か つ service が NULL で な い 場 合 、 service は 数 値 の ポ ー ト 番 号 を 含 む 文 字 列 を 指 し 示 さ な け れ ば な ら な い 。 こ の フ ラ グ は 、 名 前 解 決 サ ー ビ ス が 不 要 で あ る こ と が 分 か っ て い る 場 合 に 、 サ ー ビ ス の 起 動 を 抑 制 す る た め に 用 い ら れ る 。

nodeservice の ど ち ら か は NULL に し て よ い が 、 両 方 同 時 に NULL に し て は な ら な い 。

getaddrinfo() 関 数 は 、 addrinfo 構 造 体 の メ モ リ ー 確 保 を 行 い 、 addrinfo 構 造 体 の リ ン ク リ ス ト を 初 期 化 し 、 res に リ ス ト の 先 頭 へ の ポ イ ン タ ー を 入 れ て 返 す 。 こ の と き 、 各 構 造 体 の ネ ッ ト ワ ー ク ア ド レ ス は nodeservice に 一 致 し 、 hints で 課 さ れ た す べ て の 制 限 を 満 た す も の と な る 。 リ ン ク リ ス ト の 要 素 は ai_next フ ィ ー ル ド に よ り 連 結 さ れ る 。 リ ン ク リ ス ト の addrinfo 構 造 体 は 複 数 個 に な る こ と も あ り 、 そ の 理 由 は い く つ か あ る 。 ネ ッ ト ワ ー ク ホ ス ト が マ ル チ ホ ー ム で あ る 、 複 数 の プ ロ ト コ ル で ア ク セ ス で き る (例 え ば AF_INETAF_INET6 の 両 方 ) 、 複 数 の ソ ケ ッ ト 種 別 で 同 じ サ ー ビ ス が 利 用 で き る (例 え ば 、 ひ と つ が SOCK_STREM ア ド レ ス で 、 も う ひ と つ が SOCK_DGRAM ア ド レ ス で あ る )、 が あ る 。 通 常 は 、 ア プ リ ケ ー シ ョ ン は 返 さ れ た 順 序 で ア ド レ ス を 試 す べ き で あ る 。 getaddrinfo() の 中 で 使 用 さ れ る 並 べ 替 え 関 数 は RFC 3484 で 定 義 さ れ て い る 。 特 殊 な シ ス テ ム で は 、 /etc/gai.conf を 編 集 す る こ と で 、 こ の 順 序 を 微 調 整 す る こ と が で き る (/etc/gai.conf は glibc 2.5 以 降 で 利 用 で き る )。

hints.ai_flagsAI_CANONNAME フ ラ グ が 含 ま れ て い る 場 合 、 返 さ れ る リ ス ト の 最 初 の addrinfo 構 造 体 の ai_canonname フ ィ ー ル ド は ホ ス ト の 公 式 な 名 前 を 指 す よ う に 設 定 さ れ る 。 返 さ れ る 各 々 の addrinfo 構 造 体 の 残 り の フ ィ ー ル ド は 以 下 の よ う に 初 期 化 さ れ る 。

*

ai_family, ai_socktype, ai_protocol フ ィ ー ル ド は ソ ケ ッ ト 生 成 パ ラ メ ー タ ー を 返 す (こ れ ら の フ ィ ー ル ド の 意 味 は socket(2) の 同 じ 名 前 の 引 き 数 と 同 じ で あ る )。 例 え ば 、 ai_familyAF_INETAF_INET6 を 返 し 、 ai_socktypeSOCK_DGRAMSOCK_STREAM を 返 し 、 ai_protocol は そ の ソ ケ ッ ト の プ ロ ト コ ル を 返 す 。

*

ai_addr フ ィ ー ル ド に は ソ ケ ッ ト ア ド レ ス へ の ポ イ ン タ ー が 書 き 込 ま れ 、 ai_addrlen フ ィ ー ル ド に は ソ ケ ッ ト ア ド レ ス の 長 さ が バ イ ト 単 位 で 書 き 込 ま れ る 。

hints.ai_flagsAI_ADDRCONFIG を 含 む 場 合 、 res が 指 す リ ス ト に は 、 ロ ー カ ル シ ス テ ム に 最 低 一 つ の IPv4 ア ド レ ス が 設 定 さ れ て い る 場 合 の み IPv4 ア ド レ ス が 返 さ れ 、 ロ ー カ ル シ ス テ ム に 最 低 一 つ の IPv6 ア ド レ ス が 設 定 さ れ て い る 場 合 に の み IPv6 ア ド レ ス が 返 さ れ る 。 な お 、 こ の 場 合 に は 、 ル ー プ バ ッ ク ア ド レ ス は 有 効 に 設 定 さ れ た ア ド レ ス と は み な さ れ な い 。 こ の フ ラ グ は 、 例 え ば 、 IPv4 だ け の シ ス テ ム で 、 getaddrinfo() が 必 ず IPv6 ソ ケ ッ ト ア ド レ ス を 返 さ な い こ と を 保 証 す る の に 役 立 つ 。 IPv4 だ け の シ ス テ ム で は 、 IPv6 ア ド レ ス は connect(2)bind(2) で 必 ず 失 敗 す る こ と に な る 。

hints.ai_flagsAI_V4MAPPED が 指 定 さ れ て い て 、 hints.ai_familyAF_INET6 が 指 定 さ れ 、 マ ッ チ す る IPv6 ア ド レ ス が 見 つ か ら な か っ た 場 合 、 res が 指 す リ ス ト に は IPv4−mapped IPv6 ア ド レ ス が 返 さ れ る 。 hints.ai_flagsAI_V4MAPPEDAI_ALL の 両 方 が 指 定 さ れ て い る 場 合 、 res が 指 す リ ス ト に は IPv6 ア ド レ ス と IPv4−mapped IPv6 ア ド レ ス の 両 方 が 返 さ れ る 。 AI_V4MAPPED が 指 定 さ れ て い な い 場 合 、 AI_ALL は 無 視 さ れ る 。

freeaddrinfo() 関 数 は 、 リ ン ク リ ス ト res に 対 し て 動 的 に 割 り 当 て ら れ た メ モ リ ー を 解 放 す る 。 国 際 化 ド メ イ ン 名 の た め の getaddrinfo() の 拡 張
glibc 2.3.4 か ら 、 getaddrinfo() は 入 出 力 す る ホ ス ト 名 を 透 過 的 に 国 際 化 ド メ イ ン 名 (IDN) 形 式 (RFC 3490 の Internationalizing Domain Names in Applications (IDNA) を 参 照 の こ と ) と 変 換 す る こ と を 選 択 的 に 認 め る よ う に 拡 張 さ れ て い る 。 4 つ の 新 し い フ ラ グ が 定 義 さ れ て い る :

AI_IDN こ の フ ラ グ が 指 定 さ れ る と 、

node で 与 え ら れ た ノ ー ド 名 は 必 要 が あ れ

ば IDN 形 式 に 変 換 さ れ る 。 ソ ー ス 符 号 化 形 式 は 現 在 の ロ ケ ー ル の も の で あ る 。 入 力 名 に 非 ASCII 文 字 が 含 ま れ て い る 場 合 、 IDN 符 号 化 形 式 が 使 わ れ る 。 非 ASCII 文 字 が 含 ま れ て い る (ピ リ オ ド で 区 切 ら れ る )部 分 ノ ー ド 名 は 、 名 前 解 決 機 能 に 渡 さ れ る 前 に ASCII 互 換 符 号 化 形 式 (ACE) を 使 っ て 符 号 化 さ れ る 。

AI_CANONIDN

AI_CANONNAME が 指 定 さ れ て い る 場 合 、 getaddrinfo() は 名 前 の 検 索 に 成 功 し た 後 、 返 さ れ た addrinfo 構 造 体 に 対 応 す る ノ ー ド の 正 規 名 を 返 す 。 返 り 値 は 名 前 解 決 機 能 か ら 返 さ れ た 値 の 正 確 な コ ピ ー で あ る 。

AI_CANONIDN 名 前 が ACE で 符 号 化 さ れ て い る 場 合 、 一 つ ま た は 複 数 の 名 前 の 構 成 要 素 の 先 頭 に xn−− を 含 ん で い る 。 こ れ ら の 構 成 要 素 を 読 み 込 み 可 能 な 形 に 変 換 す る た め に 、 AI_CANONNAME と 共 に AI_CANONIDN フ ラ グ を 渡 す こ と も 出 来 る 。 返 さ れ る 文 字 列 は 現 在 の ロ ケ ー ル の 符 号 化 形 式 で 符 号 化 さ れ て い る 。

AI_IDN_ALLOW_UNASSIGNED, AI_IDN_USE_STD3_ASCII_RULES こ れ ら の フ ラ グ を セ ッ ト す る と 、 IDNA 処 理 で 使 用 さ れ る フ ラ グ IDNA_ALLOW_UNASSIGNED (未 割 り 当 て の Unicode の コ ー ド ポ イ ン ト を 許 容 ) と IDNA_USE_STD3_ASCII_RULES (出 力 が STD3 準 拠 の ホ ス ト 名 か を チ ェ ッ ク す る ) が そ れ ぞ れ 有 効 に な る 。

返 り 値

getaddrinfo() は 成 功 す る と 0 を 返 し 、 失 敗 す る と 以 下 の 非 0 の エ ラ ー コ ー ド の い ず れ か を 返 す 。
EAI_ADDRFAMILY
指 定 さ れ た ネ ッ ト ワ ー ク ホ ス ト に は 、 要 求 さ れ た ア ド レ ス フ ァ ミ リ ー の ネ ッ ト ワ ー ク ア ド レ ス が な い 。
EAI_AGAIN
ネ ー ム サ ー バ ー か ら 一 時 的 な 失 敗 (temporary failure) を 意 味 す る 返 事 が 返 さ れ た 。 後 で も う 一 度 試 し て み よ 。
EAI_BADFLAGS

hints.ai_flags の フ ラ グ に 不 正 な フ ラ グ が 含 ま れ て い る 。 ま た は 、 hints.ai_flagsAI_CANONNAME が 含 ま れ て い て 、 か つ name が NULL で あ っ た 。

EAI_FAIL ネ ー ム サ ー バ ー か ら 恒 久 的 な 失 敗 (permanent failure) を 意 味 す る 返 事 が 返 さ れ た 。
EAI_FAMILY
要 求 さ れ た ア ド レ ス フ ァ ミ リ ー が サ ポ ー ト さ れ て い な い 。
EAI_MEMORY
メ モ リ ー が 足 り な い 。
EAI_NODATA
指 定 さ れ た ネ ッ ト ワ ー ク ホ ス ト は 存 在 す る が 、 ネ ッ ト ワ ー ク ア ド レ ス が ひ と つ も 定 義 さ れ て い な い 。
EAI_NONAME

nodeservice の ど ち ら か が 不 明 、 ま た は nodeservice の 両 方 が NULL だ っ た 場 合 、 ま た は AI_NUMERICSERVhints.ai_flags に 指 定 さ れ て い て 、 hints.ai_flagsservice が 数 値 の ポ ー ト 番 号 の 文 字 列 で な い 。

EAI_SERVICE 要 求 さ れ た サ ー ビ ス は 、 要 求 さ れ た ソ ケ ッ ト タ イ プ で は 利 用 で き な い 。 他 の ソ ケ ッ ト タ イ プ で な ら 利 用 可 能 か も し れ な い 。 こ の エ ラ ー が 発 生 す る 例 と し て は 、 service が "shell" (ス ト リ ー ム ソ ケ ッ ト で の み 利 用 で き る サ ー ビ ス ) で 、 hints.ai_protocolIPPROTO_UDP が 指 定 さ れ た り 、 hints.ai_socktypeSOCK_DGRAM が 指 定 さ れ た り し た 場 合 が あ る 。 ま た 、 service が NULL 以 外 で 、 hints.ai_socktypeSOCK_RAW (サ ー ビ ス の 考 え 方 を サ ポ ー ト し て い な い ソ ケ ッ ト 種 別 ) が 指 定 さ れ た 場 合 に も 、 こ の エ ラ ー が 発 生 す る 。
EAI_SOCKTYPE
要 求 さ れ た ソ ケ ッ ト タ イ プ が サ ポ ー ト さ れ て い な い 。 こ の エ ラ ー が 発 生 す る 例 と し て は 、 hints.ai_socktypehints.ai_protocol が 矛 盾 し て い る 場 合 (例 え ば hints.ai_socktypeSOCK_DGRAMhints.ai_protocolIPPROTO_TCP) が あ る 。
EAI_SYSTEM
そ の 他 の シ ス テ ム エ ラ ー 。 詳 し く は errno を 調 べ る こ と 。

gai_strerror() 関 数 を 用 い る と 、 こ れ ら の エ ラ ー コ ー ド を 人 間 に 可 読 な 文 字 列 に 変 換 で き る の で 、 エ ラ ー 報 告 に 適 す る だ ろ う 。

フ ァ イ ル

/etc/gai.conf

準 拠

POSIX.1−2001. getaddrinfo() 関 数 は RFC 2553 に 記 載 さ れ て い る 。

注 意

getaddrinfo() は 、 IPv6 scope−ID を 指 定 す る た め に address%scope−id 記 法 を サ ポ ー ト し て い る 。

AI_ADDRCONFIG, AI_ALL, AI_V4MAPPED は glibc 2.3.3 以 降 で 利 用 可 能 で あ る 。 AI_NUMERICSERV は glibc 2.3.4 以 降 で 利 用 可 能 で あ る 。

POSIX.1−2001 に よ る と 、 hints に NULL が 指 定 さ れ た 場 合 、 ai_flags を 0 と み な す べ き と さ れ て い る 。 GNU C ラ イ ブ ラ リ で は 、 こ の 場 合 に 、 代 わ り に ai_flags(AI_V4MAPPED | AI_ADDRCONFIG) と み な す よ う に な っ て い る 。 こ の 値 の 方 が 標 準 規 格 の 改 善 に な る と 考 え ら れ て い る か ら で あ る 。

以 下 の プ ロ グ ラ ム は 、 getaddrinfo(), gai_strerror(), freeaddrinfo(), getnameinfo(3) の 使 い 方 を 示 し た も の で あ る 。 プ ロ グ ラ ム は UDP デ ー タ グ ラ ム の echo サ ー バ と ク ラ イ ア ン ト で あ る 。 サ ー バ の プ ロ グ ラ ム

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>

#define BUF_SIZE 500

int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
ssize_t nread;
char buf[BUF_SIZE];

if (argc != 2) {
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE); }

memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;

s = getaddrinfo(NULL, argv[1], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE); }

/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */

for (rp = result; rp != NULL; rp = rp−>ai_next) {
sfd = socket(rp−>ai_family, rp−>ai_socktype,
rp−>ai_protocol);
if (sfd == −1)
continue;

if (bind(sfd, rp−>ai_addr, rp−>ai_addrlen) == 0)
break; /* Success */

close(sfd); }

if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
exit(EXIT_FAILURE); }

freeaddrinfo(result); /* No longer needed */

/* Read datagrams and echo them back to sender */

for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0,
(struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == −1)
continue; /* Ignore failed request */

char host[NI_MAXHOST], service[NI_MAXSERV];

s = getnameinfo((struct sockaddr *) &peer_addr,
peer_addr_len, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0)
printf("Received %zd bytes from %s:%s\n",
nread, host, service);
else
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));

if (sendto(sfd, buf, nread, 0,
(struct sockaddr *) &peer_addr,
peer_addr_len) != nread)
fprintf(stderr, "Error sending response\n"); } } ク ラ イ ア ン ト の プ ロ グ ラ ム
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define BUF_SIZE 500

int
main(int argc, char *argv[])
{
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s, j;
size_t len;
ssize_t nread;
char buf[BUF_SIZE];

if (argc < 3) {
fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
exit(EXIT_FAILURE); }

/* Obtain address(es) matching host/port */

memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */

s = getaddrinfo(argv[1], argv[2], &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(EXIT_FAILURE); }

/* getaddrinfo() returns a list of address structures.
Try each address until we successfully connect(2).
If socket(2) (or connect(2)) fails, we (close the socket
and) try the next address. */

for (rp = result; rp != NULL; rp = rp−>ai_next) {
sfd = socket(rp−>ai_family, rp−>ai_socktype,
rp−>ai_protocol);
if (sfd == −1)
continue;

if (connect(sfd, rp−>ai_addr, rp−>ai_addrlen) != −1)
break; /* Success */

close(sfd); }

if (rp == NULL) { /* No address succeeded */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE); }

freeaddrinfo(result); /* No longer needed */

/* Send remaining command−line arguments as separate
datagrams, and read responses from server */

for (j = 3; j < argc; j++) {
len = strlen(argv[j]) + 1;
/* +1 for terminating null byte */

if (len + 1 > BUF_SIZE) {
fprintf(stderr,
"Ignoring long message in argument %d\n", j);
continue; }

if (write(sfd, argv[j], len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE); }

nread = read(sfd, buf, BUF_SIZE);
if (nread == −1) {
perror("read");
exit(EXIT_FAILURE); }

printf("Received %zd bytes: %s\n", nread, buf); }

exit(EXIT_SUCCESS); }

関 連 項 目

getaddrinfo_a(3), gethostbyname(3), getnameinfo(3), inet(3), gai.conf(5), hostname(7), ip(7)

こ の 文 書 に つ い て

こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。

COMMENTS