summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cottrell <source@isc.org>2001-03-17 02:11:29 +0000
committerBen Cottrell <source@isc.org>2001-03-17 02:11:29 +0000
commitc73ced691dda3845206dc2f43f23cbaff8a6dce6 (patch)
tree33dfba471cdc8eec7221738849e57bd3475ba684
parented5ee59141f1bf91bf5016a3b0def64b4f4a2520 (diff)
downloadisc-dhcp-c73ced691dda3845206dc2f43f23cbaff8a6dce6.tar.gz
Fixed RT 938 having to do with SIOCGIFCONF on Linux. We now do a first
pass in which we pass a null pointer for the buffer, and we will get back the length of the buffer we should allocate. This is because if you pass in a buffer that is too small, Linux (unlike other OSes) will not tell you that it is too small by returning a length greater than the length you passed in.
-rw-r--r--common/discover.c32
-rw-r--r--includes/cf/linux.h1
2 files changed, 32 insertions, 1 deletions
diff --git a/common/discover.c b/common/discover.c
index 89ca6ad8..be533e3e 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: discover.c,v 1.38 2001/02/17 21:16:44 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: discover.c,v 1.39 2001/03/17 02:11:27 tamino Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -157,8 +157,38 @@ void discover_interfaces (state)
log_fatal ("Can't create addrlist socket");
/* Get the interface configuration information... */
+
+#ifdef SIOCGIFCONF_NULL_BUF_GIVES_CORRECT_LEN
+
+ /* linux will only tell us how long a buffer it wants if we give it
+ * a null buffer first. So, do a dry run to figure out the length.
+ *
+ * XXX this code is duplicated from below because trying to fold
+ * the logic into the if statement and goto resulted in excesssive
+ * obfuscation. The intent is that unless you run Linux you shouldn't
+ * have to deal with this. */
+
+ ic.ifc_len = 0;
+ ic.ifc_ifcu.ifcu_buf = (caddr_t)NULL;
+
+ i = ioctl(sock, SIOCGIFCONF, &ic);
+ if (i < 0)
+ log_fatal ("ioctl: SIOCGIFCONF: %m");
+
+ ic.ifc_ifcu.ifcu_buf = dmalloc ((size_t)ic.ifc_len, MDL);
+ if (!ic.ifc_ifcu.ifcu_buf)
+ log_fatal ("Can't allocate SIOCGIFCONF buffer.");
+
+#else /* SIOCGIFCONF_NULL_BUF_GIVES_CORRECT_LEN */
+
+ /* otherwise, we just feed it a starting size, and it'll tell us if
+ * it needs more */
+
ic.ifc_len = sizeof buf;
ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
+
+#endif /* SIOCGIFCONF_NULL_BUF_GIVES_CORRECT_LEN */
+
gifconf_again:
i = ioctl(sock, SIOCGIFCONF, &ic);
diff --git a/includes/cf/linux.h b/includes/cf/linux.h
index a01401e0..bdc0de6a 100644
--- a/includes/cf/linux.h
+++ b/includes/cf/linux.h
@@ -151,6 +151,7 @@ extern int h_errno;
#define ALIAS_NAMES_PERMUTED
#define SKIP_DUMMY_INTERFACES
+#define SIOCGIFCONF_NULL_BUF_GIVES_CORRECT_LEN
#ifdef NEED_PRAND_CONF
#ifndef HAVE_DEV_RANDOM