Re: SOLVED: lo0 not in ioctl( SIOCGIFCONF )
- From: Jens Rehsack <rehsack@xxxxxx>
- Date: Tue, 22 Jul 2008 07:16:24 +0000
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:Thanks - that was the information I miss. I'll try tomorrow (it's slightly late here) and send back the result.Brooks Davis wrote:There are several problems with this loop. First, icoctl won't returnCopy&Paste starts here ...Hi,The attachment didn't make it through.
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 ..
-- Brooks
#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>
#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)) );
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.
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.
The _SIZEOF_ADDR_IFREQ macro should handle that correctly, shouldn't it?lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];This loop has two problems. First, the ifr's are variable length so you
while (ifr < lifr) > {
printf( "%s\n", ifr->ifr_name );
ifr = (struct ifreq *)(((char *)ifr) + _SIZEOF_ADDR_IFREQ(*ifr));
}
immediately go off into the weeds.
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 perGood point - if it's sure in this order, this is a good way to handle it.
interface and one per address so you to keep track of the last interface
name and not repeat them.
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 _______________________________________________
freebsd-net@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscribe@xxxxxxxxxxx"
- Follow-Ups:
- Re: SOLVED: lo0 not in ioctl( SIOCGIFCONF )
- From: Brooks Davis
- Re: SOLVED: lo0 not in ioctl( SIOCGIFCONF )
- References:
- lo0 not in ioctl( SIOCGIFCONF )
- From: Jens Rehsack
- Re: lo0 not in ioctl( SIOCGIFCONF )
- From: Brooks Davis
- Re: lo0 not in ioctl( SIOCGIFCONF )
- From: Jens Rehsack
- Re: lo0 not in ioctl( SIOCGIFCONF )
- From: Brooks Davis
- Re: lo0 not in ioctl( SIOCGIFCONF )
- From: Jens Rehsack
- Re: lo0 not in ioctl( SIOCGIFCONF )
- From: Brooks Davis
- lo0 not in ioctl( SIOCGIFCONF )
- Prev by Date: Re: kern/125845: [netinet] [patch] tcp_lro_rx() should make use of hardware IP cksum assistance when available
- Next by Date: Re: FreeBSD NAT-T patch integration [CFR/CFT]
- Previous by thread: Re: lo0 not in ioctl( SIOCGIFCONF )
- Next by thread: Re: SOLVED: lo0 not in ioctl( SIOCGIFCONF )
- Index(es):
Relevant Pages
|