Unix Network Programming Manual
Getting Host Data
In various situations, you may find that you have one piece of
information about a host, but you need others. For example, a host
typically has an Internet address, an Internet name and possibly
alias names. If you were writing a client process, you might prefer to
have the user specify the name of the server machine to use and then
find the address. For example, if you use ftp, it is much more
convenient to use ftp bozo.clown.edu than ftp 123.32.184.19.
This conversion can be accomplished with the gethostbyname
function.
struct hostent *gethostbyname (name)
char *name
If you pass the name of a host, it returns a pointer to a structure with
the following form:
hostent
{
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses from name server */
}
#define h_addr h_addr_list[0]
For example, if you execute the following call in a program,
struct hostent *host;
host = gethostbyname ("esus.cs.montana.edu");
and print the host structure, you will get:
h_name = esus.cs.montana.edu
h_aliases = esus
h_addrtype = 2
h_length = 4
h_addr_list = 153.90.192.1
Note that there could be multiple aliases and addresses. h_addrtype = 2
indicates the AF_UNIX family.
Similarly, if you have the address of a machine, but not the name,
such as after accepting a connection or receiving a datagram, you can
find the name by using gethostbyaddr
struct hostent *gethostbyaddr(addr, len, type)
char *addr
size_t len,
int type;
Where the address is passed as a character string of length len
and the type is specifically given. For example the following code
finds out what machine has just made a connection with the server.
sockaddr_in addr;
struct hostent *host;
clientsock = accept (sock, &addr, &addrlen);
host = gethostbyaddr (&addr.sin_addr, sizeof (struct in_addr),
addr.sin_family);
gethostbyaddr is designed to work for all types of addresses,
so each part of the data field has to be treated in a general way,
rather than as a known Internet type of address. It should be noted that
the addresses are stored in the hostent structure in network byte order
format, so they need not be converted before moving them to address
structures, such as sockaddr_in. For example,
struct hostent *host;
struct sockaddr_in addr;
host = gethostbyname ("esus.cs.montana.edu");
addr . sin_addr . s_addr = (unsigned int) host -> h_addr_list [0];
will work to move the address into the address structure. However, it
is typical to avoid data typing problems by using something like this.
struct hostent *host;
struct sockaddr_in addr;
host = gethostbyname ("esus.cs.montana.edu");
memcpy (&addr . sin_addr . s_addr, host -> h_addr_list [0],
sizeof (addr . sin_addr . s_addr));