#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <iostream>
void Usage(char *progname) {
std::cerr << "usage: " << progname << " hostname" << std::endl;
exit(EXIT_FAILURE);
}
int main(int argc, char **argv) {
int retval;
struct addrinfo hints, *results, *r;
if (argc != 2) {
Usage(argv[0]);
}
// Zero out the hints data structure using memset.
memset(&hints, 0, sizeof(hints));
// Indicate we're happy with both AF_INET or AF_INET6 addresses.
hints.ai_family = AF_UNSPEC;
// Constrain the answers to SOCK_STREAM addresses. [You can use
// the ai_addr field in a result as an argument to connect() or
// bind(), so if you leave ai_socketype as 0 for unconstrained,
// you'll get multiple results for each IP address found, one for
// each socket type.]
hints.ai_socktype = SOCK_STREAM;
// Do the lookup by invoking getaddrinfo(). This could take some
// time, since the resolution may require communicating with one
// or more DNS resolvers out on the Internet.
if ((retval = getaddrinfo(argv[1], nullptr, &hints, &results)) != 0) {
std::cerr << "getaddrinfo failed: ";
// gai_strerror is defined in netdb.h and returns a
// string describing getaddrinfo() error value.
std::cerr << gai_strerror(retval) << std::endl;
return EXIT_FAILURE;
}
// Print the results!
std::cout << "Here are the IP addresses found for '" << argv[1];
std::cout << "'" << std::endl;
for (r = results; r != nullptr; r = r->ai_next) {
// Treat the IPv4 and IPv6 cases differently.
if (r->ai_family == AF_INET) {
char ipstring[INET_ADDRSTRLEN];
struct sockaddr_in *v4addr = (struct sockaddr_in *) r->ai_addr;
inet_ntop(r->ai_family,
&(v4addr->sin_addr),
ipstring,
INET_ADDRSTRLEN);
std::cout << " IPv4: " << ipstring << std::endl;
} else if (r->ai_family == AF_INET6) {
char ipstring[INET6_ADDRSTRLEN];
struct sockaddr_in6 *v6addr = (struct sockaddr_in6 *) r->ai_addr;
inet_ntop(r->ai_family,
&(v6addr->sin6_addr),
ipstring,
INET6_ADDRSTRLEN);
std::cout << " IPv6: " << ipstring << std::endl;
} else {
std::cout << " unknown address family " << r->ai_family << std::endl;
}
}
// Clean up.
freeaddrinfo(results);
return 0;
}