Subject: kern/12578: mrouted uses SIOCGIFCONF suboptimal
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lha@stacken.kth.se>
List: netbsd-bugs
Date: 04/08/2001 19:56:53
>Number:         12578
>Category:       kern
>Synopsis:       mrouted uses SIOCGIFCONF suboptimal
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Apr 08 10:58:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Love
>Release:        NetBSD-1.5S
>Organization:
	Stacken Computer Club
>Environment:
	
System: NetBSD nutcracker.dynarc.se 1.5S NetBSD 1.5S (NUTCRACKER) #2: Mon Mar 12 16:45:25 CET 2001 lha@nutcracker.dynarc.se:/usr/src/sys/arch/i386/compile/NUTCRACKER i386
Architecture: i386
Machine: i386
>Description:
	Create a bunch of interface, start mrouted, see it fail.

>How-To-Repeat:

	mkdir mrouted
	cd mrouted

	jot -w "ifconfig gif%d create up" 21 0 > ifconfig.1
	jot -w "10.0.%d.1 netmask 0xffffff00" 21 0 > ifconfig.2
	paste ifconfig.1 ifconfig.2 > ifconfig
	sh ifconfig

	jot -w "phyint gif%d" 21 0 > mrouted.sample
	mrouted -d -c mrouted.sample

	jot -w "ifconfig gif%d destroy" 21 0 > ifconfig.del
	sh ifconfig.del

	cd ..
	rm -r mrouted


>Fix:

	I wrote the code when netbsd still used pre3.8 mrouted, but it
	seems not fixed in 3.8 either.

	The fix uses getifaddrs(), I guess if one is supposted to write
	portable code, a 

	while (1) { 
		malloc(len), if (ioctl() == 0) break; free(buf); len *=2;
	}

	loop should be used instead.

	The value 32 in struct ifreq ifbuf[32]; is probably chosen due to
	MAXVIFS is 32.

	W/o the patch, I get out 4 interface with almost-generic
	kernel + 21 gif's.

--- /afs/stacken.kth.se/src/NetBSD/current/src/usr.sbin/mrouted/config.c        Sun Dec 10 11:06:58 1995
+++ config.c    Sun Apr  8 19:33:25 2001
@@ -1,4 +1,4 @@
-/*     $NetBSD: config.c,v 1.5 1995/10/09 03:51:37 thorpej Exp $       */
+/*     $NetBSD: config.c,v 1.6 1995/12/10 10:06:58 mycroft Exp $       */
 
 /*
  * The mrouted program is covered by the license in the accompanying file
@@ -20,41 +20,22 @@
 void
 config_vifs_from_kernel()
 {
-    struct ifreq ifbuf[32];
-    struct ifreq *ifrp, *ifend;
-    struct ifconf ifc;
+    struct ifaddrs *ifap, *oifap;
     register struct uvif *v;
     register vifi_t vifi;
-    int n;
     u_int32_t addr, mask, subnet;
     short flags;

-    ifc.ifc_buf = (char *)ifbuf;
-    ifc.ifc_len = sizeof(ifbuf);
-    if (ioctl(udp_socket, SIOCGIFCONF, (char *)&ifc) < 0)
-       log(LOG_ERR, errno, "ioctl SIOCGIFCONF");
+    if (getifaddrs(&oifap) < 0)
+       log(LOG_ERR, errno, "ioctl getifaddrs");
 
-    ifrp = (struct ifreq *)ifbuf;
-    ifend = (struct ifreq *)((char *)ifbuf + ifc.ifc_len);
-    /*
-     * Loop through all of the interfaces.
-     */
-    for (; ifrp < ifend; ifrp = (struct ifreq *)((char *)ifrp + n)) {
+    for (ifap = oifap; ifap; ifap = ifap->ifa_next) {
        struct ifreq ifr;
-#if BSD >= 199006
-       n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
-       if (n < sizeof(*ifrp))
-           n = sizeof(*ifrp);
-#else
-       n = sizeof(*ifrp);
-#endif
-       /*
-        * Ignore any interface for an address family other than IP.
-        */
-       if (ifrp->ifr_addr.sa_family != AF_INET)
+
+       if (ifap->ifa_addr->sa_family != AF_INET)
            continue;
 
-       addr = ((struct sockaddr_in *)&ifrp->ifr_addr)->sin_addr.s_addr;
+       addr = ((struct sockaddr_in *)ifap->ifa_addr)->sin_addr.s_addr;
 
        /*
         * Need a template to preserve address info that is
@@ -62,7 +43,7 @@
         * SIOCGIFFLAGS stomps over it because the requests
         * are returned in a union.)
         */
-       bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
+       bcopy(ifap->ifa_name, ifr.ifr_name, sizeof(ifr.ifr_name));
 
        /*
         * Ignore loopback interfaces and interfaces that do not support
@@ -143,4 +124,5 @@
            vifs_down = TRUE;
        }
     }
+    freeifaddrs(oifap);
 }
--- /afs/stacken.kth.se/src/NetBSD/current/src/usr.sbin/mrouted/defs.h  Tue Oct 24 05:32:31 2000
+++ defs.h      Sun Apr  8 19:21:13 2001
@@ -1,4 +1,4 @@
-/*     $NetBSD: defs.h,v 1.7 1997/10/17 10:38:03 lukem Exp $   */
+/*     $NetBSD: defs.h,v 1.8 2000/10/11 20:23:53 is Exp $      */
 
 /*
  * The mrouted program is covered by the license in the accompanying file
@@ -35,6 +35,7 @@
 #ifdef RSRR
 #include <sys/un.h>
 #endif /* RSRR */
+#include <ifaddrs.h>
 
 #ifndef __P
 #ifdef __STDC__
>Release-Note:
>Audit-Trail:
>Unformatted: