Convert an IP address and port number into node and service names
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> int getnameinfo( const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags );
You might have to set both NI_NUMERICHOST and NI_NUMERICSERV to support the -n flag that many commands provide.
The getnameinfo() function converts a sockaddr structure to a host name and a service name. It's similar to gethostbyaddr_r() and getservbyport(), and is the converse of getaddrinfo().
This function looks up the given IP address and port number in the DNS and system-specific database and fills the host and serv buffers with the associated node name and service name, respectively. If the host's name can't be located, the numeric form is returned instead, unless you specified NI_NAMEREQD in the flags.
You can specify zero for hostlen or servlen if you don't need the corresponding name. Otherwise, you must provide buffers large enough to hold the nodename and the service name, including the terminating null characters.
Most systems don't provide constants that specify the maximum size of either a FQDN or a service name. In order to aid your application in allocating buffers, the following constants are defined in <netdb.h>:
#define NI_MAXHOST 1025 #define NI_MAXSERV 32
This implementation allows numeric IPv6 address notation with scope identifier, as documented in chapter 11 of draft-ietf-ipv6-scoping-arch-02.txt. An IPv6 link-local address appears as a string such as fe80::1%ne0. See getaddrinfo() for the notation.
The following code gets the numeric hostname and the service name for a given socket address. Note that there's no hardcoded reference to a particular address family.
struct sockaddr *sa; /* input */ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { errx(1, "could not get numeric hostname"); /*NOTREACHED*/ } printf("host=%s, serv=%s\n", hbuf, sbuf);
The following version checks if the socket address has reverse address mapping:
struct sockaddr *sa; /* input */ char hbuf[NI_MAXHOST]; if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) { errx(1, "could not resolve hostname"); /*NOTREACHED*/ } printf("host=%s\n", hbuf);
Safety: | |
---|---|
Cancellation point | Yes |
Interrupt handler | No |
Signal handler | No |
Thread | Yes |