X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Finet.c;h=5b81273e18c532f108e572afe68061ef2bef9e0c;hb=212ad2f520bb2fb9cdc830142f65cfb7d0bd68fe;hp=d8986508f8a88b6216bb6c79c100ba28bd8fd519;hpb=9542c566a1a38ca1760dbdef7e41441cbb7fe918;p=platform%2Fupstream%2Fconnman.git diff --git a/src/inet.c b/src/inet.c index d898650..5b81273 100644 --- a/src/inet.c +++ b/src/inet.c @@ -25,6 +25,7 @@ #include #endif +#define _GNU_SOURCE #include #include #include @@ -150,7 +151,7 @@ int __connman_inet_modify_address(int cmd, int flags, return err; } - sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE); if (sk < 0) return -errno; @@ -177,7 +178,7 @@ int connman_inet_ifindex(const char *name) if (name == NULL) return -1; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -202,7 +203,7 @@ char *connman_inet_ifname(int index) if (index < 0) return NULL; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return NULL; @@ -224,7 +225,7 @@ short int connman_inet_ifflags(int index) struct ifreq ifr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -errno; @@ -254,7 +255,7 @@ int connman_inet_ifup(int index) struct ifreq ifr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -errno; @@ -296,7 +297,7 @@ int connman_inet_ifdown(int index) struct ifreq ifr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -errno; @@ -341,7 +342,7 @@ static char *index2addr(int index) if (index < 0) return NULL; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return NULL; @@ -384,7 +385,7 @@ static char *index2ident(int index, const char *prefix) if (index < 0) return NULL; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return NULL; @@ -428,7 +429,7 @@ connman_bool_t connman_inet_is_cfg80211(int index) struct ifreq ifr; int sk; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return FALSE; @@ -653,7 +654,10 @@ int connman_inet_add_network_route(int index, const char *host, struct sockaddr_in addr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + DBG("index %d host %s gateway %s netmask %s", index, + host, gateway, netmask); + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -715,7 +719,9 @@ int connman_inet_del_network_route(int index, const char *host) struct sockaddr_in addr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + DBG("index %d host %s", index, host); + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -773,7 +779,7 @@ int connman_inet_del_ipv6_network_route(int index, const char *host, rt.rtmsg_metric = 1; rt.rtmsg_ifindex = index; - sk = socket(AF_INET6, SOCK_DGRAM, 0); + sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { err = -1; goto out; @@ -824,7 +830,7 @@ int connman_inet_add_ipv6_network_route(int index, const char *host, rt.rtmsg_metric = 1; rt.rtmsg_ifindex = index; - sk = socket(AF_INET6, SOCK_DGRAM, 0); + sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { err = -1; goto out; @@ -851,7 +857,7 @@ int connman_inet_set_ipv6_gateway_address(int index, const char *gateway) struct in6_rtmsg rt; int sk, err; - DBG("index %d, gateway %s", index, gateway); + DBG("index %d gateway %s", index, gateway); if (gateway == NULL) return -EINVAL; @@ -867,7 +873,7 @@ int connman_inet_set_ipv6_gateway_address(int index, const char *gateway) rt.rtmsg_dst_len = 0; rt.rtmsg_ifindex = index; - sk = socket(AF_INET6, SOCK_DGRAM, 0); + sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { err = -1; goto out; @@ -888,7 +894,7 @@ int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway) struct in6_rtmsg rt; int sk, err; - DBG("index %d, gateway %s", index, gateway); + DBG("index %d gateway %s", index, gateway); if (gateway == NULL) return -EINVAL; @@ -904,7 +910,7 @@ int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway) rt.rtmsg_dst_len = 0; rt.rtmsg_ifindex = index; - sk = socket(AF_INET6, SOCK_DGRAM, 0); + sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { err = -1; goto out; @@ -927,7 +933,9 @@ int connman_inet_set_gateway_address(int index, const char *gateway) struct sockaddr_in addr; int sk, err; - sk = socket(PF_INET, SOCK_DGRAM, 0); + DBG("index %d gateway %s", index, gateway); + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -976,9 +984,9 @@ int connman_inet_set_gateway_interface(int index) struct sockaddr_in addr; int sk, err; - DBG(""); + DBG("index %d", index); - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -1022,9 +1030,9 @@ int connman_inet_set_ipv6_gateway_interface(int index) const struct in6_addr any = IN6ADDR_ANY_INIT; int sk, err; - DBG(""); + DBG("index %d", index); - sk = socket(PF_INET6, SOCK_DGRAM, 0); + sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -1067,9 +1075,9 @@ int connman_inet_clear_gateway_address(int index, const char *gateway) struct sockaddr_in addr; int sk, err; - DBG(""); + DBG("index %d gateway %s", index, gateway); - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -1118,9 +1126,9 @@ int connman_inet_clear_gateway_interface(int index) struct sockaddr_in addr; int sk, err; - DBG(""); + DBG("index %d", index); - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -1164,9 +1172,9 @@ int connman_inet_clear_ipv6_gateway_interface(int index) const struct in6_addr any = IN6ADDR_ANY_INIT; int sk, err; - DBG(""); + DBG("index %d", index); - sk = socket(PF_INET6, SOCK_DGRAM, 0); + sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return -1; @@ -1219,7 +1227,7 @@ connman_bool_t connman_inet_compare_subnet(int index, const char *host) return -1; host_addr = _host_addr.s_addr; - sk = socket(PF_INET, SOCK_DGRAM, 0); + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return FALSE; @@ -1243,6 +1251,9 @@ connman_bool_t connman_inet_compare_subnet(int index, const char *host) close(sk); return FALSE; } + + close(sk); + addr = (struct sockaddr_in *)&ifr.ifr_addr; if_addr = addr->sin_addr.s_addr; @@ -1257,7 +1268,7 @@ int connman_inet_remove_from_bridge(int index, const char *bridge) if (bridge == NULL) return -EINVAL; - sk = socket(AF_INET, SOCK_STREAM, 0); + sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (sk < 0) return sk; @@ -1286,7 +1297,7 @@ int connman_inet_add_to_bridge(int index, const char *bridge) if (bridge == NULL) return -EINVAL; - sk = socket(AF_INET, SOCK_STREAM, 0); + sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (sk < 0) return sk; @@ -1312,7 +1323,7 @@ int connman_inet_set_mtu(int index, int mtu) struct ifreq ifr; int sk, err; - sk = socket(AF_INET, SOCK_DGRAM, 0); + sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return sk; @@ -1339,7 +1350,7 @@ int connman_inet_setup_tunnel(char *tunnel, int mtu) if (tunnel == NULL) return -EINVAL; - sk = socket(AF_INET, SOCK_DGRAM, 0); + sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) return sk; @@ -1379,7 +1390,7 @@ int connman_inet_create_tunnel(char **iface) struct ifreq ifr; int i, fd; - fd = open("/dev/net/tun", O_RDWR); + fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC); if (fd < 0) { i = -errno; connman_error("Failed to open /dev/net/tun: %s", @@ -1413,6 +1424,7 @@ struct rs_cb_data { __connman_inet_rs_cb_t callback; struct sockaddr_in6 addr; guint rs_timeout; + guint watch_id; void *user_data; }; @@ -1426,21 +1438,20 @@ static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT; static const struct in6_addr in6addr_all_routers_mc = IN6ADDR_ALL_ROUTERS_MC_INIT; -/* from netinet/in.h */ -struct in6_pktinfo { - struct in6_addr ipi6_addr; /* src/dst IPv6 address */ - unsigned int ipi6_ifindex; /* send/recv interface index */ -}; - static void rs_cleanup(struct rs_cb_data *data) { - g_io_channel_shutdown(data->channel, TRUE, NULL); - g_io_channel_unref(data->channel); - data->channel = 0; + if (data->channel != NULL) { + g_io_channel_shutdown(data->channel, TRUE, NULL); + g_io_channel_unref(data->channel); + data->channel = NULL; + } if (data->rs_timeout > 0) g_source_remove(data->rs_timeout); + if (data->watch_id > 0) + g_source_remove(data->watch_id); + g_free(data); } @@ -1454,7 +1465,7 @@ static gboolean rs_timeout_cb(gpointer user_data) return FALSE; if (data->callback != NULL) - data->callback(NULL, data->user_data); + data->callback(NULL, 0, data->user_data); data->rs_timeout = 0; rs_cleanup(data); @@ -1486,15 +1497,18 @@ static int icmpv6_recv(int fd, gpointer user_data) len = recvmsg(fd, &mhdr, 0); if (len < 0) { - data->callback(NULL, data->user_data); + data->callback(NULL, 0, data->user_data); + rs_cleanup(data); return -errno; } hdr = (struct nd_router_advert *)buf; + DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len, + sizeof(struct nd_router_advert)); if (hdr->nd_ra_code != 0) return 0; - data->callback(hdr, data->user_data); + data->callback(hdr, len, data->user_data); rs_cleanup(data); return len; @@ -1575,7 +1589,7 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest) DBG(""); - fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW); + fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW); if (fd < 0) return -errno; @@ -1689,7 +1703,7 @@ int __connman_inet_ipv6_send_rs(int index, int timeout, data->user_data = user_data; data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data); - sk = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6); if (sk < 0) return -errno; @@ -1709,7 +1723,7 @@ int __connman_inet_ipv6_send_rs(int index, int timeout, g_io_channel_set_encoding(data->channel, NULL, NULL); g_io_channel_set_buffered(data->channel, FALSE); - g_io_add_watch(data->channel, + data->watch_id = g_io_add_watch(data->channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, icmpv6_event, data); @@ -1717,3 +1731,53 @@ int __connman_inet_ipv6_send_rs(int index, int timeout, return 0; } + +GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr, + unsigned int length) +{ + GSList *prefixes = NULL; + uint8_t *pos; + int len; + + if (length <= sizeof(struct nd_router_advert)) + return NULL; + + len = length - sizeof(struct nd_router_advert); + pos = (uint8_t *)hdr + sizeof(struct nd_router_advert); + + while (len > 0) { + struct nd_opt_prefix_info *pinfo; + char prefix_str[INET6_ADDRSTRLEN+1], *str; + const char *prefix; + int optlen; + + if (len < 2) + break; + + optlen = pos[1] << 3; + if (optlen == 0 || optlen > len) + break; + + switch (pos[0]) { + case ND_OPT_PREFIX_INFORMATION: + pinfo = (struct nd_opt_prefix_info *)pos; + prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, + prefix_str, INET6_ADDRSTRLEN); + if (prefix == NULL) + break; + + str = g_strdup_printf("%s/%d", prefix, + pinfo->nd_opt_pi_prefix_len); + prefixes = g_slist_append(prefixes, str); + + DBG("prefix %s", str); + + break; + } + + len -= optlen; + pos += optlen; + } + + return prefixes; +}