X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Futils%2Futil.c;h=27c2238441ba2292c0a5a077cc0605938cc02d57;hb=fd6e2995141fffefb2a78ee290a6cea694690d5e;hp=9e1b46a7d78a4e5925078541f603dae05450ae67;hpb=5ad4bdeb982e1e27b8994ba9d2710f76382a50cd;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/utils/util.c b/src/utils/util.c index 9e1b46a..27c2238 100755 --- a/src/utils/util.c +++ b/src/utils/util.c @@ -34,9 +34,6 @@ #include #include #include -#include -#include -#include #include "log.h" #include "util.h" @@ -52,23 +49,6 @@ #define HEADED_PLUGIN_FILEPATH "/usr/lib/net-config-plugin-headed.so" #define TELEPHONY_PLUGIN_FILEPATH "/usr/lib/net-config-plugin-telephony.so" -typedef struct { - uint8_t family; - uint8_t bytelen; - int16_t bitlen; - uint32_t flags; - uint32_t data[8]; -} netconfig_inet_prefix_s; - -typedef struct { - int fd; - struct sockaddr_nl local; - struct sockaddr_nl peer; - uint32_t seq; - uint32_t dump; -} netconfig_rtnl_s; -netconfig_rtnl_s rth = { .fd = -1 }; - static gboolean netconfig_device_picker_test = FALSE; static int mdnsd_ref_count = 0; typedef struct { @@ -782,190 +762,36 @@ int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gi return 1; } -static int __netconfig_rtnl_talk(netconfig_rtnl_s *rtnl, struct nlmsghdr *n, pid_t peer, - unsigned groups, struct nlmsghdr *answer) +int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) { - struct nlmsghdr *h; - struct sockaddr_nl nladdr; - struct iovec iov = { - .iov_base = (void*)n, - .iov_len = n->nlmsg_len - }; - struct msghdr msg = { - .msg_name = &nladdr, - .msg_namelen = sizeof(nladdr), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - int status; - unsigned seq; - char buf[16384]; + struct in6_rtmsg rt; + int fd = 0; + int err = 0; char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = peer; - nladdr.nl_groups = groups; + memset(&rt, 0, sizeof(rt)); - n->nlmsg_seq = seq = ++rtnl->seq; + rt.rtmsg_dst_len = prefix_len; - if (answer == NULL) - n->nlmsg_flags |= NLM_F_ACK; + rt.rtmsg_flags = RTF_UP | RTF_HOST; - status = sendmsg(rtnl->fd, &msg, 0); - if (status < 0) { - DBG("failed to send message to kernel, status: %d", status); + errno = 0; + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("inet_pton failed : %s", error_buf); return -1; } - memset(buf, 0, sizeof(buf)); - - iov.iov_base = buf; - - while (1) { - iov.iov_len = sizeof(buf); - status = recvmsg(rtnl->fd, &msg, 0); - DBG("status: %d", status); - - if (status < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("netlink receive error %s (%d)", error_buf, errno); - return -1; - } - if (status == 0) { - DBG("EOF on netlink"); - return -1; - } - if (msg.msg_namelen != sizeof(nladdr)) { - DBG("sender address length == %d", msg.msg_namelen); - return -1; - } - for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) { - int len = h->nlmsg_len; - int l = len - sizeof(*h); - - if (l < 0 || len > status) { - if (msg.msg_flags & MSG_TRUNC) { - DBG("truncated message"); - return -1; - } - DBG("malformed message: len=%d", len); - return -1; - } - - if (nladdr.nl_pid != peer || - h->nlmsg_pid != rtnl->local.nl_pid || - h->nlmsg_seq != seq) { - /** Don't forget to skip that message. */ - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - continue; - } - - if (h->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); - if (l < sizeof(struct nlmsgerr)) { - DBG("Error truncated message"); - } else { - if (!err->error) { - if (answer) - memcpy(answer, h, h->nlmsg_len); - return 0; - } - - errno = -err->error; - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("RTNETLINK answers: %s", error_buf); - } - return -1; - } - if (answer) { - memcpy(answer, h, h->nlmsg_len); - return 0; - } - - DBG("Unexpected reply"); - - status -= NLMSG_ALIGN(len); - h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); - } - if (msg.msg_flags & MSG_TRUNC) { - DBG("Message truncated"); - continue; - } - if (status) { - DBG("Remnant of size %d", status); + DBG("inet_pton failed : %s", error_buf); return -1; } } -} -static int __netconfig_get_prefix(netconfig_inet_prefix_s *dst, char *arg, int family) -{ - if (family != AF_UNSPEC && family != AF_INET6) { - DBG("Error: invalid address family."); - return -1; - } - - memset(dst, 0, sizeof(*dst)); - - if (strchr(arg, ':')) { - dst->family = AF_INET6; - if (inet_pton(AF_INET6, arg, dst->data) <= 0) { - DBG("Error: invalid ipv6 address."); - return -1; - } - dst->bytelen = 16; - dst->bitlen = 128; - } - - return 0; -} - -static int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, - int alen) -{ - int len = RTA_LENGTH(alen); - struct rtattr *rta; - - if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) { - DBG("Error message exceeded bound of %d", maxlen); - return -1; - } - rta = NLMSG_TAIL(n); - rta->rta_type = type; - rta->rta_len = len; - memcpy(RTA_DATA(rta), data, alen); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); - - return 0; -} - -static int __netconfig_iproute_modify(int cmd, unsigned flags, char *interface, char *ip_addr) -{ - struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[1024]; - } req; - - struct ifreq ifr; - int fd, idx, ret; - char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; - - memset(&req, 0, sizeof(req)); - - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST|flags; - req.n.nlmsg_type = cmd; - req.r.rtm_family = AF_INET6; - - if (cmd != RTM_DELROUTE) { - req.r.rtm_protocol = RTPROT_BOOT; - req.r.rtm_type = RTN_UNICAST; - } + rt.rtmsg_metric = 1; fd = socket(AF_INET6, SOCK_DGRAM, 0); if (fd < 0) { @@ -974,144 +800,78 @@ static int __netconfig_iproute_modify(int cmd, unsigned flags, char *interface, return -1; } - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1); - ioctl(fd, SIOCGIFINDEX, &ifr); - idx = ifr.ifr_ifindex; - close(fd); + rt.rtmsg_ifindex = 0; - if (ifr.ifr_ifindex == 0) { - DBG("Cannot find device %s", interface); - return -1; + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; } - netconfig_inet_prefix_s dst; - - ret = __netconfig_get_prefix(&dst, ip_addr, req.r.rtm_family); - if (ret < 0) + if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) { + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + DBG("Failed to add route: %s", error_buf); + close(fd); return -1; - - req.r.rtm_dst_len = dst.bitlen; - if (dst.bytelen) { - ret = addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); - if (ret < 0) - return -1; } - ret = addattr_l(&req.n, sizeof(req), RTA_OIF, &idx, sizeof(uint32_t)); - if (ret < 0) - return -1; - - if (__netconfig_rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) { - DBG("__netconfig_rtnl_talk failed"); - return -1; - } + close(fd); - return 0; + return 1; } -static void __netconfig_rtnl_close() +int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) { - if (rth.fd >= 0) { - close(rth.fd); - rth.fd = -1; - } -} + struct in6_rtmsg rt; + int fd = 0; + int err = 0; -static int __netconfig_rtnl_open(netconfig_rtnl_s *rth, unsigned subscriptions, - int protocol) -{ - socklen_t addr_len; - int sndbuf = 32768; - int rcvbuf = 1024 * 1024; - char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, }; + memset(&rt, 0, sizeof(rt)); - memset(rth, 0, sizeof(*rth)); + rt.rtmsg_dst_len = prefix_len; - rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol); - if (rth->fd < 0) { - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("Failed to open netlink socket: %s", error_buf); - return -1; - } + rt.rtmsg_flags = RTF_UP | RTF_HOST; - if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) { - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("Failed to set option(SO_SNDBUF) on socket [Error: %s]", error_buf); - return -1; + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + err = -errno; + return err; } - if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) { - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("Failed to set option(SO_RCVBUF) on socket [Error: %s]", error_buf); - return -1; + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { + err = -errno; + return err; + } } - memset(&rth->local, 0, sizeof(rth->local)); - rth->local.nl_family = AF_NETLINK; - rth->local.nl_groups = subscriptions; + rt.rtmsg_metric = 1; - if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("Failed to bind netlink socket [Error: %s]", error_buf); - return -1; - } - - addr_len = sizeof(rth->local); - if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { - strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); - DBG("Failed to getsockname [Error: %s]", error_buf); - return -1; - } - if (addr_len != sizeof(rth->local)) { - DBG("Wrong address length %d", addr_len); - return -1; - } - if (rth->local.nl_family != AF_NETLINK) { - DBG("Wrong address family %d", rth->local.nl_family); + fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) return -1; - } - rth->seq = time(NULL); - return 0; -} + rt.rtmsg_ifindex = 0; -int netconfig_add_route_ipv6(gchar *interface, gchar *gateway) -{ - int ret = __netconfig_rtnl_open(&rth, 0, NETLINK_ROUTE); - if (ret < 0) { - DBG("Failed to open rtnl socket"); - return -1; - } - - ret = __netconfig_iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_EXCL, interface, gateway); - if (ret < 0) { - DBG("Failed to modify ipv6 route."); - __netconfig_rtnl_close(); - return -1; + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; } - __netconfig_rtnl_close(); - return 0; -} - -int netconfig_del_route_ipv6(gchar *interface, gchar *gateway) -{ - int ret = __netconfig_rtnl_open(&rth, 0, NETLINK_ROUTE); - if (ret < 0) { - DBG("Failed to open rtnl socket"); + if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) { + DBG("Failed to del route: %d\n", err); + close(fd); return -1; } - ret = __netconfig_iproute_modify(RTM_DELROUTE, NLM_F_CREATE|NLM_F_EXCL, interface, gateway); - if (ret < 0) { - DBG("Failed to delete ipv6 route."); - __netconfig_rtnl_close(); - return -1; - } + close(fd); - __netconfig_rtnl_close(); - return 0; + return 1; } gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context) @@ -1218,7 +978,7 @@ gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context, if (execute_mdnsd_script("start") < 0) { ERR("Failed to launch mdnsresponder daemon"); netconfig_error_invalid_parameter(context); - return FALSE; + return TRUE; } mdnsd_ref_count++; @@ -1587,6 +1347,9 @@ bool netconfig_check_feature_supported(netconfig_supported_feature_e feature) case NETCONFIG_SUPPORTED_FEATURE_WIFI_DIRECT: key = WIFI_DIRECT_FEATURE; break; + case NETCONFIG_SUPPORTED_FEATURE_WIFI_SOFTAP: + key = WIFI_SOFTAP_FEATURE; + break; default: ERR("Uknown feature"); return false;