Wandering Thoughts archives

2022-08-04

The odd return value of the original 4.2 BSD gethostbyname()

In my entry on the history of looking up host addresses in Unix, I touched on how from the beginning gethostbyname() had an issue in its API, one that the BSD Unix people specifically called out in its manual page's BUGS section:

All information is contained in a static area so it must be copied if it is to be saved. [...]

But there is another oddity in how the original gethostbyname() behaved and what it returned. The gethostbyname() API returns a pointer to a 'struct hostent', which in 4.2 BSD was documented as:

struct  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;     /* address */
};

The oddity is that in 4.2 BSD, gethostbyname() could return only a single IP address for your host, although the host could have several names (a single 'official' name and then aliases).

The reason for this behavior is that in 4.2 BSD, everything was looked up in /etc/hosts, and the specific behavior for doing this was, to quote the manual page:

Gethostbyname and gethostbyaddr sequentially search from the beginning of the file until a matching host name or host address is found, or until EOF is encountered.

Famously, these functions return the first match (and only the first match) that they find even if there are additional matching entries. An /etc/hosts line has the format:

127.0.0.1    localhost.localdomain localhost myalias

Which is to say, a single IP address but then an official name with additional optional aliases. The 4.2 BSD gethostbyname() API is designed to return exactly this information, which means that you get one IP address but multiple host names. The implication of this is that in 4.2 BSD, if you put the same name on multiple IP addresses in /etc/hosts (perhaps because your host had multiple interfaces), looking up the name would only ever return the first address.

This is exactly backward from the information that DNS naturally provides you when you look up a host by name; the host may easily have multiple IP addresses, but if it has other names there's no natural way for DNS to tell you. As a result, the 'struct hostent' in 4.3 BSD changed (cf):

struct  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] /* address, for backward compatibility */

Now your gethostbyname() lookups could return multiple IP addresses, and still potentially multiple names too. In practice I suspect that name server lookups in 4.3 BSD mostly returned an empty h_aliases list.

(I believe that most gethostbyname() implementations still only returned the first entry they found in /etc/hosts if they searched it, rather than continuing through the whole file and merging the information together from all matching lines.)

Sidebar: Dealing with multiple interfaces in /etc/hosts

If you had a host with multiple IP addresses, my memory is that you gave the additional IPs special names:

192.168.1.1   server server-net1
192.168.2.1   server-net2
192.168.3.1   server-dev

I believe people were inconsistent about whether the additional IPs should have 'server' as their official name, with the per-interface names always aliases. On the one hand, it made gethostbyaddr() give you the official name as, well, the official name; on the other hand, it meant that a gethostbyname() on the official name you'd just gotten back would give you a different IP address.

unix/GethostbynameOddOriginalAPI written at 23:08:19; Add Comment

Link: The MGR Window System

The MGR Window System (via) is a brief introduction to MGR, an interesting and under-mentioned Unix windowing system, including a screenshot. I once used MGR myself and have reasonably fond memories of it, so it's nice to see more writing about it on the Internet.

(And looking at my old entry I see that I linked to this article there in HTTP version. Still, I encourage you to read about MGR. It's a path not taken in Unix window systems.)

links/TheMGRWindowSystem written at 12:46:19; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.