Subject: Re: dhcpd
To: Hisashi T Fujinaka <email@example.com>
From: Greg Troxel <firstname.lastname@example.org>
Date: 09/12/2007 19:48:02
[dhclient fails with sys/net/if.c 1.200]
I am also seeing trouble with dhclient. The SIOCGIFCONF interface is
tricky, and it may be that moving to struct sockaddr_storage results in
different interpretations of what the API should be. racoon works fine
with the new version.
It's not surprising both dhclient and dhcpd fail; they use the same
Can anyone run them under gdb and see how they cope with parsing the
results of SIOCGIFCONF?
But, I can see the problem; dhclient checks the size of the sockaddr in
ifreq against struct sockaddr, not against sizeof(ifreq).
There's also another bug, in that the 'was the buffer big enough check'
is unreliable. But that's not what's causing trouble now for most
So, this comes down to whether the API for struct ifreq was
size is determined by sa_len if size is > struct sockaddr
size is determined by sa_len if size is > (union in ifreq for
sockaddrs, and hence the sockaddr actually needs to extend beyond
racoon assumed the latter. The former is crazy - it means that an IPv4
address results in ifreq spacing of struct ifreq (144 bytes), because
sockaddr_in fits in sockaddr. But sockaddr_dl or sockaddr_in6 is
bigger, and would result in *smaller* struct ifreq, exactly being big
The real problem is that SIOCGIFCONF never had a real API definition.
I think the right fix is to change dhcp to use sizeof (ifreq.ifr_ifru)
instead of sockaddr for deciding if more space is needed. This declares
that we follow the 2nd choice of what the API used to be.