Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: SIOCGIFCONF ioctl family problems under compat netbsd32



On Mon, Jun 23, 2008 at 10:10:26AM -0400, Greg Troxel wrote:
> Your example code looks incorrect.  Does it work OK on NetBSD/i386?

Unfortunatley no. I forgot to check that a 4.0 binary on -current
NetBSD/i386 works. I was focusing on compat netbsd32 :-(

>   cur = cnf.ifc_req; l = cnf.ifc_len;
>   while (l) {
>     adr = (struct sockaddr *)&cur->ifr_addr;
>     printf("%s %d\n", cur->ifr_name, (int)adr->sa_family);
>     cur++; l -= sizeof(struct ifreq); }
> 
> The problem is that in OSIOCGIFCONF, the rule is that the new structure
> offset is sizeof(struct ifreq) if adr.sa_len <= sizeof(cnf.ifru), and
> adr.sa_len if it's >=.  In SIOCGIFCONF, the same rule works, but
> adr.sa_len < sizeof(cnf.ifru) always, because ifru holds struct
> sockaddr_storage ifru_space.  This case comes up with AF_INET6
> sockaddrs, which are bigger than struct sockaddr, and I think also with
> AF_LINK.
> 
> As a first step, try printing adr->sa_len, sizeof(struct ifreq) and
> sizeof (cnf.ifru).  I think you'll find that with OSIOCGIFCONF on i386
> or amd64, sa_len exceeds sizeof(cnf.ifru) and then the next entry is
> garbage.

Yep. Thanks for the explanation; i knew this one was tricky.
This one works a lot better ;-)

  cur = cnf.ifc_req; l = cnf.ifc_len;
  while (l) {
    adr = (struct sockaddr *)&cur->ifr_addr;
    printf("%s %d\n", cur->ifr_name, adr->sa_family);
#define MAX(a,b) ((a <= b) ? (b) : (a)) 
    s = MAX(adr->sa_len, sizeof(cur->ifr_ifru));
    cur = (struct ifreq *)((char *)cur + sizeof(cur->ifr_name) + s);
    l -= sizeof(cur->ifr_name) + s; }

Thanks again.

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.


Home | Main Index | Thread Index | Old Index