]> git.proxmox.com Git - mirror_corosync.git/commitdiff
Add generic implementation of getifaddrs
authorJan Friesse <jfriesse@redhat.com>
Wed, 15 Feb 2012 09:47:22 +0000 (10:47 +0100)
committerJan Friesse <jfriesse@redhat.com>
Thu, 16 Feb 2012 09:47:56 +0000 (10:47 +0100)
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Steven Dake <sdake@redhat.com>
configure.ac
exec/totemip.c
include/corosync/totem/totemip.h

index b2e52f415a74004cdaba02b707b51d918db688b9..9f22fce2d000fecaf013e3516f3040010ff3bda3 100644 (file)
@@ -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
index c901e1c929d41fbfb61fd49d33e224d0e5d293c1..a0c166b90a8d87abdd91e8f459cd6f52cd52d4fd 100644 (file)
 #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);
+}
index acc06eefca11bb17e8662882948152e7b0f85d09..d354ec2d9047abf4bfcb07484ffa06350ec1fbd3 100644 (file)
@@ -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)
 {