#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>


int main (int argc, char **argv)
{
	int err;
	char *host=NULL, *service=NULL;
	struct addrinfo hints, *res, *cur;

	if (argc == 1) {
		fprintf(stderr, "Usage: %s <addr> [port]\n", argv[0]);
		exit(1);
	}

	if (argc > 1)
		host = argv[1];
	if (argc > 2)
		service = argv[2];

	memset(&hints, '\0', sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_flags = AI_PASSIVE;
	hints.ai_socktype = SOCK_DGRAM;

	err = getaddrinfo(host, service, &hints, &res);

	if (err) {
		fprintf(stderr, "getaddrinfo failed: %d\n", gai_strerror(err));
		goto out;
	}

	printf("Looking up alternatives for %s (%s)\n", host, service);

	printf("Results:\n");
	printf("====================================\n");
	for (cur = res; cur != NULL; cur = cur->ai_next) {
		char *family;
		char host[NI_MAXHOST], serv[NI_MAXSERV];

		switch (cur->ai_family) {
		case AF_INET:
			family = strdup("inet");
			break;
		case AF_INET6:
			family = strdup("inet6");
			break;
		default:
			err = asprintf(&family, "%d", cur->ai_family);
			break;
		}
		printf("family: %s\n", family);

		free(family);

		err = getnameinfo(cur->ai_addr, cur->ai_addrlen,
				host, sizeof(host), serv, sizeof(serv),
				NI_NUMERICHOST | NI_NUMERICSERV);

		if (!err)
			printf("addr: %s (%s)\n", host, service);

		printf("====================================\n");
	
	}
out:
	freeaddrinfo(res);
	return 0;
}
