Discussion:
samba and SIOCGIFCONF
(too old to reply)
Matthias Drochner
2007-12-20 22:20:04 UTC
Permalink
Sorry that I forgot who it was, but someone did some fixes to
SIOCGIFCONF recently. Now the samba pkg exhibits problems
looking up its interface, and it is using SIOCGIFCONF, and the
code (source/lib/interfaces.c) looks highly suspicious.

Could you please get the pkg to work -- this is rather
urgent because a fix would be needed before the pkgsrc Q4
branch.

thanks & best regards
Matthias




-------------------------------------------------------------------
-------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich

Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDirig'in Baerbel Brumme-Bothe
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Dr. Ulrich Krafft (stellv. Vorsitzender), Dr. Sebastian M. Schmidt
-------------------------------------------------------------------
-------------------------------------------------------------------

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2007-12-21 03:28:02 UTC
Permalink
That was me and I don't use samba at all. I am very hesitant to add
patches because I don't understand how it ever could have worked.


From: Greg Troxel <***@ir.bbn.com>
Subject: Re: nmap not working?
To: "Jared D. McNeill" <***@invisible.ca>
Cc: current-***@netbsd.org, pkgsrc-***@netbsd.org
Date: Fri, 09 Nov 2007 19:55:49 -0500

In pkgsrc/net/samba/work/samba-2.0.26a/source/lib/interfaces.c, line 123
has a for loop that uses struct ifreq *ifr as an array in data returned
from SIOCGIFCONF. This is totally bogus and would have failed under 4.4BSD.
With the struct sockaddr_storage change, it should work.

If it doesn't work, someone should gdb this loop.

If it works for some, and fails to find interfaces on systems with many
interfaces, then change buff from 8192 to 32768 or more. Each address
is now 144 bytes, the minimum struct ifreq, because sockaddr_storage is
128 and there's 16 of ifr_name.


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Matthias Drochner
2007-12-21 17:33:56 UTC
Permalink
I am very hesitant to add patches because I don't understand how it
ever could have worked.
Is there some documentation or example how to scan the
result of an SIOCGIFCONF ioctl correctly now?

but anyway, I've patched samba to use getifaddrs() if possible.
It works well now for me.

best regards
Matthias




-------------------------------------------------------------------
-------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich

Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDir'in Baerbel Brumme-Bothe
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Dr. Ulrich Krafft (stellv. Vorsitzender), Dr. Sebastian M. Schmidt
-------------------------------------------------------------------
-------------------------------------------------------------------

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2007-12-22 00:39:24 UTC
Permalink
Is there some documentation or example how to scan the
result of an SIOCGIFCONF ioctl correctly now?

Yes, it's in the comment in src/sys/net/if.c:ifconf(). Basically, if
the sa_len is > the size of the union in ifreq, the new ifreq starts at
the end of the included sockaddr. otherwise it's at the end of the
ifreq. This is the same rule as always. In current, the sockaddr is
always <= the union (becaues it's sockaddr_storage), so it's just ifr+1.
But the code has to be ok on pre-current, and other systems.

The dhcp

/*
* Return interface configuration
* of system. List may be used
* in later ioctl's (above) to get
* other information.
*
* Each record is a struct ifreq. Before the addition of
* sockaddr_storage, the API rule was that sockaddr flavors that did
* not fit would extend beyond the struct ifreq, with the next struct
* ifreq starting sa_len beyond the struct sockaddr. Because the
* union in struct ifreq includes struct sockaddr_storage, every kind
* of sockaddr must fit. Thus, there are no longer any overlength
* records.
*
* Records are added to the user buffer if they fit, and ifc_len is
* adjusted to the length that was written. Thus, the user is only
* assured of getting the complete list if ifc_len on return is at
* least sizeof(struct ifreq) less than it was on entry.
*
* If the user buffer pointer is NULL, this routine copies no data and
* returns the amount of space that would be needed.
*
* Invariants:
* ifrp points to the next part of the user's buffer to be used. If
* ifrp != NULL, space holds the number of bytes remaining that we may
* write at ifrp. Otherwise, space holds the number of bytes that
* would have been written had there been adequate space.
*/

I believe the dhcp code in src/dist/dhcp/common/discover.c is correct:

#ifdef HAVE_SA_LEN
/*
* Classically, struct ifreq used with SIOCGIFCONF had
* a union where struct sockaddr was the largest
* member. If the address fit in the union, the next
* ifreq followed immediately. If not, the next ifreq
* followed the end of the actual sockaddr. In
* NetBSD-current after ~2007-05, ifreq has a
* sockaddr_storage member, and the next ifreq follows
* the current ifreq always, because no sockaddr can
* be bigger than sockaddr_storage. Thus, compare the
* length to the union's size, not struct sockaddr.
*/
if (ifp -> ifr_addr.sa_len > sizeof (ifp->ifr_ifru)) {
if (sizeof(struct ifreq) + ifp->ifr_addr.sa_len >
sizeof(ifcpy))
break;
/* XXX This copies IFNAMSIZ bytes too many. */
memcpy(&ifcpy, (caddr_t)ic.ifc_req + i,
sizeof(struct ifreq) + ifp->ifr_addr.sa_len);
i += offsetof(struct ifreq, ifr_ifru) +
ifp -> ifr_addr.sa_len;
} else
#endif
i += sizeof *ifp;






but anyway, I've patched samba to use getifaddrs() if possible.
It works well now for me.

That's a better approach anyway. As you are probably getting the
impression, SIOCGIFCONF is too hard to use.




--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...