getaddrinfo sample_alpha
getaddrinfo の man の内容を見てみた。
DESCRIPTION The getaddrinfo() function is used to get a list of IP addresses and port numbers for host hostname and service servname. It is a replacement for and provides more flexibility than the gethostbyname(3) and getservbyname(3) functions. ... hints is an optional pointer to a struct addrinfo, as defined by <netdb.h>: struct addrinfo { int ai_flags; /* input flags */ int ai_family; /* protocol family for socket */ int ai_socktype; /* socket type */ int ai_protocol; /* protocol for socket */ socklen_t ai_addrlen; /* length of socket-address */ struct sockaddr *ai_addr; /* socket-address for socket */ char *ai_canonname; /* canonical name for service location */ struct addrinfo *ai_next; /* pointer to next in list */ }; ... ai_family The protocol family that should be used. When ai_family is set to PF_UNSPEC, it means the caller will accept any protocol family supported by the operating system. ai_socktype Denotes the type of socket that is wanted: SOCK_STREAM, SOCK_DGRAM, or SOCK_RAW. When ai_socktype is zero the caller will accept any socket type. ai_protocol Indicates which transport protocol is desired, IPPROTO_UDP or IPPROTO_TCP. If ai_protocol is zero the caller will accept any protocol. ai_flags The ai_flags field to which the hints parameter points shall be set to zero or be the bitwise-inclusive OR of one or more of the values AI_ADDRCONFIG, AI_ALL, AI_CANONNAME, AI_NUMERICHOST, AI_NUMERICSERV, AI_PASSIVE, and AI_V4MAPPED. ... After a successful call to getaddrinfo(), *res is a pointer to a linked list of one or more addrinfo structures. The list can be traversed by following the ai_next pointer in each addrinfo structure until a null pointer is encountered. The three members ai_family, ai_socktype, and ai_protocol in each returned addrinfo structure are suitable for a call to socket(2). For each addrinfo structure in the list, the ai_addr member points to a filled-in socket address structure of length ai_addrlen. ...
ai_flags の具体値についても記述されていたが、長くなるので省略。
サンプルも書いてあったが、これは接続可能か試すもののようだ。どちらかというと、addrinfo 構造体の内容を画面に出力するようなものがありがたいのだけれども。自作するしかないか。それでも、hint を埋める部分くらいまでは参考になりそうだ。
#include <arpa/inet.h> // for inet_ntoa #include <err.h> // for errx #include <netdb.h> // for addrinfo, getaddrinfo, freeaddrinfo #include <stdio.h> #include <string.h> // for memset #include <unistd.h> // for close int main(int argc, char *args[]){ // Local values struct addrinfo hints, *res, *res0; int error; // Reset hint memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; // Get addrinfor and error check error = getaddrinfo(args[1], NULL, &hints, &res0); if (error) { errx(1, "%s", gai_strerror(error)); } // Display addrinfo contents int i = 0; for (res = res0 ; res ; res = res->ai_next) { printf("========== addrinfo[%d] ==========\n", i); printf("ai_flags:%d\n", res->ai_flags); printf("ai_family:%d\n", res->ai_family); printf("ai_socktype:%d\n", res->ai_socktype); printf("ai_protocol:%d\n", res->ai_protocol); printf("ai_addrlen:%d\n", res->ai_addrlen); struct sockaddr_in *res_addr = ((struct sockaddr_in *)res->ai_addr); printf("ai_addr:%s\n", inet_ntoa(res_addr->sin_addr)); printf("==================================\n"); i++; } freeaddrinfo(res0); return 0; }
実行結果は以下。
$ ./a.out localhost ========== addrinfo[0] ========== ai_flags:0 ai_family:30 ai_socktype:1 ai_protocol:6 ai_addrlen:28 ai_addr:0.0.0.0 ================================== ========== addrinfo[1] ========== ai_flags:0 ai_family:2 ai_socktype:1 ai_protocol:6 ai_addrlen:16 ai_addr:127.0.0.1 ================================== ========== addrinfo[2] ========== ai_flags:0 ai_family:30 ai_socktype:1 ai_protocol:6 ai_addrlen:28 ai_addr:0.0.0.0 ==================================
ちょっと違う気がする・・・アドレスは 0.0.0.0 じゃないはず。引き続きデバッグが必要か。