gethostbyname

Wie sieht's aus?

#include <netdb.h>

extern int h_errno;

struct hostent *gethostbyname(const char *name);
    

Was tut's?

Mit gethostbyname() wandelt man einen Hostnamen in die dazugehörigen IP-Adressen um. Dazu wird vom System eine struct hostent{} angelegt, und ein Zeiger darauf zurückgeliefert. Die Struktur sieht in etwa wie folgt aus:

struct  hostent {
    char    *h_name;        /* official name of host */
    char    **h_aliases;    /* alias list */
    int     h_addrtype;     /* host 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]  /* address, for backward compatibility */
    

In h_name steht der offizielle Name, während h_aliases ein nullterminiertes Array aus Alias-Namen ist. Ebenso ist h_addr_list ein nullterminiertes Array aus Adressen, allerdings im Binärformat. Das char* täuscht hier und stammt aus Zeiten, in denen man noch nicht void* für generische Zeigertypen kannte. Man castet also einfach auf eine struct in_addr* und es passt.

Der Rückgabewert ist NULL wenn's nicht geklappt hat. Unter UNIX liegt in der Variablen h_errno der etwaige Fehlercode, den man dann mit der Funktion herror() auswerten kann. Unter Windows ist WSAGetLastError() gefragt.

Was macht der Parameter?

Der Parameter ist der Hostname, den man aufgelöst haben will. Während unter UNIX scheinbar (lies: unter Linux und FreeBSD war's so) auch IP-Adressen akzeptiert werden, gibt dies unter Windows einen Fehler. Um portabel zu bleiben sollte man also vorher inet_aton() oder inet_addr() bemühen, um zu sehen ob es sich um eine IP-Adresse handelt.

Wie verwende ich es?

struct sockaddr_in addr;
struct hostent *host;
...
host = gethostbyname("www.freebsd.org");
if (!host)
{
    herror("gethostbyname() failed");
    return 1;
}
...
addr.sin_addr = *(struct in_addr*) host->h_addr;
...