summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-05-18 10:32:27 +0200
committerVolker Lendecke <vl@samba.org>2009-05-18 13:38:55 +0200
commitbbbf9f13add12906480e6697eb56a2680dabe160 (patch)
treeeb7e7ef800154d0a862231038431d4bccb821ceb /source3/lib
parent67a2e629919bdc5a783e64636890fec2a7dfa9f8 (diff)
downloadsamba-bbbf9f13add12906480e6697eb56a2680dabe160.tar.gz
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
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/interface.c15
-rw-r--r--source3/lib/interfaces.c39
-rw-r--r--source3/lib/util_sock.c7
3 files changed, 39 insertions, 22 deletions
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index b32ccb9c568..4a8a154edbc 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 2535418d99a..bc6c991f6f8 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 1d7a82d7a57..40e2887440f 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);