Host and Service Names
The interfaces getaddrinfo
(), getnameinfo
(), gai_strerror
(), and freeaddrinfo
() 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
(), gethostbyname
(), and getservbyname
() APIs. Both IPv6 and IPv4 addresses are handled transparently. For more information, see the
getaddrinfo
(3C),
getnameinfo
(3C),
gai_strerror
(3C),
freeaddrinfo
(3C),
getipnodebyname
(3C),
gethostbyname
(3C), and
getservbyname
(3C) man pages.
The getaddrinfo
()
routine returns the combined address and port number of the
specified host and service names. Because the information returned by
getaddrinfo
()
is dynamically allocated, the information must be
freed by freeaddrinfo
()
to prevent memory leaks.
getnameinfo
()
returns the host and services names associated
with a specified address and port number. Call gai_strerror
()
to
print error messages based on the EAI_xxx
codes returned by
getaddrinfo
()
and getnameinfo
().
An example of using getaddrinfo
()
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
()
in the structure
pointed to by res
, the storage should be released by
freeaddrinfo(res)
.
The getnameinfo
()
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); }