From owner-freebsd-net@FreeBSD.ORG Tue Jul 22 07:16:48 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 A50441065679; Tue, 22 Jul 2008 07:16:48 +0000 (UTC) (envelope-from rehsack@web.de) Received: from fmmailgate02.web.de (fmmailgate02.web.de [217.72.192.227]) by mx1.freebsd.org (Postfix) with ESMTP id 31C528FC20; Tue, 22 Jul 2008 07:16:47 +0000 (UTC) (envelope-from rehsack@web.de) Received: from smtp05.web.de (fmsmtp05.dlan.cinetic.de [172.20.4.166]) by fmmailgate02.web.de (Postfix) with ESMTP id B7874E6B53BD; Tue, 22 Jul 2008 09:16:46 +0200 (CEST) Received: from [87.149.238.59] (helo=waldorf.muppets.liwing.de) by smtp05.web.de with esmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1KLC74-0001Hj-00; Tue, 22 Jul 2008 09:16:46 +0200 Message-ID: <48858948.9020403@web.de> Date: Tue, 22 Jul 2008 07:16:24 +0000 From: Jens Rehsack User-Agent: Thunderbird 2.0.0.14 (X11/20080703) MIME-Version: 1.0 To: Brooks Davis 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> <20080721224618.GH1699@lor.one-eyed-alien.net> In-Reply-To: <20080721224618.GH1699@lor.one-eyed-alien.net> Content-Type: multipart/mixed; boundary="------------050202000507030102060902" Sender: rehsack@web.de X-Sender: rehsack@web.de X-Provags-ID: V01U2FsdGVkX19c5FGype9FmIOxGiRGqw/C7U3jblmBY27iB7i6 YuMfpn7jFO0MjddkLyFTxMIqltJQZfthE3ennQLRIsSJLq3H4P vrnP1ydgM= X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Cc: FreeBSD Net Subject: Re: SOLVED: 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: Tue, 22 Jul 2008 07:16:48 -0000 This is a multi-part message in MIME format. --------------050202000507030102060902 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Brooks Davis wrote: > 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, >>>>>> >>>>>> maybe this question is better asked in this list ... >>>>>> >>>>>> 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 implementing >>>>>> 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 .. >>>>> The attachment didn't make it through. >>>>> >>>>> -- Brooks >>>> Copy&Paste starts here ... >>>> #include >>>> #include >>>> #include >>>> #include >>>> #include >>>> #include >>>> #include >>>> #include >>>> >>>> #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 >>>> >>>> int >>>> main() >>>> { >>>> struct ifconf ifc; >>>> struct ifreq *ifr, *lifr; >>>> int fd; >>>> unsigned int n; >>>> >>>> fd = socket( AF_INET, SOCK_STREAM, 0 ); >>>> bzero(&ifc, sizeof(ifc)); >>>> n = 3; >>>> ifr = calloc( ifc.ifc_len, sizeof(*ifr) ); >>>> do >>>> { >>>> n *= 2; >>>> ifr = realloc( ifr, sizeof(*ifr) * n ); >>>> bzero( ifr, sizeof(*ifr) * n ); >>>> ifc.ifc_req = ifr; >>>> ifc.ifc_len = n * sizeof(*ifr); >>>> } while( ( ioctl( fd, SIOCGIFCONF, &ifc ) == -1 ) || ( >>>> ifc.ifc_len == 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 <=. 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. >> Thanks - that was the information I miss. I'll try tomorrow (it's slightly >> late here) and send back the result. >> Using <= should produce an endless loop, but maybe checking if ifc.ifc_len >> <= (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. Actually, because there're very different sizes of sockaddr's (sockaddr_in, sockaddr_in6, ...), I require at least a page must be left over. Because of other OS may support return of errors in overflow, I didn't remove the check - finally it must run on AIX, Windows and Linux, too. >>>> lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len]; >>>> >>>> while (ifr < lifr) > { >>>> printf( "%s\n", ifr->ifr_name ); >>>> ifr = (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. >> The _SIZEOF_ADDR_IFREQ macro should handle that correctly, shouldn't it? > > Right here as well. Finally - I must enhance this using SA_LEN if available to support systems without sa_len member support. I'll try it in office with our linux machines there, because I don't have any penguins at home ;) >>> 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. >> 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. By the way, because I'm looking for interfaces, I skip everything which is no AF_LINK - should work, too (and does for my test-machines ...). Final question: would it make sense to submit a patch against ports/net/p5-Net-Interface using this knowledge to unbreak the port, or must I submit the patch to CPAN and hope, that it will be committed fastly? /Jens --------------050202000507030102060902--