X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Finet.c;h=e0ef7dbb9f55a7f300a187db3c1b7a9d6804f26f;hb=7ef7e96fc2f3eb620fffb6f277339214efe83747;hp=b128e578f19e26c121e32d4ecba0921cb8b81ac8;hpb=6b2381a2adabea7d8309ff158ef675ff88184305;p=platform%2Fupstream%2Fconnman.git diff --git a/src/inet.c b/src/inet.c index b128e57..e0ef7db 100644 --- a/src/inet.c +++ b/src/inet.c @@ -189,6 +189,78 @@ done: return err; } +#if defined TIZEN_EXT_WIFI_MESH +char *connman_inet_ifaddr(const char *name) +{ + struct ifreq ifr; + struct ether_addr eth; + char *str; + int sk, err; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) + return NULL; + + strncpy(ifr.ifr_name, name, IFNAMSIZ-1); + + err = ioctl(sk, SIOCGIFHWADDR, &ifr); + close(sk); + + if (err < 0) + return NULL; + + str = g_malloc(18); + if (!str) + return NULL; + + memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth)); + snprintf(str, 13, "%02x%02x%02x%02x%02x%02x", + eth.ether_addr_octet[0], + eth.ether_addr_octet[1], + eth.ether_addr_octet[2], + eth.ether_addr_octet[3], + eth.ether_addr_octet[4], + eth.ether_addr_octet[5]); + + return str; +} + +char *connman_inet_ifname2addr(const char *name) +{ + struct ifreq ifr; + struct ether_addr eth; + char *str; + int sk, err; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) + return NULL; + + strncpy(ifr.ifr_name, name, IFNAMSIZ-1); + + err = ioctl(sk, SIOCGIFHWADDR, &ifr); + close(sk); + + if (err < 0) + return NULL; + + str = g_malloc(18); + if (!str) + return NULL; + + memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth)); + snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x", + eth.ether_addr_octet[0], + eth.ether_addr_octet[1], + eth.ether_addr_octet[2], + eth.ether_addr_octet[3], + eth.ether_addr_octet[4], + eth.ether_addr_octet[5]); + + return str; +} +#endif + bool __connman_inet_is_any_addr(const char *address, int family) { bool ret = false; @@ -363,6 +435,46 @@ done: return err; } +#if defined TIZEN_EXT +void connman_inet_update_device_ident(struct connman_device *device) +{ + int index; + enum connman_device_type type; + char *ident = NULL, *addr = NULL; + + index = connman_device_get_index(device); + type = connman_device_get_type(device); + + switch (type) { + case CONNMAN_DEVICE_TYPE_UNKNOWN: + return; + case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: + case CONNMAN_DEVICE_TYPE_WIFI: + addr = index2addr(index); + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_CELLULAR: + ident = index2ident(index, NULL); + break; + case CONNMAN_DEVICE_TYPE_BLUETOOTH: + case CONNMAN_DEVICE_TYPE_GPS: + case CONNMAN_DEVICE_TYPE_VENDOR: + break; + } + + if (ident != NULL) { + connman_device_set_ident(device, ident); + g_free(ident); + } + + if (addr != NULL) { + connman_device_set_string(device, "Address", addr); + g_free(addr); + } +} +#endif + bool connman_inet_is_ifup(int index) { int sk; @@ -1116,6 +1228,67 @@ bool connman_inet_compare_subnet(int index, const char *host) return ((if_addr & netmask_addr) == (host_addr & netmask_addr)); } +static bool mem_mask_equal(const void *a, const void *b, + const void *mask, size_t n) +{ + const unsigned char *addr1 = a; + const unsigned char *addr2 = b; + const unsigned char *bitmask = mask; + size_t i; + + for (i = 0; i < n; i++) { + if ((addr1[i] ^ addr2[i]) & bitmask[i]) + return false; + } + + return true; +} + +bool connman_inet_compare_ipv6_subnet(int index, const char *host) +{ + struct ifaddrs *ifaddr, *ifa; + bool rv = false; + char name[IF_NAMESIZE]; + struct in6_addr haddr; + + if (inet_pton(AF_INET6, host, &haddr) <= 0) + return false; + + if (!if_indextoname(index, name)) + return false; + + DBG("index %d interface %s", index, name); + + if (getifaddrs(&ifaddr) < 0) { + DBG("Cannot get addresses err %d/%s", errno, strerror(errno)); + return false; + } + + for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { + struct sockaddr_in6 *iaddr; + struct sockaddr_in6 *imask; + + if (!ifa->ifa_addr) + continue; + + if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) != 0 || + ifa->ifa_addr->sa_family != AF_INET6) + continue; + + iaddr = (struct sockaddr_in6 *)ifa->ifa_addr; + imask = (struct sockaddr_in6 *)ifa->ifa_netmask; + + rv = mem_mask_equal(&iaddr->sin6_addr, &haddr, + &imask->sin6_addr, + sizeof(haddr)); + goto out; + } + +out: + freeifaddrs(ifaddr); + return rv; +} + int connman_inet_remove_from_bridge(int index, const char *bridge) { struct ifreq ifr; @@ -1366,6 +1539,36 @@ static int icmpv6_recv(int fd, struct xs_cb_data *data) return -errno; } +#if defined TIZEN_EXT + /* Set Received Source Address from router as IPv6 Gateway Address */ + char src_addr[INET6_ADDRSTRLEN]; + if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN) + == NULL) + return -errno; + + DBG("Received Source Address %s from router", src_addr); + + /* icmpv6_recv() function can be called in two scenarios : + * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6() + * 2. When __connman_inet_ipv6_send_rs() is called from + * __connman_6to4_probe() + * In the second case it is not required to set DHCPv6 Gateway Address + * as DHCPv6 was not started and network structure was not passed as + * user_data. If it is tried to add Source Address as Gateway Address + * then it will lead to crash because of user_data being ip_address + * instead of network structure. So Adding Gateway Address in case 1st + * case only. + */ + char *address = data->user_data; + int err = 0; + unsigned char buffer[sizeof(struct in6_addr)] = {0, }; + /* Checking if user_data is an ip_address */ + err = inet_pton(AF_INET, address, buffer); + /* Setting Received Source Address from + * router as Gateway Address */ + if(err <= 0) + __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data); +#endif hdr = (struct nd_router_advert *)buf; DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len, sizeof(struct nd_router_advert)); @@ -1465,6 +1668,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest, char cbuf[CMSG_SPACE(sizeof(*pinfo))]; struct iovec iov[2]; int fd, datalen, ret, iovlen = 1; +#if defined TIZEN_EXT + char ebuf[256]; +#endif DBG(""); @@ -1543,6 +1749,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest, msgh.msg_controllen = cmsg->cmsg_len; ret = sendmsg(fd, &msgh, 0); +#if defined TIZEN_EXT + DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf))); +#endif close(fd); return ret; @@ -2563,11 +2772,21 @@ int __connman_inet_get_route(const char *dest_address, rth->req.u.r.rt.rtm_scope = 0; rth->req.u.r.rt.rtm_type = 0; rth->req.u.r.rt.rtm_src_len = 0; - rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3; rth->req.u.r.rt.rtm_tos = 0; - __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST, - &rp->ai_addr, rp->ai_addrlen); + if (rp->ai_family == AF_INET) { + struct sockaddr_in *sin = (struct sockaddr_in *)rp->ai_addr; + + rth->req.u.r.rt.rtm_dst_len = 32; + __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), + RTA_DST, &sin->sin_addr, sizeof(sin->sin_addr)); + } else if (rp->ai_family == AF_INET6) { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rp->ai_addr; + + rth->req.u.r.rt.rtm_dst_len = 128; + __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), + RTA_DST, &sin6->sin6_addr, sizeof(sin6->sin6_addr)); + } freeaddrinfo(rp); @@ -3165,7 +3384,7 @@ static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file, if (cmdline[len - 1] == '\n') cmdline[--len] = '\0'; - /* split in arguments (seperated by space) */ + /* split in arguments (separated by space) */ args = g_strsplit(cmdline, " ", 0); if (!args) { connman_error("%s: Cannot split cmdline \"%s\"\n", __func__, @@ -3368,7 +3587,7 @@ char **__connman_inet_get_pnp_nameservers(const char *pnp_file) } /* - * Perform two passes to retreive a char ** array of + * Perform two passes to retrieve a char ** array of * nameservers that are not 0.0.0.0 * * The first pass counts them, the second fills in the