Re: SOLVED: lo0 not in ioctl( SIOCGIFCONF )



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 <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)) );
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 _______________________________________________
freebsd-net@xxxxxxxxxxx mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscribe@xxxxxxxxxxx"

Relevant Pages

  • Re: lo0 not in ioctl( SIOCGIFCONF )
    ... struct ifreq *ifr, *lifr; ... bzero(ifr, sizeof(*ifr) * n); ... There are several problems with this loop. ... Yes, your algorithm is O), but allocating a larger ...
    (freebsd-net)
  • Re: Ada Popularity: Comparison of Ada/Charles with C++ STL (and Perl)
    ... >> Here the iterator type and its constraint are constructed out of the ... for Index in reverse V'First + 4..V'Last loop ... language supports multiple interface inheritance. ...
    (comp.lang.ada)
  • Re: Creating many letters(mail merge) from a single template in C#
    ... I understand that you and users decide to use the interface to insert ... In this case, as a developer, you basically need to loop through all the fields ... generates in order to figure out how best to extract the information you need ... This reply is posted in the Newsgroup; please post any follow question or reply ...
    (microsoft.public.office.developer.automation)
  • Re: writing drivers using C++
    ... Whether a class has overloaded operators is part of ... the interface of that class, ... 'cleanup code' can often be avoided (eg by allocating ... temporary buffers of any kind on the stack, which constructors cannot ...
    (comp.os.linux.development.system)
  • Re: Speed of interfaces vs inheritance
    ... I seem to recall, in years past, that the interface approach was slower. ... Instead of your code doing the loop and worrying about performance, ... public void run{ ... HttpServer h = new HttpServer; ...
    (comp.lang.java.programmer)