[Openswan dev] [PATCH] pluto cannot handle systems with lots of interfaces

David McCullough david_mccullough at au.securecomputing.com
Thu Aug 10 08:44:01 EDT 2006


Hi all,

Here's a patch to fix plutos use of SIOCGIFCONF for when the buffer size
cannot hold all the interfaces configured on a system.  Not sure what
the actual limit is,  but it fails on a system with 2000+

This is against OpenSwan 2.4.6,  but should apply to most versions I suspect,

Cheers,
Davidm

Signed-off-by: David McCullough <david.mccullough at securecomputing.com>

-- 
David McCullough,  david_mccullough at securecomputing.com,   Ph:+61 734352815
Secure Computing - SnapGear  http://www.uCdot.org http://www.cyberguard.com
-------------- next part --------------
Index: programs/pluto/server.c
===================================================================
RCS file: openswan/programs/pluto/server.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 server.c
--- programs/pluto/server.c	4 Aug 2006 05:07:22 -0000	1.1.1.4
+++ programs/pluto/server.c	10 Aug 2006 03:34:04 -0000
@@ -340,8 +340,9 @@
 find_raw_ifaces(void)
 {
     int j;	/* index into buf */
+    int num;	/* number of interfaces */
     struct ifconf ifconf;
-    struct ifreq buf[300];	/* for list of interfaces -- arbitrary limit */
+    struct ifreq *buf;	/* for list of interfaces */
     struct raw_iface *rifaces = NULL;
     int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);    /* Get a UDP socket */
 
@@ -364,16 +365,31 @@
 	    exit_log_errno((e, "bind() failed in find_raw_ifaces()"));
     }
 
-    /* Get local interfaces.  See netdevice(7). */
-    ifconf.ifc_len = sizeof(buf);
-    ifconf.ifc_buf = (void *) buf;
-    zero(buf);
+    num = 100;
+    buf = NULL;
+    for (;;) {
+	/* Get local interfaces.  See netdevice(7). */
+	ifconf.ifc_len = num * sizeof(struct ifreq);
+	buf = (void *) realloc(buf, ifconf.ifc_len);
+	if (!buf)
+	    exit_log_errno((e, "realloc of %d in find_raw_ifaces4()",
+		    ifconf.ifc_len));
+	memset(buf, 0, num*sizeof(struct ifreq));
+	ifconf.ifc_buf = (void *) buf;
+
+	if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
+	    exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
+
+	/* if we got back less than we asked for, we have them all */
+	if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
+	    break;
 
-    if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
-	exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces()"));
+	/* try again and ask for more this time */
+	num += 100;
+    }
 
     /* Add an entry to rifaces for each interesting interface. */
-    for (j = 0; (j+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; j++)
+    for (j = 0; (j+1) * sizeof(struct ifreq) <= (size_t)ifconf.ifc_len; j++)
     {
 	struct raw_iface ri;
 	const struct sockaddr_in *rs = (struct sockaddr_in *) &buf[j].ifr_addr;
@@ -426,6 +442,9 @@
 
     close(master_sock);
 
+    if (buf)
+	free(buf);
+
     return rifaces;
 }
 


More information about the Dev mailing list