Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jul 2008 17:24:16 -0500
From:      Brooks Davis <brooks@freebsd.org>
To:        Jens Rehsack <rehsack@web.de>
Cc:        FreeBSD Net <freebsd-net@freebsd.org>
Subject:   Re: lo0 not in ioctl( SIOCGIFCONF )
Message-ID:  <20080721222416.GG1699@lor.one-eyed-alien.net>
In-Reply-To: <4884FFFF.9090908@web.de>
References:  <4884F401.4050103@web.de> <20080721204820.GE1699@lor.one-eyed-alien.net> <4884FFFF.9090908@web.de>

next in thread | previous in thread | raw e-mail | index | archive | help

--Y+xroYBkGM9OatJL
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Jul 21, 2008 at 09:30:39PM +0000, Jens Rehsack wrote:
> Brooks Davis wrote:
>>> Hi,
>>>=20
>>> maybe this question is better asked in this list ...
>>>=20
>>> I was searching why ports/net/p5-Net-Interface was not working as
>>> expected and found some reasons. Most of them I can answer by implement=
ing
>>> some test code as attached, but now I'm wondering why em0 is shown twice
>>> and lo0 is not included.
>>> The same situation on another machine ..
>>=20
>> The attachment didn't make it through.
>>=20
>> -- Brooks
>=20
> Copy&Paste starts here ...
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/socket.h>
> #include <net/if.h>
> #include <errno.h>
> #include <strings.h>
> #include <sys/ioctl.h>
> #include <ifaddrs.h>
>=20
> #ifndef _SIZEOF_ADDR_IFREQ
> #define	_SIZEOF_ADDR_IFREQ(ifr) \
> 	((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \
> 	 (sizeof(struct ifreq) - sizeof(struct sockaddr) + \
> 	  (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))
> #endif
>=20
> int
> main()
> {
>     struct ifconf ifc;
>     struct ifreq *ifr, *lifr;
>     int fd;
>     unsigned int n;
>=20
>     fd =3D socket( AF_INET, SOCK_STREAM, 0 );
>     bzero(&ifc, sizeof(ifc));
>         n =3D 3;
>         ifr =3D calloc( ifc.ifc_len, sizeof(*ifr) );
>         do
>         {
>             n *=3D 2;
>             ifr =3D realloc( ifr, sizeof(*ifr) * n );
>             bzero( ifr, sizeof(*ifr) * n );
>             ifc.ifc_req =3D ifr;
>             ifc.ifc_len =3D n * sizeof(*ifr);
>         } while( ( ioctl( fd, SIOCGIFCONF, &ifc ) =3D=3D -1 ) || ( ifc.if=
c_len=20
> =3D=3D n * sizeof(*ifr)) );

There are several problems with this loop.  First, icoctl won't return
an error in the overflow case because that's not how SIOCGIFCONF works.
SIOCGIFCONF is badly designed in a number of ways, but that's how it
is.  Second, checking that the array is completely full isn't at all
reliable because what is returned is actually ifreq structures which
might or might not vary in length as they contain addresses.  Thus you
need <=3D.  Third, you should start by allocating a significant amount of
space.  Yes, your algorithm is O(sqrt(n)), but allocating a larger
value has effectively no cost so you might as well save some system calls
on average.

>     lifr =3D (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
>
>     while (ifr < lifr) >     {
>         printf( "%s\n", ifr->ifr_name );
>         ifr =3D (struct ifreq *)(((char *)ifr) + _SIZEOF_ADDR_IFREQ(*ifr)=
);
>     }

This loop has two problems.  First, the ifr's are variable length so you
immediately go off into the weeds.  Second, there is at least one per
interface and one per address so you to keep track of the last interface
name and not repeat them.

-- Brooks

>=20
>     return 0;
> }
> _______________________________________________
> freebsd-net@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-net
> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
>=20

--Y+xroYBkGM9OatJL
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (FreeBSD)

iD8DBQFIhQyQXY6L6fI4GtQRAoifAJ46MILVTny+Nd4S8sUcQ8CcJjrw0gCfRnQV
F1kAkRd2NHvWg6uLiVfSNpg=
=91SQ
-----END PGP SIGNATURE-----

--Y+xroYBkGM9OatJL--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080721222416.GG1699>