what is the correct way to use gethostbyname() in c to retrive the real ip address of the host. Also why would people say DHCP would put this approach in potential danger ?
Asked
Active
Viewed 4,260 times
0
-
https://msdn.microsoft.com/en-us/library/windows/desktop/ms738524(v=vs.85).aspx – Abhineet May 06 '15 at 06:25
-
The *correct* approach is to not use `gethostbyname()` at all. It is deprecated. Use `getaddrinfo()` instead. As for why either is *potentially* dangerous is because it relies on DNS lookups, and DNS attacks and faulty DNS configurations can make false information be reported. – Remy Lebeau May 07 '15 at 02:25
2 Answers
1
A supplement to Jordan's answer(He has been inactive for 7 years so there is no way to edit his answer...)
- A typo
char * host_name = "mail.google.com";
- After getting a vector of
struct in_addr
(v4) orstruct in6_addr
(v6), you can useinet_ntop()
to retrieve the IP address#include <string.h> #include <arpa/inet.h> char ip_address[INET6_ADDRSTRLEN]; // sufficient for both v4 and v6 address memset(ip_address, 0, INET6_ADDRSTRLEN); // for the case of v4 for (int i = 0; address_list[i] != NULL; i++) { inet_ntop(AF_INET, &address_list[i], ip_address, INET_ADDRSTRLEN); } // for the case of v6 for (int i = 0; address_list[i] != NULL; i++) { inet_ntop(AF_INET6, &address_list[i], ip_address, INET_ADDRSTRLEN); } printf("%s", ip_address);
- You may notice the weird type of
hostent.h_addr_list
, why does it have typechar **
, this is a historical problem.
Further reading: why-is-h-addr-list-in-struct-hostent-a-char-instead-of-struct-in-addr
Complete code:
#include <stdio.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
int main() {
char * hostname = "www.google.com";
struct hostent * hp = gethostbyname(hostname);
char ip_address[INET6_ADDRSTRLEN];
memset(ip_address, 0, INET6_ADDRSTRLEN);
struct in_addr ** p1 = NULL;
struct in6_addr ** p2 = NULL;
switch (hp->h_addrtype) {
case AF_INET:
p1 = (struct in_addr **)hp->h_addr_list;
for(int i = 0; p1[i]!=NULL; i+=1) {
inet_ntop(AF_INET, &p1[i], ip_address, INET_ADDRSTRLEN);
printf("%s\n", ip_address);
*ip_address = '\0';
}
break;
case AF_INET6:
p2 = (struct in6_addr **)hp->h_addr_list;
for(int i = 0; p2[i]!=NULL; i+=1) {
inet_ntop(AF_INET6, &p2[i], ip_address, INET6_ADDRSTRLEN);
printf("%s\n", ip_address);
*ip_address = '\0';
}
break;
}
}

Steve Lau
- 658
- 7
- 13
0
The gethostbyname()
function returns information about the host by using DNS to look up the name.
The function's return data type and parameters are shown below:
struct hostent* gethostbyname(const char *name);
An example to extract a list of IP addresses from a hostname (in this case, "mail.google.com") is shown below:
char host_name = "mail.google.com";
struct hostent *host_info = gethostbyname(host_name);
if (host_info == NULL)
{
return(-1);
}
if (host_info->h_addrtype == AF_INET)
{
struct in_addr **address_list = (struct in_addr **)host_info->h_addr_list;
for(int i = 0; address_list[i] != NULL; i++)
{
// use *(address_list[i]) as needed...
}
}
else if (host_info->h_addrtype == AF_INET6)
{
struct in6_addr **address_list = (struct in6_addr **)host_info->h_addr_list;
for(int i = 0; address_list[i] != NULL; i++)
{
// use *(address_list[i]) as needed...
}
}

Remy Lebeau
- 555,201
- 31
- 458
- 770