// 2016-01-10
// Look up host by either address or name.

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>

int main (int argc, char **argv) {
  struct addrinfo hint, *res, *ri;
  int ret;
  char name[256], addr[256];

  if (argc != 2) {
    fprintf (stderr, "Usage: %s address|name\n", argv[0]);
    return -1;
  }

  memset(&hint, 0, sizeof hint);
  hint.ai_family   = PF_UNSPEC;
  hint.ai_socktype = SOCK_STREAM;   // Reduce number of responses
  hint.ai_protocol = IPPROTO_TCP;   // Same
  ret = getaddrinfo(argv[1], NULL, &hint, &res);
  if (ret)
    fprintf (stderr, "getaddrinfo: %s\n", gai_strerror(ret));
  else if (!res)
    printf ("getaddrinfo returned null\n");
  else
    for (ri=res; ri!=NULL; ri=ri->ai_next) {
      void *src = NULL;
      strcpy(addr, "?");
      switch (ri->ai_family) {
      case AF_INET:
        src = &(((struct sockaddr_in *)(ri->ai_addr))->sin_addr);
	break;
      case AF_INET6:
	src = &(((struct sockaddr_in6 *)(ri->ai_addr))->sin6_addr);
	break;
      }
      if (src && (!inet_ntop(ri->ai_family, src, addr, sizeof(addr))))
	perror("inet_ntop");
      ret = getnameinfo(ri->ai_addr, ri->ai_addrlen, name, sizeof(name),
			NULL, 0, NI_NAMEREQD);
      if (ret) {
	fprintf (stderr, "getnameinfo: %s\n", gai_strerror(ret));
	strcpy(name, "?");
      }
      printf ("%39s  %s\n", addr, name);
    }
  return 0;
}
