#include <vconf-keys.h>
#include <tzplatform_config.h>
#include <system_info.h>
-#include <stdint.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
#include "log.h"
#include "util.h"
#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 {
g_error_free(error);
}
- chmod(pathname, S_IRUSR | S_IWUSR);
- DBG("Successfully saved keyfile %s", pathname);
+ if (chmod(pathname, S_IRUSR | S_IWUSR) < 0)
+ DBG("Failed to change mode");
+ else
+ DBG("Successfully saved keyfile %s", pathname);
g_free(keydata);
}
errno = 0;
if (execve(file_path, args, envs) == -1) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Fail to execute command (%s)", error_buf);
+ DBG("Fail to execute command (%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
exit(1);
}
} else if (pid > 0) {
return rv;
}
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("failed to fork(%s)", error_buf);
+ DBG("failed to fork(%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -EIO;
}
errno = 0;
if (execv(args[0], args) == -1) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Fail to execute command (%s)", error_buf);
+ DBG("Fail to execute command (%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
g_strfreev(args);
exit(1);
}
return rv;
}
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("failed to fork(%s)", error_buf);
+ DBG("failed to fork(%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
g_strfreev(args);
return -EIO;
state = sigaction(SIGCHLD, &act, 0);
if (state != 0) {
- DBG("sigaction() : %d");
+ DBG("sigaction() : %d", state);
return -1;
}
errno = 0;
if (execvp(file_path, args) == -1) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- ERR("Fail to execute command (%s)", error_buf);
+ ERR("Fail to execute command (%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -1;
}
} else if (pid > 0) {
return rv;
}
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("failed to fork(%s)", error_buf);
+ DBG("failed to fork(%s)",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -EIO;
}
state = sigaction(SIGCHLD, &act, 0);
if (state != 0) {
- DBG("sigaction() : %d");
+ DBG("sigaction() : %d", state);
return -1;
}
errno = 0;
sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sock < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to create socket : %s", error_buf);
+ DBG("Failed to create socket : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -1;
}
close(sock);
if (result < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to get ifr index: %s", error_buf);
+ DBG("Failed to get ifr index: %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -1;
}
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to create socket : %s", error_buf);
+ DBG("Failed to create socket : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -1;
}
if (ioctl(sock, SIOCADDRT, &rt) < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to set route address : %s", error_buf);
+ DBG("Failed to set route address : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
close(sock);
return -1;
}
sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to create socket : %s", error_buf);
+ DBG("Failed to create socket : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
return -1;
}
if (ioctl(sock, SIOCDELRT, &rt) < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to set route address : %s", error_buf);
+ DBG("Failed to set route address : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
close(sock);
return -1;
}
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;
-
- n->nlmsg_seq = seq = ++rtnl->seq;
-
- if (answer == NULL)
- n->nlmsg_flags |= NLM_F_ACK;
-
- status = sendmsg(rtnl->fd, &msg, 0);
- if (status < 0) {
- DBG("failed to send message to kernel, status: %d", status);
- 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;
- 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;
- }
+ memset(&rt, 0, sizeof(rt));
- DBG("Unexpected reply");
+ rt.rtmsg_dst_len = prefix_len;
- 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);
- return -1;
- }
- }
-}
+ rt.rtmsg_flags = RTF_UP | RTF_HOST;
-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.");
+ errno = 0;
+ if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
+ DBG("inet_pton failed : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
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.");
+ if (gateway != NULL) {
+ rt.rtmsg_flags |= RTF_GATEWAY;
+ if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
+ DBG("inet_pton failed : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
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) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to create socket : %s", error_buf);
+ DBG("Failed to create socket : %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
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) {
+ DBG("Failed to add route: %s",
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+ 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;
-
- 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;
- }
+ rt.rtmsg_metric = 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;
-}
-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;
- }
+ rt.rtmsg_ifindex = 0;
- 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)
if (execute_mdnsd_script("start") < 0) {
ERR("Failed to launch mdnsresponder daemon");
netconfig_error_invalid_parameter(context);
- return FALSE;
+ return TRUE;
}
mdnsd_ref_count++;
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;