C Programming

Gethostbyname() Function in C Language

The C language has a large number of functions for programming the sockets. Many of them are used to obtain necessary information from the host to which a connection is to be made. The information that this type of function retrieves is essential for a successful connection since it involves the domain addresses, port numbers, and so on.

In this Linux Hint article, you will learn all about the gethostbyname() function which is most commonly used to resolve and obtain the IP addresses from the host names.

We will show you the syntax of this function and the theoretical description of how it works, its input and output arguments, the data type that is used in each case, and its correct declaration.

We then apply what we learned through the practical examples, including the code snippets and images, where we implement the gethostbyname() function to resolve and obtain the hostname addresses.

Syntax of the Gethostbyname() Function in C Language

struct hostent *gethostbyname(const char *name);

Description of the Gethostbyname() Function in C Language

The gethostbyname() function returns the IP address, official name, and address family of a hostname. This function asks the server to resolve and return the address of the hostname which is specified as a string or pointer to it in its single input argument name.

If no error occurs, gethostbyname() returns a pointer to a structure of type “hostent” which stores the hostname information. If an error occurs, a NULL pointer is returned and the error identification code can be retrieved via the h_errno global variable.

Hostnames are usually associated with a single address, but there are cases of large platforms that have multiple associated addresses such as “www.google.com”. For this reason, the “hostent” structures are designed to contain a list of addresses. Each of them can be accessed using the “h_addr_list” array of pointers. Further ahead, there is a special section that explains everything about this type of structure.

Although the gethostbyname() function is considered deprecated and has been replaced by getaddrinfo(), its simplicity in method invocation and input arguments makes it very useful when you only need the address of a hostname.

The gethostbyname() function, as well as all other functions of the gethostXXXX() family, the structures and variables they use, are declared in the “netdb.h” header. So, you must include them in your code like in the following:

#include <netdb.h>

How to Get the Address of a Hostname with the Gethostbyname() Function in C Language

In this example, we will use the gethostbyname() function to get the address and official name of the “www.kernel.org” hostname.

Step 1: The first step is to insert the required headers and create a main() function that returns an empty value.

Step 2: Inside the main() function, we declare the pointer host to a structure of type hostent which serves as the output argument of gethostbyname(). We also declare a 256-character array called “buffer” which stores the string that contains the name of the host that we pass as the input argument.

Step 3: After declaring the variables and structure that we use, we call the gethostbyname() function, passing the buffer as the input argument and the host structure as the output arguments.

Step 4: If the function returns successfully, the next step is to display the official name and address. For this, we use the printf() function in two calls. The first call shows the official name of the domain, a string that is pointed to by the h_name element of the host structure. The second call shows the address that is stored in h_addr_list [0], defined as h_addr, which we convert to a string using the inet_ntoa() function.

The following is the complete code with all four steps for this example:

//Step 1

#include <stdio.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

void main()
//Step 2
{
structhostent *host;
char buffer [255] = "www.kernel.org";

//Step 3
host = gethostbyname( buffer );

//Step 4
printf("\nIP address of %s is: ", host->h_name );
printf("%s\n\n",inet_ntoa (*(structin_addr*)host->h_addr));
}

The following image shows the compilation and execution of this code. As we can see, gethostbyname() obtains an information from the “www.kernel.org” domain and stores it in a “hostent” structure.

The Hostent Structure

The “hostent” structure stores the useful data which are provided by the server when a query is made with functions such as gethostbyname(). These socket connection is prequeried to resolve the addresses and returns the information such as the domain name, address family, and a list of addresses if more than one exists. You can see this structure along with a detailed description of each element in the following:

struct hostent
{  
char *h_name;                
char **h_aliases;            
inth_addrtype;              
inth_length;                
char **h_addr_list;            
#defineh_addrh_addr_list[0]  
};

h_name: This is a pointer to a string with the domain name for which it is queried.

h_aliases: It is a list of alternative names.

h_addrtype: This member specifies the address family for which it is queried.

h_length: It specifies the size of the address.

h_addr_list: This is the pointer to a list of address pointers. If the server returns more than one address for the queried name, each is accessed via this list pointer.

h_addr: For simplicity, this structure defines the h_addr as a pointer to the first address in the h_addr_list. Access is through this definition.


Errors that Can Occur when Using the Gethostbyname() Function: How to Recognize and Identify Them

The gethostbyname() function returns a null pointer in case of an error. The easiest way to detect an error is to use an “if” condition where the input condition is the output pointer with a NULL value. The following is a code snippet that shows this technique:

if ((host = gethostbyname( buffer )) == NULL){

printf( "An error occurred while trying to get information from the server.");

}

When an error occurs, its numerical identification value is automatically stored in the h_errno global variable. The definitions of the errors and their numerical representation are specified in the “netdb.h” header.

The following is an excerpt from the “netdb.h” header with the errors that the gethostbyname() function can generate, their numerical value in h_errno, and a brief description of each error:

Definition Value Error
HOST_NOT_FOUND 1 Host not found.
TRY_AGAIN 2 Non-Authoritative. Host not found.
NO_RECOVERY 3 Non recoverable error.
NO_DATA 4 Valid name, no data record of requested type.

The easiest way to identify an error is to open a conditional switch jump within the “if” condition that we saw earlier. The jump condition is the h_errno variable. Each case is the definition of each of the errors that we just described.

Now, let us look at the code of the first example where we insert this method to detect and identify the errors in step 3.

//Step 1

#include <stdio.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>

void main()

void main()

//Step 2
{
structhostent *host;
char buffer [255] = "www.000000000.com";

//Step 3
if ((host=gethostbyname(buffer))==NULL){

    switch (h_errno){
    case HOST_NOT_FOUND:
    printf("Host not found. Error %i\n", h_errno);
    break;
    case TRY_AGAIN:
    printf("Non-Authoritative. Host not found. Error %i\n", h_errno);
    break;
    case NO_DATA:
    printf("Valid name, no data record of requested type. Error %i\n", h_errno);
    break;
    case NO_RECOVERY:
    printf("Non recoverable error. Error %i\n", h_errno);
    break;
   
    }
   }

Else{
//Step 4
printf("\nIP address of %s is: ", host->h_name );
printf("%s\n\n",inet_ntoa (*(structin_addr*)host->h_addr));
     }
}

As you can see, we specify a non-existent domain in the buffer that serves as the input argument to the gethostbyname() function in this case. This results in an error that is identified in the conditional jump switch.

The following image shows the compilation and execution of this code. In this case, the gethostbyname() function could not find the host. So, the program jumps to the

HOST _NOT_ FOUND case of the switch condition:

Conclusion

In this Linux Hint article, we showed you how to use the gethostbyname() function to get an information about a hostname. We learned the theoretical description of how it works and how the input and output arguments are composed, including a special section which describes how a “hostent” structure is composed.

We then implemented the use of this function in practical examples. In doing so, we used the code snippets to show the necessary headers for its use, the declaration of structures and variables for their arguments, and the conversion and display of the obtained information.

In addition, we included a section which explains the possible errors that this function can generate and taught the techniques to detect and identify them.

As we have seen in this article, the simplicity of this function and its fast implementation means that it is still useful, even though it was considered obsolete.

About the author

Julio Cesar

Julio Cesar is a 42 years old programmer with 8 years of experience in embedded systems development, 6 years developing firmware for user interfaces in C and C++. Additionally he has 2 years of experience developing scripts for network devices and 3 years as developer of high frequency PCB (Printed Circuit Board).