getnameinfo()

Perform address-to-nodename translation in a protocol-independent manner

Synopsis:

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

Arguments:

sa
Points to either a sockaddr_in structure (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds the IP address and port number.
salen
Length of the sockaddr_in or sockaddr_in6 structure.
host
Buffer pointer for the host.
hostlen
Size of the host buffer.
serv
Buffer pointer for the server.
servlen
Length of the server buffer.
flags
Change the default action of getnameinfo(). By default, the fully qualified domain name (FQDN) for the host is looked up in the DNS and returned.

These flags are defined in <netdb.h>:

NI_NOFQDN
Only the nodename portion of the FQDN is returned for local hosts.
NI_NUMERICHOST
If set, or if the host's name can't be located in the DNS, the numeric form of the host's address is returned instead of its name (e.g. by calling inet_ntop() instead of getnodebyaddr()).
NI_NAMEREQD
If set, an error is returned when the host's name can't be located in the DNS.
NI_NUMERICSERV
If set, the numeric form of the service address (instead of its name) is returned e.g. its port number. You may require two NI_NUMERICxxx flags to support the -n flag that many commands provide.
NI_DGRAM
Specify that the service is a datagram service. Call getservbyport() with a second argument of udp instead of its default of tcp. This is required for the few ports (512-514) that have different services for UDP and TCP.

Library:

libsocket

Use the -l socket option to qcc to link against this library.

Description:

The getnameinfo() function defines and performs protocol-independent address-to-nodename translation. You can think of it as implementing the reverse-functionality of getaddrinfo() or similar functionality of gethostbyaddr() or getservbypor().

This function looks up an IP address and port number provided by the caller in the DNS and system-specific database. For both IP address and port number, the getnameinfo() function returns text strings in respective buffers provided by the caller. The function indicates successful completion by a zero return value; a non-zero return value indicates failure.

The getnameinfo() function returns the nodename associated with the IP address in the buffer pointed to by the host argument. The hostlen argument gives the length of this buffer.

The getnameinfo() function returns the service name associated with the port number in the buffer pointed to by the serv argument. The servlen argument gives the length of this buffer.

Specify zero for hostlen or servlen when the caller chooses not to return either string. Otherwise, the caller 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

You may find the first value as the constant MAXDNAME in recent versions of BIND's <arpa/nameser.h>; older versions of BIND define this constant to be 256. The second value is a guess based on the services listed in the current Assigned Numbers RFC. BIND (Berkeley Internet Name Domain) is a suite of functionalities that implements Domain Name System (DNS) protocols.

Extension

The implementation allows experimental numeric IPv6 address notation with scope identifier. An IPv6 link-local address appears as string like fe80::1%ne0, when the NI_WITHSCOPEID bit is enabled in the flags argument. See getaddrinfo() for the notation.

Returns:

0
Success.
Non-zero value
An error occurred (see below).

Errors:

EAI_AGAIN
The name couldn't be resolved at this time. Future attempts may succeed.
EAI_BADFLAGS
The flags had invalid values.
EAI_FAIL
A nonrecoverable error occurred.
EAI_FAMILY
The address family wasn't recognized or the address length was invalid for the specified family.
EAI_MEMORY
There was a memory allocation failure.
EAI_NONAME
The name doesn't resolve for the supplied parameters. NI_NAMEREQD is set and the host's name can't be located, or both node name and serv name were null.
EAI_SYSTEM
A system error occurred. The error code can be found in errno.

Examples:

The following code gets the numeric hostname and the service name for a given socket address. There is 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);

Classification:

POSIX 1003.1

Safety:
Cancellation point Yes
Interrupt handler No
Signal handler No
Thread No

See also:

getaddrinfo(), gethostbyaddr(), getservbyport(), /etc/hosts, /etc/nsswitch.conf, /etc/services, named