#include "../replace/replace.h"
#include "../replace/system/network.h"
-#define MAX_INTERFACES 128
-
struct iface_struct {
char name[16];
int flags;
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
void load_interfaces(void)
{
- struct iface_struct ifaces[MAX_INTERFACES];
+ struct iface_struct *ifaces = NULL;
const char **ptr = lp_interfaces();
int i;
}
/* 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,
exit(1);
}
}
+ TALLOC_FREE(ifaces);
/* if we don't have a interfaces line then use all broadcast capable
interfaces except loopback */
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;
}
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;
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]));
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);
freeifaddrs(iflist);
+ *pifaces = ifaces;
return total;
}
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 */
}
}
+ *pifaces = ifaces;
return total;
}