2

How can I get the IP-address from a domain name with the top level domain name? In this example get the IP of google.com. And if possible in IPv6 in the correct format.

This is what I've tried so far:

#include <netdb.h>

using namespace std;

int main()
{
    struct hostent* myHostent;
    myHostent = gethostbyname("google.com");
    cout<<myHostent <<"\n";
    //output is a hex code
    cout<<myHostent->h_name<<"\n";
    //output is google.com
    cout<<myHostent->h_aliases;
    //output is a hex code  
}

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
  • `h_aliases` is a pointer to pointer of `char` (i.e. points to multiple C-strings). You need to access further one dimension in to see the strings. – Govind Parmar Feb 04 '20 at 19:20
  • 7
    `gethostbyname()` is deprecated, use `getaddrinfo()` instead. And be prepared to handle the case where the host has more than 1 IP address reported. – Remy Lebeau Feb 04 '20 at 19:21
  • https://linux.die.net/man/3/gethostent - note: `gethostbyname` is deprecated, don't use it. – Jesper Juhl Feb 04 '20 at 19:21
  • Note that what you get is what your DNS server says, that is your ISP. Sometimes this is not the true IP. Also, the hosts file affects these functions. – Michael Chourdakis Feb 04 '20 at 19:39

1 Answers1

2

The domain's IP addresses (yes plural, there can be more than 1) is in the hostent::h_addr_list field, not in the hostent::h_aliases field, eg:

int main()
{
    hostent* myHostent = gethostbyname("google.com");
    if (!myHostent)
    {
        cerr << "gethostbyname() failed" << "\n";
    }
    else
    {
        cout << myHostent->h_name << "\n";

        char ip[INET6_ADDRSTRLEN];
        for (unsigned int i = 0; myHostent->h_addr_list[i] != NULL; ++i)
        {
            cout << inet_ntop(myHostent->h_addrtype, myHostent->h_addr_list[i], ip, sizeof(ip)) << "\n";
        }
    }

    return 0;
}

That said, gethostbyname() is deprecated, use getaddrinfo() instead, eg:

void* getSinAddr(addrinfo *addr)
{
    switch (addr->ai_family)
    {
        case AF_INET:
            return &(reinterpret_cast<sockaddr_in*>(addr->ai_addr)->sin_addr);

        case AF_INET6:
            return &(reinterpret_cast<sockaddr_in6*>(addr->ai_addr)->sin6_addr);
    }

    return NULL;
}

int main()
{
    addrinfo hints = {};
    hints.ai_flags = AI_CANONNAME;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    addrinfo *res;

    int ret = getaddrinfo("google.com", NULL, &hints, &res);
    if (ret != 0)
    {
        cerr << "getaddrinfo() failed: " << gai_strerror(ret) << "\n";
    }
    else
    {
        cout << res->ai_canonname << "\n";

        char ip[INET6_ADDRSTRLEN];
        for(addrinfo addr = res; addr; addr = addr->ai_next)
        {
            cout << inet_ntop(addr->ai_family, getSinAddr(addr), ip, sizeof(ip)) << "\n";
        }

        freeaddrinfo(res);
    }

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770