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

#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

#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;
}






Compile and Run

$ gcc hostname_to_ip.c && ./a.out www.google.com
www.google.com resolved to 74.125.235.19

$ gcc hostname_to_ip.c && ./a.out www.yahoo.com
www.yahoo.com resolved to 72.30.2.43

$ gcc hostname_to_ip.c && ./a.out www.msn.com
www.msn.com resolved to 207.46.140.34
Last Updated On : 19th November 2012

Subscribe to get updates delivered to your inbox

16 Comments + Add Comment

  • Explain the program

  • Thank you
    anyone checking this code while running the output….
    ./a.out http://www.google.com

  • First of all, thanks for putting this tutorial up! I have used it as a basis for my next-gen code! Having stated that, let me show you how I have improved it.

    Your getaddrinfo example continuously overwrites the “ip” C-string, until interating through the linked list is finished. Why not simply write to it once at end of the loop, if only getting the last entry is what you REALLY want, but that’s hardly useful! What you want is to make sure you’re using an IP that works!

    “man getaddrinfo” from the terminal. On my OSX, it has nice example of iterating through the list and trying to test a socket connection for TCP. I have turned that example into usable code, integrated with your tutorial’s code:

    http://pastebin.com/cfUw5sG6

    For UDP you can do similar things by implementing a “test” msg for the server to receive and acknowledge with adaptive retransmission timeout.

    • Actually, having learned a little more, I’ve reverted to the newer inet_ntop. Simpler to use, I’m unsure if any power is lost from using it. I think it will be alright. Just thought I would leave evidence of my trail.

  • Thanks very much, while getaddinfo is not always work:

    [[email protected] gethostbyname]$ ./gethostbyname http://www.google.com

    http://www.google.com resolved to 173.194.72.99

    [[email protected] gethostbyname]$ ./getaddrinfo http://www.google.com

    http://www.google.com resolved to 0.0.0.0

    [[email protected] gethostbyname]$ ./getaddrinfo http://www.msn.com

    http://www.msn.com resolved to 131.253.13.140

    [[email protected] gethostbyname]$

    WHY?

    • try changing the following line

      hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6

      to this

      hints.ai_family = AF_INET;

      • Thank you, It works !
        In the manual,
        “The value AF_UNSPEC indicates that getaddrinfo() should return socket addresses for any address family (either IPv4 or IPv6, for example) that can be used with node and service.”
        What is the basis of the judgments using IPv4 or IPv6?

        The server support ipv6 ? or just my pc support IPv6?

    • or call the getaddrinfo function like this

      getaddrinfo( hostname , NULL , NULL , &servinfo);

      that should give the correct ip of the hostname.

  • sir I have error like this—-
    gethostbyname: unknown host
    please resolve this..

    • check your internet connectivity by pinging the host first.
      use the following command at terminal/console

      ping hostname

      if ping replies come correctly, then try the program again and let me know the results.

  • how to get our own ip address?? am getting only loopback address

  • its really helpful

Leave a comment