Oracle® Solaris 11.2 Programming Interfaces Guide

Exit Print View

Updated: July 2014
 
 

Host and Service Names

The interfaces getaddrinfo(3SOCKET), getnameinfo(3SOCKET), gai_strerror(3SOCKET), and freeaddrinfo(3SOCKET) provide a simplified way to translate between the names and addresses of a service on a host. These interfaces are more recent than the getipnodebyname(3SOCKET), gethostbyname(3NSL), and getservbyname(3SOCKET) APIs. Both IPv6 and IPv4 addresses are handled transparently.

The getaddrinfo(3SOCKET) routine returns the combined address and port number of the specified host and service names. Because the information returned by getaddrinfo(3SOCKET) is dynamically allocated, the information 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. Call gai_strerror(3SOCKET) to print error messages based on the EAI_xxx codes returned by getaddrinfo(3SOCKET) and getnameinfo(3SOCKET).

An example of using getaddrinfo(3SOCKET) follows.

struct addrinfo        *res, *aip;
struct addrinfo        hints;
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).

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

struct sockaddr_storage faddr;
int                     sock, new_sock, sock_opt;
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);
}