|
#include <stdio.h> |
|
#include <string.h> |
|
#include <netdb.h> |
|
#include <stdlib.h> |
|
#include <arpa/inet.h> |
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
struct addrinfo hints; |
|
struct addrinfo *result = NULL; |
|
|
|
int err; |
|
|
|
if (argc != 2) { |
|
fprintf(stderr, "Usage: %s [hostname]\n", argv[0]); |
|
exit(EXIT_FAILURE); |
|
} |
|
|
|
char *hostname = argv[1]; |
|
|
|
memset(&hints, 0, sizeof(hints)); |
|
hints.ai_socktype = SOCK_STREAM; |
|
hints.ai_family = AF_UNSPEC; |
|
|
|
if ((err = getaddrinfo(hostname, NULL, &hints, &result)) != 0) { |
|
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(err)); |
|
exit(EXIT_FAILURE); |
|
}; |
|
|
|
struct addrinfo *rp; |
|
int i; |
|
for (rp = result, i = 0; rp != NULL; rp = rp->ai_next, i++) { |
|
char resolve_addr[INET6_ADDRSTRLEN]; |
|
char reverse_addr[INET6_ADDRSTRLEN]; |
|
|
|
inet_ntop(rp->ai_family, &((struct sockaddr_in *) rp->ai_addr)->sin_addr, resolve_addr, sizeof(resolve_addr)); |
|
|
|
struct sockaddr *sa; |
|
socklen_t len; |
|
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; |
|
|
|
struct sockaddr_in resolve_sockaddr; |
|
resolve_sockaddr.sin_family = ((struct sockaddr_in *) rp->ai_addr)->sin_family; |
|
resolve_sockaddr.sin_addr = ((struct sockaddr_in *) rp->ai_addr)->sin_addr; |
|
if (getnameinfo((const struct sockaddr *) &resolve_sockaddr, len, |
|
hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) == 0) { |
|
strcpy(reverse_addr, hbuf); |
|
} else { |
|
strcpy(reverse_addr, "not resolved"); |
|
} |
|
|
|
char *type; |
|
switch (rp->ai_family) { |
|
case AF_INET: |
|
type = "v4"; |
|
break; |
|
case AF_INET6: |
|
type = "v6"; |
|
break; |
|
default: |
|
break; |
|
} |
|
printf("[%s] %s -> %s\n", type, resolve_addr, reverse_addr); |
|
} |
|
|
|
freeaddrinfo(result); |
|
} |