summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/interfaces.h4
-rw-r--r--source3/lib/interface.c15
-rw-r--r--source3/lib/interfaces.c39
-rw-r--r--source3/lib/util_sock.c7
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);