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