[PATCH 1/6] Add generic implementation of getifaddrs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)
 {
-- 
1.7.1

_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux