From: Jukka Rissanen Date: Tue, 27 Mar 2012 07:59:56 +0000 (+0300) Subject: net: Add functions to get dest address of P-t-P link X-Git-Tag: 2.0_alpha~480 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ecd3e684d9ada5328371ff81b3170a71f5d8c00;p=framework%2Fconnectivity%2Fconnman.git net: Add functions to get dest address of P-t-P link These functions are needed when we need to setup a route to point-to-point link destination address. The route is needed if P-t-P link does not have a default route. --- diff --git a/include/inet.h b/include/inet.h index 1aa23ea..60525d5 100644 --- a/include/inet.h +++ b/include/inet.h @@ -78,6 +78,8 @@ int connman_inet_remove_from_bridge(int index, const char *bridge); int connman_inet_set_mtu(int index, int mtu); int connman_inet_setup_tunnel(char *tunnel, int mtu); int connman_inet_create_tunnel(char **iface); +int connman_inet_get_dest_addr(int index, char **dest); +int connman_inet_ipv6_get_dest_addr(int index, char **dest); #ifdef __cplusplus } diff --git a/src/inet.c b/src/inet.c index 5b81273..6202021 100644 --- a/src/inet.c +++ b/src/inet.c @@ -1781,3 +1781,97 @@ GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr, return prefixes; } + +static int get_dest_addr(int family, int index, char *buf, int len) +{ + struct ifreq ifr; + void *addr; + int sk; + + sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) + return -errno; + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno)); + close(sk); + return -errno; + } + + if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) { + DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno)); + close(sk); + return -errno; + } + + if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) { + close(sk); + errno = EINVAL; + return -errno; + } + + DBG("index %d %s", index, ifr.ifr_name); + + if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) { + connman_error("Get destination address failed (%s)", + strerror(errno)); + close(sk); + return -errno; + } + + close(sk); + + switch (family) { + case AF_INET: + addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr; + break; + case AF_INET6: + addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr; + break; + default: + errno = EINVAL; + return -errno; + } + + if (inet_ntop(family, addr, buf, len) == NULL) { + DBG("error %d/%s", errno, strerror(errno)); + return -errno; + } + + return 0; +} + +int connman_inet_get_dest_addr(int index, char **dest) +{ + char addr[INET_ADDRSTRLEN]; + int ret; + + ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN); + if (ret < 0) + return ret; + + *dest = g_strdup(addr); + + DBG("destination %s", *dest); + + return 0; +} + +int connman_inet_ipv6_get_dest_addr(int index, char **dest) +{ + char addr[INET6_ADDRSTRLEN]; + int ret; + + ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN); + if (ret < 0) + return ret; + + *dest = g_strdup(addr); + + DBG("destination %s", *dest); + + return 0; +}