[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