On a running BSD system, a person would use the "ifconfig" command to configure various network interfaces, specifying the IP address, net mask, and such. The ifconfig program uses various ioctl calls to do this fiddling, for example SIOCSIFADDR and SIOCSIFNETMASK. These calls get handled in netinet/in.c We see loops like this:
struct in_ifaddr *ia; for (ia = in_ifaddr; ia; ia = ia->ia_next) if (net == ia->ia_net) return (i & ia->ia_subnetmask);In this loop, we are traversing a singly linked list with the list head "in_ifaddr". It is somewhat unfortunate that the list head and the name of the structure are the same. It is unfortunate because it is a point of confusion in reading the code, and also a nuisance when using grep.
If an ioctl like SIOCSIFADDR or SIOCSIFNETMASK is made and no such entry is present in the list, a new one is created and linked in, then and there. The structure itself is defined in in_var.h and this file also includes the line:
extern struct in_ifaddr *in_ifaddr;I first tripped across this list in in_pcb.c via the following line in the routine in_pcbbind(). Here it is simply checking that the list is non-empty.
if (in_ifaddr == 0) return (EADDRNOTAVAIL);In order to ferret out these calls (and evaluate them) I decided to rename the list head and call it "in_ifaddr_head". I'll also note that NetBSD-1.3 has made some changes, now there is a pointer in the structure "tqh_first". The references are restricted to in.c and in_pcb.c. I comment out the check in in_pcbbind() and away I go.
Kyu / [email protected]