Re: [PATCH 1/6] Add generic implementation of getifaddrs

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

 



Steve,
actually getifaddrs implmentation is based on previous BSD/Darwin one, and I've tested on OpenBSD 4.6 and FreeBSD 7 (OpenBSD should be supported since 2.6, and generally speaking, all *BSD systems should work).

I've tested RHEL 5 and RHEL 6 as Linux candidates.

Only one system I know about that doesn't work is Solaris 10, what is solved in patch 3/6 (Solaris 11 should also support getifaddrs and I've tested OpenIndiana which has support, so we can remove 3/6 as soon as Sol <= 10 is EOL).

Last major system I know about is Windows NT, and there Cygwin has support for getifaddrs.

In other words, this patch should give us much wider support then we had before, and also we no longer depends on OS specific bits, but using ~standard interface.

Honza

Steven Dake napsal(a):
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


[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