Using getnameinfo()

getnameinfo() can be used to convert an addrinfo structure back into a text format. It works with both IPv4 and IPv6. It also, optionally, converts a port number into a text format number or service name.

The declaration for getnameinfo() can be seen in the following code:

int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
char *host, socklen_t hostlen,
char *serv, socklen_t servlen, int flags);

The first two parameters are passed in from the ai_addr and ai_addrlen fields of struct addrinfo.

The next two parameters, host and hostlen, specify a character buffer and buffer length to store the hostname or IP address text.

The following two parameters, serv and servlen, specify the buffer and length to store the service name.

If you don't need both the hostname and the service, you can optionally pass in only one of either host or serv.

Flags can be a bitwise OR combination of the following:

  • NI_NAMEREQD requires getnameinfo() to return a hostname and not an address. By default, getnameinfo() tries to return a hostname but returns an address if it can't. NI_NAMEREQD will cause an error to be returned if the hostname cannot be determined.
  • NI_DGRAM specifies that the service is UDP-based rather than TCP-based. This is only important for ports that have different standard services for UDP versus TCP. This flag is ignored if NI_NUMERICSERV is set.
  • NI_NUMERICHOST requests that getnameinfo() returns the IP address and not a hostname.
  • NI_NUMERICSERV requests that getnameinfo() returns the port number and not a service name.

For example, we can use getnameinfo() as follows:

char host[100];
char serv[100];
getnameinfo(address->ai_addr, address->ai_addrlen,
host, sizeof(host),
serv, sizeof(serv),
0);

printf("%s %s ", host, serv);

In the preceding code, getnameinfo() attempts to perform a reverse DNS lookup. This works like the DNS queries we've done in this chapter so far, but backward. A DNS query asks which IP address does this hostname point to? A reverse DNS query asks instead, which hostname does this IP address point to? Keep in mind that this is not a one-to-one relationship. Many hostnames can point to one IP address, but an IP address can store a DNS record for only one hostname. In fact, reverse DNS records are not even set for many IP addresses.

If address is a struct addrinfo with the address for example.com port 80 (http), then the preceding code might print as follows:

example.com http

If the code prints something different for you, it's probably working as intended. It is dependent on which address is in address and how the reverse DNS is set up for that IP address. Try it with a different address.

If, instead of the hostname, we would like the IP address, we can modify our code to the following:

char host[100];
char serv[100];
getnameinfo(address->ai_addr, address->ai_addrlen,
host, sizeof(host),
serv, sizeof(serv),
NI_NUMERICHOST | NI_NUMERICSERV);

printf("%s %s ", host, serv);

In the case of the previous code, it might print the following:

93.184.216.34 80

Using NI_NUMERICHOST generally runs much faster too, as it doesn't require getnameinfo() to send off any reverse DNS queries.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.202.103