diff options
-rw-r--r-- | source3/include/interfaces.h | 4 | ||||
-rw-r--r-- | source3/lib/interface.c | 15 | ||||
-rw-r--r-- | source3/lib/interfaces.c | 39 | ||||
-rw-r--r-- | source3/lib/util_sock.c | 7 |
4 files changed, 40 insertions, 25 deletions
diff --git a/source3/include/interfaces.h b/source3/include/interfaces.h index 9a19c33b57..6ba0e21f6d 100644 --- a/source3/include/interfaces.h +++ b/source3/include/interfaces.h @@ -27,8 +27,6 @@ #include "../replace/replace.h" #include "../replace/system/network.h" -#define MAX_INTERFACES 128 - struct iface_struct { char name[16]; int flags; @@ -46,6 +44,6 @@ void make_bcast(struct sockaddr_storage *pss_out, void make_net(struct sockaddr_storage *pss_out, const struct sockaddr_storage *pss_in, const struct sockaddr_storage *nmask); -int get_interfaces(struct iface_struct *ifaces, int max_interfaces); +int get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces); #endif diff --git a/source3/lib/interface.c b/source3/lib/interface.c index b32ccb9c56..4a8a154edb 100644 --- a/source3/lib/interface.c +++ b/source3/lib/interface.c @@ -492,7 +492,7 @@ static void interpret_interface(char *token) void load_interfaces(void) { - struct iface_struct ifaces[MAX_INTERFACES]; + struct iface_struct *ifaces = NULL; const char **ptr = lp_interfaces(); int i; @@ -507,7 +507,7 @@ void load_interfaces(void) } /* Probe the kernel for interfaces */ - total_probed = get_interfaces(ifaces, MAX_INTERFACES); + total_probed = get_interfaces(talloc_tos(), &ifaces); if (total_probed > 0) { probed_ifaces = (struct iface_struct *)memdup(ifaces, @@ -517,6 +517,7 @@ void load_interfaces(void) exit(1); } } + TALLOC_FREE(ifaces); /* if we don't have a interfaces line then use all broadcast capable interfaces except loopback */ @@ -569,15 +570,17 @@ void gfree_interfaces(void) bool interfaces_changed(void) { + bool ret = false; int n; - struct iface_struct ifaces[MAX_INTERFACES]; + struct iface_struct *ifaces = NULL; - n = get_interfaces(ifaces, MAX_INTERFACES); + n = get_interfaces(talloc_tos(), &ifaces); if ((n > 0 )&& (n != total_probed || memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) { - return true; + ret = true; } - return false; + TALLOC_FREE(ifaces); + return ret; } diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c index 2535418d99..bc6c991f6f 100644 --- a/source3/lib/interfaces.c +++ b/source3/lib/interfaces.c @@ -123,10 +123,12 @@ void make_net(struct sockaddr_storage *pss_out, Get the netmask address for a local interface. ****************************************************************************/ -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) +static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces) { + struct iface_struct *ifaces; struct ifaddrs *iflist = NULL; struct ifaddrs *ifptr = NULL; + int count; int total = 0; size_t copy_size; @@ -134,10 +136,25 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) return -1; } + count = 0; + for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) { + if (!ifptr->ifa_addr || !ifptr->ifa_netmask) { + continue; + } + if (!(ifptr->ifa_flags & IFF_UP)) { + continue; + } + count += 1; + } + + ifaces = talloc_array(mem_ctx, struct iface_struct, count); + if (ifaces == NULL) { + errno = ENOMEM; + return -1; + } + /* Loop through interfaces, looking for given IP address */ - for (ifptr = iflist, total = 0; - ifptr != NULL && total < max_interfaces; - ifptr = ifptr->ifa_next) { + for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) { memset(&ifaces[total], '\0', sizeof(ifaces[total])); @@ -147,13 +164,13 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) continue; } - ifaces[total].flags = ifptr->ifa_flags; - /* Check the interface is up. */ - if (!(ifaces[total].flags & IFF_UP)) { + if (!(ifptr->ifa_flags & IFF_UP)) { continue; } + ifaces[total].flags = ifptr->ifa_flags; + #if defined(HAVE_IPV6) if (ifptr->ifa_addr->sa_family == AF_INET6) { copy_size = sizeof(struct sockaddr_in6); @@ -183,6 +200,7 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) freeifaddrs(iflist); + *pifaces = ifaces; return total; } @@ -250,14 +268,14 @@ static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) return 0; } -int get_interfaces(struct iface_struct *ifaces, int max_interfaces); /* this wrapper is used to remove duplicates from the interface list generated above */ -int get_interfaces(struct iface_struct *ifaces, int max_interfaces) +int get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces) { + struct iface_struct *ifaces; int total, i, j; - total = _get_interfaces(ifaces, max_interfaces); + total = _get_interfaces(mem_ctx, &ifaces); if (total <= 0) return total; /* now we need to remove duplicates */ @@ -274,6 +292,7 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces) } } + *pifaces = ifaces; return total; } diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1d7a82d7a5..40e2887440 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1948,12 +1948,7 @@ bool is_myname_or_ipaddr(const char *s) return false; } - nics = TALLOC_ARRAY(ctx, struct iface_struct, - MAX_INTERFACES); - if (!nics) { - return false; - } - n = get_interfaces(nics, MAX_INTERFACES); + n = get_interfaces(talloc_tos(), &nics); for (i=0; i<n; i++) { if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) { TALLOC_FREE(nics); |