From: Jukka Rissanen Date: Thu, 4 Apr 2013 11:44:49 +0000 (+0300) Subject: inet: Get an address from a given interface and address family X-Git-Tag: 1.13~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb147fc28a6c2bb3b81a9677af518c8e3bf6cc4e;p=platform%2Fupstream%2Fconnman.git inet: Get an address from a given interface and address family The returned address is used when we need to have a listening socket tied to specific interface and address, and do not want to bind to any address. --- diff --git a/src/connman.h b/src/connman.h index e9c774e..b63e658 100644 --- a/src/connman.h +++ b/src/connman.h @@ -133,6 +133,7 @@ int __connman_inet_modify_address(int cmd, int flags, int index, int family, const char *peer, unsigned char prefixlen, const char *broadcast); +int __connman_inet_get_interface_address(int index, int family, void *address); #include #include diff --git a/src/inet.c b/src/inet.c index 0027fe6..5196576 100644 --- a/src/inet.c +++ b/src/inet.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "connman.h" @@ -2376,3 +2377,57 @@ connman_bool_t connman_inet_is_ipv6_supported() close(sk); return TRUE; } + +int __connman_inet_get_interface_address(int index, int family, void *address) +{ + struct ifaddrs *ifaddr, *ifa; + int err = -ENOENT; + char name[IF_NAMESIZE]; + + if (if_indextoname(index, name) == NULL) + return -EINVAL; + + DBG("index %d interface %s", index, name); + + if (getifaddrs(&ifaddr) < 0) { + err = -errno; + DBG("Cannot get addresses err %d/%s", err, strerror(-err)); + return err; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + + if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 && + ifa->ifa_addr->sa_family == family) { + if (family == AF_INET) { + struct sockaddr_in *in4 = (struct sockaddr_in *) + ifa->ifa_addr; + if (in4->sin_addr.s_addr == INADDR_ANY) + continue; + memcpy(address, &in4->sin_addr, + sizeof(struct in_addr)); + } else if (family == AF_INET6) { + struct sockaddr_in6 *in6 = + (struct sockaddr_in6 *)ifa->ifa_addr; + if (memcmp(&in6->sin6_addr, &in6addr_any, + sizeof(struct in6_addr)) == 0) + continue; + memcpy(address, &in6->sin6_addr, + sizeof(struct in6_addr)); + + } else { + err = -EINVAL; + goto out; + } + + err = 0; + break; + } + } + +out: + freeifaddrs(ifaddr); + return err; +}