ネットワークインタフェース

ホスト名とサービス名

インタフェース getaddrinfo(3SOCKET)getnameinfo(3SOCKET)、および freeaddrinfo(3SOCKET) を使用すると、ホスト上のサービスの名前とアドレスを簡単に変換できます。IPv6 の場合、getipnodebyname(3SOCKET)getservbyname(3SOCKET) を呼び出してアドレスの結合方法を決定する代わりに、これらのインタフェースを使用できます。同様に IPv4 では、これらのインタフェースを gethostbyname(3NSL)getservbyname(3SOCKET) の代わりに使用できます。IPv6 アドレスと IPv4 アドレスは、どちらも透過的に処理されます。

getaddrinfo(3SOCKET) は、指定されたホストの結合アドレスとポート番号、およびサービス名を返します。getaddrinfo(3SOCKET) が返す情報はすべて動的に割り当てられるため、メモリーリークが防止されるように freeaddrinfo(3SOCKET) を使用して解放しなければなりません。getnameinfo(3SOCKET) は、指定されたアドレスとポート番号に関連付けられたホスト名とサービス名を返します。getaddrinfo(3SOCKET)getnameinfo(3SOCKET) が返す EAI_xxx コードに基づくエラーメッセージを出力するには、gai_strerror(3SOCKET) を呼び出します。

getaddrinfo(3SOCKET) の使用例を次に示します。

    struct addrinfo         *res, *aip;
    struct addrinfo         hints;
    int                     sock = -1;
    int                     error;

    /* ホストアドレスを取得する。アドレスのタイプは問わない。*/
    bzero(&hints, sizeof (hints));
    hints.ai_flags = AI_ALL|AI_ADDRCONFIG;
    hints.ai_socktype = SOCK_STREAM;

    error = getaddrinfo(hostname, servicename, &hints, &res);
    if (error != 0) {
        (void) fprintf(stderr, "getaddrinfo: %s for host %s service %s¥n",
                 gai_strerror(error), hostname, servicename);
        return (-1);
    }
 

res が指す構造体の getaddrinfo(3SOCKET) が返す情報を処理したあと、次の文によって記憶領域を解放する必要があります。

        freeaddrinfo(res);

次の例に示すように、getnameinfo(3SOCKET) はエラー原因を調べるのに特に便利です。

    struct sockaddr_storage faddr;
    int                     sock, new_sock;
    socklen_t               faddrlen;
    int                     error;
    char                    hname[NI_MAXHOST];
    char                    sname[NI_MAXSERV];

     ...
         faddrlen = sizeof (faddr);
         new_sock = accept(sock, (struct sockaddr *)&faddr, &faddrlen);
         if (new_sock == -1) {
             if (errno != EINTR && errno != ECONNABORTED) {
                 perror("accept");
             }
             continue;
         }        
         error = getnameinfo((struct sockaddr *)&faddr, faddrlen, hname, 
                     sizeof (hname), sname, sizeof (sname), 0);
         if (error) {
             (void) fprintf(stderr, "getnameinfo: %s¥n",
                         gai_strerror(error));
         } else {
             (void) printf("Connection from %s/%s¥n", hname, sname);
         }