Does this work on non-linux systems? Reviewed-by: Steven Dake <sdake@xxxxxxxxxx> On 02/15/2012 09:09 AM, Jan Friesse wrote: > 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) > { _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss