diff options
author | Ben Cottrell <source@isc.org> | 2001-03-17 02:11:29 +0000 |
---|---|---|
committer | Ben Cottrell <source@isc.org> | 2001-03-17 02:11:29 +0000 |
commit | c73ced691dda3845206dc2f43f23cbaff8a6dce6 (patch) | |
tree | 33dfba471cdc8eec7221738849e57bd3475ba684 | |
parent | ed5ee59141f1bf91bf5016a3b0def64b4f4a2520 (diff) | |
download | isc-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.c | 32 | ||||
-rw-r--r-- | includes/cf/linux.h | 1 |
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 |