Re: Question about SIOCGIFCONF

From: Steven Whitehouse
Date: Fri May 28 2010 - 06:13:10 EST


Hi,

On Fri, 2010-05-28 at 06:57 +0200, Eric Dumazet wrote:
> Le jeudi 27 mai 2010 Ã 21:02 -0600, Jeffrey Merkey a Ãcrit :
> > Why is SIOGICONF only instrumented to return a single interface lo for
> > example. I noticed that ifconfig always uses /proc/net/dev but the
> > older SIOCGIFCONF ioctl seems to be busted. Anyone have an
> > explanation or is this just how the shit is these days or is the
> > fucking thing broken (seems to be). ?
>
> Shit comes from you eyes maybe ?
>
> Correction : Shit comes from your eyes, definitely.
>
> Proof :
>
> # strace -o /tmp/STRACE ifconfig -a
> # grep SIOCGIFCONF /tmp/STRACE
> ioctl(4, SIOCGIFCONF, {120, {{"lo", {AF_INET, inet_addr("127.0.0.1")}},
> {"wlan0", {AF_INET, inet_addr("192.168.1.21")}}, {"ppp0", {AF_INET,
> inet_addr("10.150.51.210")}}}}) = 0
>
>
> Part of ifconfig :
>
> ifc.ifc_buf = NULL;
> for (;;) {
> ifc.ifc_len = sizeof(struct ifreq) * numreqs;
> ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
>
> if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
> perror("SIOCGIFCONF");
> goto out;
> }
> if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
> /* assume it overflowed and try again */
> numreqs += 10;
> continue;
> }
> break;
> }
>
> maybe numreqs should be firt initialized to 64, then doubled each
> round...
>

Yes, except that this will fail if you add a protocol that is not known
about by ifconfig and it has a struct sockaddr which is larger than the
16 bytes allowed for in the ifreq. There used to be a DECnet
implementation of this ioctl() but we had to get rid of it because it
broke every single SIOCGFICONF using program (including ifconfig) on the
system for that reason.

This is partly historical. Some systems have a struct sockaddr which
includes a length parameter which means that you can always parse the
returned values, even if they are larger than 16 bytes and the protocol
is unknown. Linux does not have this length field, so you have to know
in advance a full list of all protocols which have sockaddr's greater
than 16 bytes in length in order to parse the results.

The upshot of all that is that it is much better to use rtnetlink, as
per iproute2 instead of this ioctl which is obsolete for most purposes.
A quick grep through the code suggests that ipv4 is the only protocol
which implements this ioctl currently,

Steve.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/