diff options
author | Volker Lendecke <vl@samba.org> | 2009-05-18 10:32:27 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-05-18 13:38:55 +0200 |
commit | bbbf9f13add12906480e6697eb56a2680dabe160 (patch) | |
tree | eb7e7ef800154d0a862231038431d4bccb821ceb | |
parent | 67a2e629919bdc5a783e64636890fec2a7dfa9f8 (diff) | |
download | samba-bbbf9f13add12906480e6697eb56a2680dabe160.tar.gz samba-bbbf9f13add12906480e6697eb56a2680dabe160.tar.bz2 samba-bbbf9f13add12906480e6697eb56a2680dabe160.zip |
Fix bug 5681: Do not limit the number of network interfaces
Jeremy as far as I can see there is no real technical reason to limit the
number of interfaces. If you like this patch, can you please merge it to 3.4?
If you don't please tell me :-)
Thanks,
Volker
-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); |