Shammer's Philosophy

My private adversaria

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 じゃないはず。引き続きデバッグが必要か。