Get ip address from hostname in C using Linux sockets
Socket applications often need to convert hostnames like google.com to their corresponding ip address. This is done through dns requests. The socket api in linux provides functions like gethostbyname and getaddrinfo that can be used to perform the dns requests and get the ip address.
gethostbyname
The first method uses the traditional gethostbyname function to retrieve information about a hostname/domain name.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //for exit(0);
#include<sys/socket.h>
#include<errno.h> //For errno - the error number
#include<netdb.h> //hostent
#include<arpa/inet.h>
int
hostname_to_ip(
char
* ,
char
*);
int
main(
int
argc ,
char
*argv[])
{
if
(argc <2)
{
printf
(
"Please provide a hostname to resolve"
);
exit
(1);
}
char
*hostname = argv[1];
char
ip[100];
hostname_to_ip(hostname , ip);
printf
(
"%s resolved to %s"
, hostname , ip);
printf
(
"\n"
);
}
/*
Get ip from domain name
*/
int
hostname_to_ip(
char
* hostname ,
char
* ip)
{
struct
hostent *he;
struct
in_addr **addr_list;
int
i;
if
( (he = gethostbyname( hostname ) ) == NULL)
{
// get the host info
herror(
"gethostbyname"
);
return
1;
}
addr_list = (
struct
in_addr **) he->h_addr_list;
for
(i = 0; addr_list[i] != NULL; i++)
{
//Return the first one;
strcpy
(ip , inet_ntoa(*addr_list[i]) );
return
0;
}
return
1;
}
|
Compile and Run
$ gcc hostname_to_ip.c && ./a.out www.google.com www.google.com resolved to 74.125.235.16 $ gcc hostname_to_ip.c && ./a.out www.msn.com www.msn.com resolved to 207.46.140.34 $ gcc hostname_to_ip.c && ./a.out www.yahoo.com www.yahoo.com resolved to 98.137.149.56
getaddrinfo
The second method uses the getaddrinfo function to retrieve information about a hostname/domain name. The getaddrinfo supports ipv6 better.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //for exit(0);
#include<sys/socket.h>
#include<errno.h> //For errno - the error number
#include<netdb.h> //hostent
#include<arpa/inet.h>
int
hostname_to_ip(
char
* ,
char
*);
int
main(
int
argc ,
char
*argv[])
{
if
(argc <2)
{
printf
(
"Please provide a hostname to resolve"
);
exit
(1);
}
char
*hostname = argv[1];
char
ip[100];
hostname_to_ip(hostname , ip);
printf
(
"%s resolved to %s"
, hostname , ip);
printf
(
"\n"
);
}
/*
Get ip from domain name
*/
int
hostname_to_ip(
char
*hostname ,
char
*ip)
{
int
sockfd;
struct
addrinfo hints, *servinfo, *p;
struct
sockaddr_in *h;
int
rv;
memset
(&hints, 0,
sizeof
hints);
hints.ai_family = AF_UNSPEC;
// use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if
( (rv = getaddrinfo( hostname ,
"http"
, &hints , &servinfo)) != 0)
{
fprintf
(stderr,
"getaddrinfo: %s\n"
, gai_strerror(rv));
return
1;
}
// loop through all the results and connect to the first we can
for
(p = servinfo; p != NULL; p = p->ai_next)
{
h = (
struct
sockaddr_in *) p->ai_addr;
strcpy
(ip , inet_ntoa( h->sin_addr ) );
}
freeaddrinfo(servinfo);
// all done with this structure
return
0;
}
|