[Openswan dev] dynamically allocate number of interfaces
Michael Richardson
mcr at xelerance.com
Thu Aug 10 11:18:13 CEST 2006
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 patch is against #public (which has moved the function to
sysdep_*.c), and remembers how many interfaces it tried last time.
Everytime you do "--listen", it has to re-list the interfaces.
This is against OpenSwan 2.4.6, but should apply to most versions I suspect,
Signed-off-by: David McCullough <david.mccullough at securecomputing.com>
Signed-off-by: Michael Richardson <mcr at xelerance.com>
---
14d777fe6b2aca49dcdf5e7d30463ffb90fa2b2d
programs/pluto/sysdep_bsd.c | 39 ++++++++++++++++++++++++++++-----------
programs/pluto/sysdep_linux.c | 37 +++++++++++++++++++++++++++----------
2 files changed, 55 insertions(+), 21 deletions(-)
14d777fe6b2aca49dcdf5e7d30463ffb90fa2b2d
diff --git a/programs/pluto/sysdep_bsd.c b/programs/pluto/sysdep_bsd.c
index b86347a..4af81df 100644
--- a/programs/pluto/sysdep_bsd.c
+++ b/programs/pluto/sysdep_bsd.c
@@ -197,9 +197,10 @@ struct raw_iface *
find_raw_ifaces4(void)
{
static const int on = TRUE; /* by-reference parameter; constant, we hope */
- int j; /* index into buf */
+ int j; /* index into buf */
+ static int num=64; /* number of interfaces */
struct ifconf ifconf;
- struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
+ struct ifreq *buf; /* for list of interfaces -- arbitrary limit */
struct raw_iface *rifaces = NULL;
int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
@@ -222,16 +223,32 @@ find_raw_ifaces4(void)
exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
}
- /* Get local interfaces. See netdevice(7). */
- ifconf.ifc_len = sizeof(buf);
- ifconf.ifc_buf = (void *) buf;
- zero(buf);
-
- if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
- exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
+ buf = NULL;
+
+ /* a million interfaces is probably the maximum, ever... */
+ while(num < (1024*1024)) {
+ /* 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;
+
+ /* try again and ask for more this time */
+ num *= 2;
+ }
+
/* 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;
diff --git a/programs/pluto/sysdep_linux.c b/programs/pluto/sysdep_linux.c
index f0f82ad..36a78cf 100644
--- a/programs/pluto/sysdep_linux.c
+++ b/programs/pluto/sysdep_linux.c
@@ -196,8 +196,9 @@ find_raw_ifaces4(void)
{
static const int on = TRUE; /* by-reference parameter; constant, we hope */
int j; /* index into buf */
+ static int num=64; /* number of interfaces */
struct ifconf ifconf;
- struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
+ struct ifreq *buf; /* for list of interfaces -- arbitrary limit */
struct raw_iface *rifaces = NULL;
int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
@@ -220,16 +221,32 @@ find_raw_ifaces4(void)
exit_log_errno((e, "bind() failed in find_raw_ifaces4()"));
}
- /* Get local interfaces. See netdevice(7). */
- ifconf.ifc_len = sizeof(buf);
- ifconf.ifc_buf = (void *) buf;
- zero(buf);
-
- if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
- exit_log_errno((e, "ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));
-
+ buf = NULL;
+
+ /* a million interfaces is probably the maximum, ever... */
+ while(num < (1024*1024)) {
+ /* 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;
+
+ /* try again and ask for more this time */
+ num *= 2;
+ }
+
/* 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;
--
1.3.GIT
commit-id 14d777fe6b2aca49dcdf5e7d30463ffb90fa2b2d
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 480 bytes
Desc: not available
Url : http://lists.openswan.org/pipermail/dev/attachments/20060810/9406f70b/attachment.bin
More information about the Dev
mailing list