Signed-off-by: Jan Friesse <jfriesse@xxxxxxxxxx>
---
configure.ac | 4 +-
exec/totemip.c | 86 ++++++++++++++++++++++++++++++++++++++
include/corosync/totem/totemip.h | 14 ++++++
3 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index b2e52f4..9f22fce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,7 +90,7 @@ AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stdint.h \
stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h \
sys/time.h syslog.h unistd.h sys/types.h getopt.h malloc.h \
- sys/sockio.h utmpx.h])
+ sys/sockio.h utmpx.h ifaddrs.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -125,7 +125,7 @@ AC_CHECK_FUNCS([alarm alphasort atexit bzero dup2 endgrent endpwent fcntl \
getcwd getpeerucred getpeereid gettimeofday inet_ntoa memmove \
memset mkdir scandir select socket strcasecmp strchr strdup \
strerror strrchr strspn strstr pthread_setschedparam \
- sched_get_priority_max sched_setscheduler])
+ sched_get_priority_max sched_setscheduler getifaddrs])
AC_CONFIG_FILES([Makefile
exec/Makefile
diff --git a/exec/totemip.c b/exec/totemip.c
index c901e1c..a0c166b 100644
--- a/exec/totemip.c
+++ b/exec/totemip.c
@@ -68,6 +68,10 @@
#include <linux/rtnetlink.h>
#endif
+#ifdef HAVE_GETIFADDRS
+#include <ifaddrs.h>
+#endif
+
#include <corosync/totem/totemip.h>
#include <corosync/swab.h>
@@ -672,3 +676,85 @@ finished:
return res;
}
#endif /* COROSYNC_LINUX */
+
+#ifdef HAVE_GETIFADDRS
+int totemip_getifaddrs(struct list_head *addrs)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct totem_ip_if_address *if_addr;
+
+ if (getifaddrs(&ifap) != 0)
+ return (-1);
+
+ list_init(addrs);
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (ifa->ifa_addr == NULL || ifa->ifa_netmask == NULL)
+ continue ;
+
+ if ((ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6) ||
+ (ifa->ifa_netmask->sa_family != AF_INET && ifa->ifa_netmask->sa_family != AF_INET6))
+ continue ;
+
+ if_addr = malloc(sizeof(struct totem_ip_if_address));
+ if (if_addr == NULL) {
+ goto error_free_ifaddrs;
+ }
+
+ list_init(&if_addr->list);
+
+ memset(if_addr, 0, sizeof(struct totem_ip_if_address));
+
+ if_addr->interface_up = ifa->ifa_flags & IFF_UP;
+ if_addr->interface_num = if_nametoindex(ifa->ifa_name);
+ if_addr->name = strdup(ifa->ifa_name);
+ if (if_addr->name == NULL) {
+ goto error_free_addr;
+ }
+
+ if (totemip_sockaddr_to_totemip_convert((const struct sockaddr_storage *)ifa->ifa_addr,
+ &if_addr->ip_addr) == -1) {
+ goto error_free_addr_name;
+ }
+
+ if (totemip_sockaddr_to_totemip_convert((const struct sockaddr_storage *)ifa->ifa_netmask,
+ &if_addr->mask_addr) == -1) {
+ goto error_free_addr_name;
+ }
+
+ list_add(&if_addr->list, addrs);
+ }
+
+ freeifaddrs(ifap);
+
+ return (0);
+
+error_free_addr_name:
+ free(if_addr->name);
+
+error_free_addr:
+ free(if_addr);
+
+error_free_ifaddrs:
+ totemip_freeifaddrs(addrs);
+ freeifaddrs(ifap);
+ return (-1);
+}
+#else
+#endif /* HAVE_GETIFADDRS */
+
+void totemip_freeifaddrs(struct list_head *addrs)
+{
+ struct totem_ip_if_address *if_addr;
+ struct list_head *list;
+
+ for (list = addrs->next; list != addrs;) {
+ if_addr = list_entry(list, struct totem_ip_if_address, list);
+ list = list->next;
+
+ free(if_addr->name);
+ list_del(&if_addr->list);
+ free(if_addr);
+ }
+ list_init(addrs);
+}
diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
index acc06ee..d354ec2 100644
--- a/include/corosync/totem/totemip.h
+++ b/include/corosync/totem/totemip.h
@@ -39,6 +39,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
+#include <corosync/list.h>
#ifdef __cplusplus
extern "C" {
@@ -64,6 +65,15 @@ struct totem_ip_address
unsigned char addr[TOTEMIP_ADDRLEN];
} __attribute__((packed));
+struct totem_ip_if_address
+{
+ struct totem_ip_address ip_addr;
+ struct totem_ip_address mask_addr;
+ int interface_up;
+ int interface_num;
+ char *name;
+ struct list_head list;
+};
extern int totemip_equal(const struct totem_ip_address *addr1,
const struct totem_ip_address *addr2);
@@ -88,6 +98,10 @@ extern int totemip_iface_check(struct totem_ip_address *bindnet,
int *interface_num,
int mask_high_bit);
+extern int totemip_getifaddrs(struct list_head *addrs);
+
+extern void totemip_freeifaddrs(struct list_head *addrs);
+
/* These two simulate a zero in_addr by clearing the family field */
static inline void totemip_zero_set(struct totem_ip_address *addr)
{