瀏覽代碼

Add generic implementation of getifaddrs

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Steven Dake <sdake@redhat.com>
Jan Friesse 14 年之前
父節點
當前提交
27e9988486
共有 3 個文件被更改,包括 102 次插入2 次删除
  1. 2 2
      configure.ac
  2. 86 0
      exec/totemip.c
  3. 14 0
      include/corosync/totem/totemip.h

+ 2 - 2
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

+ 86 - 0
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);
+}

+ 14 - 0
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)
 {