diff options
Diffstat (limited to 'net/isc-dhcp40-server/files/patch-common::discover.c')
-rw-r--r-- | net/isc-dhcp40-server/files/patch-common::discover.c | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/net/isc-dhcp40-server/files/patch-common::discover.c b/net/isc-dhcp40-server/files/patch-common::discover.c new file mode 100644 index 000000000000..1cfcc2094098 --- /dev/null +++ b/net/isc-dhcp40-server/files/patch-common::discover.c @@ -0,0 +1,238 @@ +--- common/discover.c.orig Fri Jul 25 21:44:15 2003 ++++ common/discover.c Fri Mar 5 23:33:04 2004 +@@ -47,6 +47,7 @@ + #endif /* not lint */ + + #include "dhcpd.h" ++#include <ifaddrs.h> + #include <sys/ioctl.h> + + struct interface_info *interfaces, *dummy_interfaces, *fallback_interface; +@@ -135,10 +136,7 @@ + { + struct interface_info *tmp, *ip; + struct interface_info *last, *next; +- char buf [2048]; +- struct ifconf ic; +- struct ifreq ifr; +- int i; ++ struct ifaddrs *ifap, *ifa; + int sock; + int address_count = 0; + struct subnet *subnet; +@@ -157,61 +155,6 @@ + if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + log_fatal ("Can't create addrlist socket"); + +- /* Get the interface configuration information... */ +- +-#ifdef SIOCGIFCONF_ZERO_PROBE +- /* 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; +-#else +- /* 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 +- +- gifconf_again: +- i = ioctl(sock, SIOCGIFCONF, &ic); +- +- if (i < 0) +- log_fatal ("ioctl: SIOCGIFCONF: %m"); +- +-#ifdef SIOCGIFCONF_ZERO_PROBE +- /* Workaround for SIOCGIFCONF bug on some Linux versions. */ +- if (ic.ifc_ifcu.ifcu_buf == 0 && ic.ifc_len == 0) { +- ic.ifc_len = sizeof buf; +- ic.ifc_ifcu.ifcu_buf = (caddr_t)buf; +- goto gifconf_again; +- } +-#endif +- +- /* If the SIOCGIFCONF resulted in more data than would fit in +- a buffer, allocate a bigger buffer. */ +- if ((ic.ifc_ifcu.ifcu_buf == buf +-#ifdef SIOCGIFCONF_ZERO_PROBE +- || ic.ifc_ifcu.ifcu_buf == 0 +-#endif +- ) && ic.ifc_len > sizeof buf) { +- 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."); +- goto gifconf_again; +-#ifdef SIOCGIFCONF_ZERO_PROBE +- } else if (ic.ifc_ifcu.ifcu_buf == 0) { +- ic.ifc_ifcu.ifcu_buf = (caddr_t)buf; +- ic.ifc_len = sizeof buf; +- goto gifconf_again; +-#endif +- } +- + + /* If we already have a list of interfaces, and we're running as + a DHCP server, the interfaces were requested. */ +@@ -224,51 +167,38 @@ + else + ir = INTERFACE_REQUESTED; + ++ if (getifaddrs(&ifap) != 0) ++ log_fatal ("getifaddrs failed"); ++ + /* Cycle through the list of interfaces looking for IP addresses. */ +- for (i = 0; i < ic.ifc_len;) { +- struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i); +-#ifdef HAVE_SA_LEN +- if (ifp -> ifr_addr.sa_len > sizeof (struct sockaddr)) +- i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len; +- else +-#endif +- i += sizeof *ifp; ++ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + + #ifdef ALIAS_NAMES_PERMUTED +- if ((s = strrchr (ifp -> ifr_name, ':'))) { ++ if ((s = strrchr (ifa -> ifa_name, ':'))) { + *s = 0; + } + #endif + + #ifdef SKIP_DUMMY_INTERFACES +- if (!strncmp (ifp -> ifr_name, "dummy", 5)) ++ if (!strncmp (ifa -> ifa_name, "dummy", 5)) + continue; + #endif + +- +- /* See if this is the sort of interface we want to +- deal with. */ +- strcpy (ifr.ifr_name, ifp -> ifr_name); +- if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0) +- log_fatal ("Can't get interface flags for %s: %m", +- ifr.ifr_name); +- + /* See if we've seen an interface that matches this one. */ + for (tmp = interfaces; tmp; tmp = tmp -> next) +- if (!strcmp (tmp -> name, ifp -> ifr_name)) ++ if (!strcmp (tmp -> name, ifa -> ifa_name)) + break; + +- /* Skip non broadcast interfaces (plus loopback and +- point-to-point in case an OS incorrectly marks them +- as broadcast). Also skip down interfaces unless we're ++ /* See if this is the sort of interface we want to ++ deal with. Skip loopback, point-to-point and down ++ interfaces, except don't skip down interfaces if we're + trying to get a list of configurable interfaces. */ +- if (((!(ifr.ifr_flags & IFF_BROADCAST) || +- ifr.ifr_flags & IFF_LOOPBACK || +- ifr.ifr_flags & IFF_POINTOPOINT) && !tmp) || +- (!(ifr.ifr_flags & IFF_UP) && ++ if ((ifa->ifa_flags & IFF_LOOPBACK) || ++ (ifa->ifa_flags & IFF_POINTOPOINT) || ++ (!(ifa->ifa_flags & IFF_UP) && + state != DISCOVER_UNCONFIGURED)) + continue; +- ++ + /* If there isn't already an interface by this name, + allocate one. */ + if (!tmp) { +@@ -276,9 +206,9 @@ + status = interface_allocate (&tmp, MDL); + if (status != ISC_R_SUCCESS) + log_fatal ("Error allocating interface %s: %s", +- ifp -> ifr_name, ++ ifa -> ifa_name, + isc_result_totext (status)); +- strcpy (tmp -> name, ifp -> ifr_name); ++ strcpy (tmp -> name, ifa -> ifa_name); + interface_snorf (tmp, ir); + interface_dereference (&tmp, MDL); + tmp = interfaces; /* XXX */ +@@ -290,9 +220,9 @@ + /* If we have the capability, extract link information + and record it in a linked list. */ + #ifdef HAVE_AF_LINK +- if (ifp -> ifr_addr.sa_family == AF_LINK) { ++ if (ifa -> ifa_addr->sa_family == AF_LINK) { + struct sockaddr_dl *foo = ((struct sockaddr_dl *) +- (&ifp -> ifr_addr)); ++ (ifa -> ifa_addr)); + #if defined (HAVE_SIN_LEN) + tmp -> hw_address.hlen = foo -> sdl_alen; + #else +@@ -305,12 +235,11 @@ + } else + #endif /* AF_LINK */ + +- if (ifp -> ifr_addr.sa_family == AF_INET) { ++ if (ifa -> ifa_addr->sa_family == AF_INET) { + struct iaddr addr; + + /* Get a pointer to the address... */ +- memcpy (&foo, &ifp -> ifr_addr, +- sizeof ifp -> ifr_addr); ++ bcopy(ifa->ifa_addr, &foo, sizeof(foo)); + + /* We don't want the loopback interface. */ + if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK) && +@@ -323,16 +252,15 @@ + found, keep a pointer to ifreq structure in + which we found it. */ + if (!tmp -> ifp) { +-#ifdef HAVE_SA_LEN +- unsigned len = ((sizeof ifp -> ifr_name) + +- ifp -> ifr_addr.sa_len); +-#else +- unsigned len = sizeof *ifp; +-#endif ++ ++ int len = (IFNAMSIZ + ++ ifa -> ifa_addr->sa_len); + tif = (struct ifreq *)dmalloc (len, MDL); + if (!tif) + log_fatal ("no space for ifp."); +- memcpy (tif, ifp, len); ++ strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ); ++ memcpy(&tif->ifr_addr, ifa->ifa_addr, ++ ifa->ifa_addr->sa_len); + tmp -> ifp = tif; + tmp -> primary_address = foo.sin_addr; + } +@@ -346,9 +274,6 @@ + } + } + +- /* If we allocated a buffer, free it. */ +- if (ic.ifc_ifcu.ifcu_buf != buf) +- dfree (ic.ifc_ifcu.ifcu_buf, MDL); + + #if defined (LINUX_SLASHPROC_DISCOVERY) + /* On Linux, interfaces that don't have IP addresses don't +@@ -529,6 +454,7 @@ + be able to configure, we can quit now. */ + if (state == DISCOVER_UNCONFIGURED) { + close (sock); ++ freeifaddrs(ifap); + return; + } + +@@ -674,6 +600,7 @@ + } + + close (sock); ++ freeifaddrs(ifap); + + if (state == DISCOVER_SERVER && wifcount == 0) { + log_info ("%s", ""); |