From owner-freebsd-net@FreeBSD.ORG Mon Jul 21 22:45:39 2008 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 19BAD1065672 for ; Mon, 21 Jul 2008 22:45:39 +0000 (UTC) (envelope-from brooks@lor.one-eyed-alien.net) Received: from lor.one-eyed-alien.net (cl-162.ewr-01.us.sixxs.net [IPv6:2001:4830:1200:a1::2]) by mx1.freebsd.org (Postfix) with ESMTP id 874348FC12 for ; Mon, 21 Jul 2008 22:45:38 +0000 (UTC) (envelope-from brooks@lor.one-eyed-alien.net) Received: from lor.one-eyed-alien.net (localhost [127.0.0.1]) by lor.one-eyed-alien.net (8.14.2/8.14.2) with ESMTP id m6LMkIgJ005701; Mon, 21 Jul 2008 17:46:18 -0500 (CDT) (envelope-from brooks@lor.one-eyed-alien.net) Received: (from brooks@localhost) by lor.one-eyed-alien.net (8.14.2/8.14.2/Submit) id m6LMkI2W005700; Mon, 21 Jul 2008 17:46:18 -0500 (CDT) (envelope-from brooks) Date: Mon, 21 Jul 2008 17:46:18 -0500 From: Brooks Davis To: Jens Rehsack Message-ID: <20080721224618.GH1699@lor.one-eyed-alien.net> References: <4884F401.4050103@web.de> <20080721204820.GE1699@lor.one-eyed-alien.net> <4884FFFF.9090908@web.de> <20080721222416.GG1699@lor.one-eyed-alien.net> <48850F72.90204@web.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="a8sldprk+5E/pDEv" Content-Disposition: inline In-Reply-To: <48850F72.90204@web.de> User-Agent: Mutt/1.5.17 (2007-11-01) Cc: FreeBSD Net Subject: Re: lo0 not in ioctl( SIOCGIFCONF ) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Jul 2008 22:45:39 -0000 --a8sldprk+5E/pDEv Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Jul 21, 2008 at 10:36:34PM +0000, Jens Rehsack wrote: > Brooks Davis wrote: >> 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 impleme= nting >>>>> some test code as attached, but now I'm wondering why em0 is shown tw= ice >>>>> and lo0 is not included. >>>>> The same situation on another machine .. >>>> The attachment didn't make it through. >>>>=20 >>>> -- Brooks >>> Copy&Paste starts here ... >>> #include >>> #include >>> #include >>> #include >>> #include >>> #include >>> #include >>> #include >>>=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 ) || (=20 >>> ifc.ifc_len =3D=3D n * sizeof(*ifr)) ); >>=20 >> 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. >=20 > Thanks - that was the information I miss. I'll try tomorrow (it's slightl= y=20 > late here) and send back the result. > Using <=3D should produce an endless loop, but maybe checking if ifc.ifc_= len=20 > <=3D (n/2) * sizeof(*ifr) could bring wanted results ... Oops, you're right. Actually, the condition to check is probably (n*sizeof(*ifr) - ifc.ifc_len < sizeof(*ifr)). Actually, since the size of the returned values aren't actually a multiple of sizeof(*ifr), I'd probably switch to allocating a multiple of 4k. >>> lifr =3D (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; >>>=20 >>> while (ifr < lifr) > { >>> printf( "%s\n", ifr->ifr_name ); >>> ifr =3D (struct ifreq *)(((char *)ifr) + _SIZEOF_ADDR_IFREQ(*if= r)); >>> } >>=20 >> This loop has two problems. First, the ifr's are variable length so you >> immediately go off into the weeds. >=20 > The _SIZEOF_ADDR_IFREQ macro should handle that correctly, shouldn't it? Right here as well. >> 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. >=20 > Good point - if it's sure in this order, this is a good way to handle it. It is in the current implementation and it's hard to imaging that we'd break that. -- Brooks >> -- Brooks >=20 > /Jens >=20 --a8sldprk+5E/pDEv Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (FreeBSD) iD8DBQFIhRG5XY6L6fI4GtQRAl1OAJ9/invMMLU4Ciuqk1VyV1U6z+m5zgCeIr+i 7tpMuvd086cG1D5KmdwIVH4= =uCUk -----END PGP SIGNATURE----- --a8sldprk+5E/pDEv--