Add generic implementation of getifaddrs

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Reviewed-by: Steven Dake <sdake@redhat.com>
This commit is contained in:
Jan Friesse 2012-02-15 10:47:22 +01:00
parent 4c3aab9caf
commit 27e9988486
3 changed files with 102 additions and 2 deletions

View 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

View File

@ -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);
}

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