Network Interface Guide

Host and Service Names

The interfaces getaddrinfo(3SOCKET), getnameinfo(3SOCKET), and freeaddrinfo(3SOCKET) provide a simplified method of translating between the names and addresses of a service on a host. For IPv6, these interfaces can be used instead of calling getipnodebyname(3SOCKET) and getservbyname(3SOCKET) and then figuring out how to combine the addresses. Similarly, for IPv4, these interfaces can be used instead of gethostbyname(3NSL) and getservbyname(3SOCKET). Both IPv6 and IPv4 addresses are handled transparently.

getaddrinfo(3SOCKET) returns the combined address and port number of the specified host and service names. Since all of the information returned by getaddrinfo(3SOCKET) is dynamically allocated, it must be freed by freeaddrinfo(3SOCKET) to prevent memory leaks.getnameinfo(3SOCKET) returns the host and services names associated with a specified address and port number. To print error messages based on the EAI_xxx codes returned by getaddrinfo(3SOCKET) and getnameinfo(3SOCKET), call gai_strerror(3SOCKET).

An example of using getaddrinfo(3SOCKET) follows:

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

    /* Get host address.  Any type of address will do. */
    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);
    }
 

After processing the information returned by getaddrinfo(3SOCKET) in the structure pointed to by res, the storage should be released by

        freeaddrinfo(res);

getnameinfo(3SOCKET) is particularly useful in identifying the cause of an error as in the following example:

    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);
         }