5 * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
6 * Copyright (C) 2003-2005 Go-Core Project
7 * Copyright (C) 2003-2006 Helsinki University of Technology
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <linux/sockios.h>
38 #include <arpa/inet.h>
39 #include <net/route.h>
40 #include <net/ethernet.h>
42 #include <net/if_arp.h>
43 #include <netinet/icmp6.h>
45 #include <linux/if_tun.h>
48 #include <linux/fib_rules.h>
51 #include <gdhcp/gdhcp.h>
53 #define NLMSG_TAIL(nmsg) \
54 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
55 NLMSG_ALIGN((nmsg)->nlmsg_len)))
57 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
58 int type, const void *data, size_t data_length)
63 length = RTA_LENGTH(data_length);
65 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
70 rta->rta_len = length;
71 memcpy(RTA_DATA(rta), data, data_length);
72 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
77 int __connman_inet_modify_address(int cmd, int flags,
78 int index, int family,
81 unsigned char prefixlen,
82 const char *broadcast)
84 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
85 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
86 RTA_LENGTH(sizeof(struct in6_addr)) +
87 RTA_LENGTH(sizeof(struct in6_addr))];
89 struct nlmsghdr *header;
90 struct sockaddr_nl nl_addr;
91 struct ifaddrmsg *ifaddrmsg;
92 struct in6_addr ipv6_addr;
93 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
96 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
97 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
98 address, peer, prefixlen, broadcast);
103 if (family != AF_INET && family != AF_INET6)
106 memset(&request, 0, sizeof(request));
108 header = (struct nlmsghdr *)request;
109 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
110 header->nlmsg_type = cmd;
111 header->nlmsg_flags = NLM_F_REQUEST | flags;
112 header->nlmsg_seq = 1;
114 ifaddrmsg = NLMSG_DATA(header);
115 ifaddrmsg->ifa_family = family;
116 ifaddrmsg->ifa_prefixlen = prefixlen;
117 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
118 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
119 ifaddrmsg->ifa_index = index;
121 if (family == AF_INET) {
122 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
126 inet_pton(AF_INET, broadcast, &ipv4_bcast);
128 ipv4_bcast.s_addr = ipv4_addr.s_addr |
129 htonl(0xfffffffflu >> prefixlen);
132 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
135 err = __connman_inet_rtnl_addattr_l(header,
144 err = __connman_inet_rtnl_addattr_l(header,
152 err = __connman_inet_rtnl_addattr_l(header,
160 } else if (family == AF_INET6) {
161 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
164 err = __connman_inet_rtnl_addattr_l(header,
173 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
177 memset(&nl_addr, 0, sizeof(nl_addr));
178 nl_addr.nl_family = AF_NETLINK;
180 if ((err = sendto(sk, request, header->nlmsg_len, 0,
181 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
192 bool __connman_inet_is_any_addr(const char *address, int family)
195 struct addrinfo hints;
196 struct addrinfo *result = NULL;
197 struct sockaddr_in6 *in6 = NULL;
198 struct sockaddr_in *in4 = NULL;
200 if (!address || !*address)
203 memset(&hints, 0, sizeof(struct addrinfo));
205 hints.ai_family = family;
207 if (getaddrinfo(address, NULL, &hints, &result))
211 if (result->ai_family == AF_INET6) {
212 in6 = (struct sockaddr_in6*)result->ai_addr;
213 ret = IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr);
214 } else if (result->ai_family == AF_INET) {
215 in4 = (struct sockaddr_in*)result->ai_addr;
216 ret = in4->sin_addr.s_addr == INADDR_ANY;
219 freeaddrinfo(result);
226 int connman_inet_ifindex(const char *name)
234 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
238 memset(&ifr, 0, sizeof(ifr));
239 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
241 err = ioctl(sk, SIOCGIFINDEX, &ifr);
248 return ifr.ifr_ifindex;
251 char *connman_inet_ifname(int index)
259 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
263 memset(&ifr, 0, sizeof(ifr));
264 ifr.ifr_ifindex = index;
266 err = ioctl(sk, SIOCGIFNAME, &ifr);
273 return g_strdup(ifr.ifr_name);
276 int connman_inet_ifup(int index)
281 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
285 memset(&ifr, 0, sizeof(ifr));
286 ifr.ifr_ifindex = index;
288 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
293 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
298 if (ifr.ifr_flags & IFF_UP) {
303 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
305 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
318 int connman_inet_ifdown(int index)
320 struct ifreq ifr, addr_ifr;
321 struct sockaddr_in *addr;
324 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
328 memset(&ifr, 0, sizeof(ifr));
329 ifr.ifr_ifindex = index;
331 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
336 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
341 memset(&addr_ifr, 0, sizeof(addr_ifr));
342 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
343 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
344 addr->sin_family = AF_INET;
345 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
346 connman_warn("Could not clear IPv4 address index %d", index);
348 if (!(ifr.ifr_flags & IFF_UP)) {
353 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
355 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
366 bool connman_inet_is_ifup(int index)
372 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
374 connman_warn("Failed to open socket");
378 memset(&ifr, 0, sizeof(ifr));
379 ifr.ifr_ifindex = index;
381 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
382 connman_warn("Failed to get interface name for interface %d", index);
386 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
387 connman_warn("Failed to get interface flags for index %d", index);
391 if (ifr.ifr_flags & IFF_UP)
401 struct in6_addr ifr6_addr;
402 __u32 ifr6_prefixlen;
403 unsigned int ifr6_ifindex;
406 int connman_inet_set_ipv6_address(int index,
407 struct connman_ipaddress *ipaddress)
410 unsigned char prefix_len;
413 if (!ipaddress->local)
416 prefix_len = ipaddress->prefixlen;
417 address = ipaddress->local;
419 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
421 err = __connman_inet_modify_address(RTM_NEWADDR,
422 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
423 address, NULL, prefix_len, NULL);
425 connman_error("%s: %s", __func__, strerror(-err));
432 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
435 unsigned char prefix_len;
436 const char *address, *broadcast, *peer;
438 if (!ipaddress->local)
441 prefix_len = ipaddress->prefixlen;
442 address = ipaddress->local;
443 broadcast = ipaddress->broadcast;
444 peer = ipaddress->peer;
446 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
448 err = __connman_inet_modify_address(RTM_NEWADDR,
449 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
450 address, peer, prefix_len, broadcast);
452 connman_error("%s: %s", __func__, strerror(-err));
459 int connman_inet_clear_ipv6_address(int index, const char *address,
464 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
469 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
470 address, NULL, prefix_len, NULL);
472 connman_error("%s: %s", __func__, strerror(-err));
479 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
482 unsigned char prefix_len;
483 const char *address, *broadcast, *peer;
485 prefix_len = ipaddress->prefixlen;
486 address = ipaddress->local;
487 broadcast = ipaddress->broadcast;
488 peer = ipaddress->peer;
490 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
491 address, prefix_len, peer, broadcast);
496 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
497 address, peer, prefix_len, broadcast);
499 connman_error("%s: %s", __func__, strerror(-err));
506 int connman_inet_add_host_route(int index, const char *host,
509 return connman_inet_add_network_route(index, host, gateway, NULL);
512 int connman_inet_del_host_route(int index, const char *host)
514 return connman_inet_del_network_route(index, host);
517 int connman_inet_add_network_route(int index, const char *host,
523 struct sockaddr_in addr;
526 DBG("index %d host %s gateway %s netmask %s", index,
527 host, gateway, netmask);
529 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
535 memset(&ifr, 0, sizeof(ifr));
536 ifr.ifr_ifindex = index;
538 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
544 DBG("ifname %s", ifr.ifr_name);
546 memset(&rt, 0, sizeof(rt));
547 rt.rt_flags = RTF_UP;
550 * Set RTF_GATEWAY only when gateway is set and the gateway IP address
551 * is not IPv4 any address (0.0.0.0). If the given gateway IP address is
552 * any address adding of route will fail when RTF_GATEWAY set. Passing
553 * gateway as NULL or INADDR_ANY should have the same effect. Setting
554 * the gateway address later to the struct is not affected by this,
555 * since given IPv4 any address (0.0.0.0) equals the value set with
558 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET))
559 rt.rt_flags |= RTF_GATEWAY;
561 rt.rt_flags |= RTF_HOST;
563 memset(&addr, 0, sizeof(addr));
564 addr.sin_family = AF_INET;
565 addr.sin_addr.s_addr = inet_addr(host);
566 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
568 memset(&addr, 0, sizeof(addr));
569 addr.sin_family = AF_INET;
571 addr.sin_addr.s_addr = inet_addr(gateway);
573 addr.sin_addr.s_addr = INADDR_ANY;
574 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
576 memset(&addr, 0, sizeof(addr));
577 addr.sin_family = AF_INET;
578 addr.sin_addr.s_addr = INADDR_ANY;
580 addr.sin_addr.s_addr = inet_addr(netmask);
582 addr.sin_addr.s_addr = INADDR_ANY;
583 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
585 rt.rt_dev = ifr.ifr_name;
587 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
594 connman_error("Adding host route failed (%s)",
600 int connman_inet_del_network_route(int index, const char *host)
604 struct sockaddr_in addr;
607 DBG("index %d host %s", index, host);
609 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
615 memset(&ifr, 0, sizeof(ifr));
616 ifr.ifr_ifindex = index;
618 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
624 DBG("ifname %s", ifr.ifr_name);
626 memset(&rt, 0, sizeof(rt));
627 rt.rt_flags = RTF_UP | RTF_HOST;
629 memset(&addr, 0, sizeof(addr));
630 addr.sin_family = AF_INET;
631 addr.sin_addr.s_addr = inet_addr(host);
632 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
634 rt.rt_dev = ifr.ifr_name;
636 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
643 connman_error("Deleting host route failed (%s)",
649 int connman_inet_del_ipv6_network_route(int index, const char *host,
650 unsigned char prefix_len)
655 DBG("index %d host %s", index, host);
660 memset(&rt, 0, sizeof(rt));
662 rt.rtmsg_dst_len = prefix_len;
664 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
669 rt.rtmsg_flags = RTF_UP | RTF_HOST;
672 rt.rtmsg_ifindex = index;
674 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
680 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
687 connman_error("Del IPv6 host route error (%s)",
693 int connman_inet_del_ipv6_host_route(int index, const char *host)
695 return connman_inet_del_ipv6_network_route(index, host, 128);
698 int connman_inet_add_ipv6_network_route(int index, const char *host,
700 unsigned char prefix_len)
705 DBG("index %d host %s gateway %s", index, host, gateway);
710 memset(&rt, 0, sizeof(rt));
712 rt.rtmsg_dst_len = prefix_len;
714 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
719 rt.rtmsg_flags = RTF_UP | RTF_HOST;
722 * Set RTF_GATEWAY only when gateway is set, the gateway IP address is
723 * not IPv6 any address (e.g., ::) and the address is valid (conversion
724 * succeeds). If the given gateway IP address is any address then
725 * adding of route will fail when RTF_GATEWAY set. Passing gateway as
726 * NULL or IPv6 any address should have the same effect.
729 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET6) &&
730 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) > 0)
731 rt.rtmsg_flags |= RTF_GATEWAY;
734 rt.rtmsg_ifindex = index;
736 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
742 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
749 connman_error("Set IPv6 host route error (%s)",
755 int connman_inet_add_ipv6_host_route(int index, const char *host,
758 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
761 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
766 DBG("index %d gateway %s", index, gateway);
771 memset(&rt, 0, sizeof(rt));
773 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
778 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
780 rt.rtmsg_dst_len = 0;
781 rt.rtmsg_ifindex = index;
783 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
789 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
796 connman_error("Clear default IPv6 gateway error (%s)",
802 int connman_inet_set_gateway_interface(int index)
806 struct sockaddr_in addr;
809 DBG("index %d", index);
811 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
817 memset(&ifr, 0, sizeof(ifr));
818 ifr.ifr_ifindex = index;
820 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
826 DBG("ifname %s", ifr.ifr_name);
828 memset(&rt, 0, sizeof(rt));
829 rt.rt_flags = RTF_UP;
831 memset(&addr, 0, sizeof(addr));
832 addr.sin_family = AF_INET;
833 addr.sin_addr.s_addr = INADDR_ANY;
835 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
836 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
837 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
839 rt.rt_dev = ifr.ifr_name;
841 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
848 connman_error("Setting default interface route failed (%s)",
854 int connman_inet_set_ipv6_gateway_interface(int index)
858 struct sockaddr_in6 addr;
859 const struct in6_addr any = IN6ADDR_ANY_INIT;
862 DBG("index %d", index);
864 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
870 memset(&ifr, 0, sizeof(ifr));
871 ifr.ifr_ifindex = index;
873 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
879 DBG("ifname %s", ifr.ifr_name);
881 memset(&rt, 0, sizeof(rt));
882 rt.rt_flags = RTF_UP;
884 memset(&addr, 0, sizeof(addr));
885 addr.sin6_family = AF_INET6;
886 addr.sin6_addr = any;
888 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
889 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
890 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
892 rt.rt_dev = ifr.ifr_name;
894 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
901 connman_error("Setting default interface route failed (%s)",
907 int connman_inet_clear_gateway_address(int index, const char *gateway)
911 struct sockaddr_in addr;
914 DBG("index %d gateway %s", index, gateway);
916 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
922 memset(&ifr, 0, sizeof(ifr));
923 ifr.ifr_ifindex = index;
925 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
931 DBG("ifname %s", ifr.ifr_name);
933 memset(&rt, 0, sizeof(rt));
934 rt.rt_flags = RTF_UP | RTF_GATEWAY;
936 memset(&addr, 0, sizeof(addr));
937 addr.sin_family = AF_INET;
938 addr.sin_addr.s_addr = INADDR_ANY;
939 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
941 memset(&addr, 0, sizeof(addr));
942 addr.sin_family = AF_INET;
943 addr.sin_addr.s_addr = inet_addr(gateway);
944 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
946 memset(&addr, 0, sizeof(addr));
947 addr.sin_family = AF_INET;
948 addr.sin_addr.s_addr = INADDR_ANY;
949 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
951 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
958 connman_error("Removing default gateway route failed (%s)",
964 int connman_inet_clear_gateway_interface(int index)
968 struct sockaddr_in addr;
971 DBG("index %d", index);
973 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
979 memset(&ifr, 0, sizeof(ifr));
980 ifr.ifr_ifindex = index;
982 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
988 DBG("ifname %s", ifr.ifr_name);
990 memset(&rt, 0, sizeof(rt));
991 rt.rt_flags = RTF_UP;
993 memset(&addr, 0, sizeof(addr));
994 addr.sin_family = AF_INET;
995 addr.sin_addr.s_addr = INADDR_ANY;
997 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
998 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
999 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1001 rt.rt_dev = ifr.ifr_name;
1003 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1010 connman_error("Removing default interface route failed (%s)",
1016 int connman_inet_clear_ipv6_gateway_interface(int index)
1020 struct sockaddr_in6 addr;
1021 const struct in6_addr any = IN6ADDR_ANY_INIT;
1024 DBG("index %d", index);
1026 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1032 memset(&ifr, 0, sizeof(ifr));
1033 ifr.ifr_ifindex = index;
1035 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1041 DBG("ifname %s", ifr.ifr_name);
1043 memset(&rt, 0, sizeof(rt));
1044 rt.rt_flags = RTF_UP;
1046 memset(&addr, 0, sizeof(addr));
1047 addr.sin6_family = AF_INET6;
1048 addr.sin6_addr = any;
1050 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1051 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1052 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1054 rt.rt_dev = ifr.ifr_name;
1056 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1063 connman_error("Removing default interface route failed (%s)",
1069 bool connman_inet_compare_subnet(int index, const char *host)
1072 struct in_addr _host_addr;
1073 in_addr_t host_addr, netmask_addr, if_addr;
1074 struct sockaddr_in *netmask, *addr;
1077 DBG("host %s", host);
1082 if (inet_aton(host, &_host_addr) == 0)
1084 host_addr = _host_addr.s_addr;
1086 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1090 memset(&ifr, 0, sizeof(ifr));
1091 ifr.ifr_ifindex = index;
1093 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1098 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1103 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1104 netmask_addr = netmask->sin_addr.s_addr;
1106 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1113 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1114 if_addr = addr->sin_addr.s_addr;
1116 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1119 static bool mem_mask_equal(const void *a, const void *b,
1120 const void *mask, size_t n)
1122 const unsigned char *addr1 = a;
1123 const unsigned char *addr2 = b;
1124 const unsigned char *bitmask = mask;
1127 for (i = 0; i < n; i++) {
1128 if ((addr1[i] ^ addr2[i]) & bitmask[i])
1135 bool connman_inet_compare_ipv6_subnet(int index, const char *host)
1137 struct ifaddrs *ifaddr, *ifa;
1139 char name[IF_NAMESIZE];
1140 struct in6_addr haddr;
1142 if (inet_pton(AF_INET6, host, &haddr) <= 0)
1145 if (!if_indextoname(index, name))
1148 DBG("index %d interface %s", index, name);
1150 if (getifaddrs(&ifaddr) < 0) {
1151 DBG("Cannot get addresses err %d/%s", errno, strerror(errno));
1155 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1156 struct sockaddr_in6 *iaddr;
1157 struct sockaddr_in6 *imask;
1162 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) != 0 ||
1163 ifa->ifa_addr->sa_family != AF_INET6)
1166 iaddr = (struct sockaddr_in6 *)ifa->ifa_addr;
1167 imask = (struct sockaddr_in6 *)ifa->ifa_netmask;
1169 rv = mem_mask_equal(&iaddr->sin6_addr, &haddr,
1176 freeifaddrs(ifaddr);
1180 int connman_inet_remove_from_bridge(int index, const char *bridge)
1188 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1194 memset(&ifr, 0, sizeof(ifr));
1195 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1196 ifr.ifr_ifindex = index;
1198 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1205 connman_error("Remove interface from bridge error %s",
1211 int connman_inet_add_to_bridge(int index, const char *bridge)
1219 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1225 memset(&ifr, 0, sizeof(ifr));
1226 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1227 ifr.ifr_ifindex = index;
1229 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1236 connman_error("Add interface to bridge error %s",
1242 int connman_inet_set_mtu(int index, int mtu)
1247 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1251 memset(&ifr, 0, sizeof(ifr));
1252 ifr.ifr_ifindex = index;
1254 err = ioctl(sk, SIOCGIFNAME, &ifr);
1257 err = ioctl(sk, SIOCSIFMTU, &ifr);
1264 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1274 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1278 index = if_nametoindex(tunnel);
1280 err = connman_inet_set_mtu(index, mtu);
1284 memset(&ifr, 0, sizeof(ifr));
1285 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1286 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1293 if ((ifr.ifr_flags ^ flags) & mask) {
1294 ifr.ifr_flags &= ~mask;
1295 ifr.ifr_flags |= mask & flags;
1296 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1298 connman_error("SIOCSIFFLAGS failed: %s",
1307 int connman_inet_create_tunnel(char **iface)
1312 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1315 connman_error("Failed to open /dev/net/tun: %s",
1320 memset(&ifr, 0, sizeof(ifr));
1321 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1323 for (i = 0; i < 256; i++) {
1324 sprintf(ifr.ifr_name, "tun%d", i);
1326 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1331 connman_error("Failed to find available tun device");
1336 *iface = g_strdup(ifr.ifr_name);
1342 * This callback struct is used when sending router and neighbor
1343 * solicitation and advertisement messages.
1346 GIOChannel *channel;
1348 struct sockaddr_in6 addr;
1354 #define CMSG_BUF_LEN 512
1355 #define IN6ADDR_ALL_NODES_MC_INIT \
1356 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1357 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1358 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1360 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1361 static const struct in6_addr in6addr_all_routers_mc =
1362 IN6ADDR_ALL_ROUTERS_MC_INIT;
1364 static void xs_cleanup(struct xs_cb_data *data)
1366 if (data->channel) {
1367 g_io_channel_shutdown(data->channel, TRUE, NULL);
1368 g_io_channel_unref(data->channel);
1369 data->channel = NULL;
1372 if (data->timeout > 0)
1373 g_source_remove(data->timeout);
1375 if (data->watch_id > 0)
1376 g_source_remove(data->watch_id);
1381 static gboolean rs_timeout_cb(gpointer user_data)
1383 struct xs_cb_data *data = user_data;
1385 DBG("user data %p", user_data);
1390 if (data->callback) {
1391 __connman_inet_rs_cb_t cb = data->callback;
1392 cb(NULL, 0, data->user_data);
1400 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1404 unsigned char chdr[CMSG_BUF_LEN];
1405 unsigned char buf[1540];
1406 struct nd_router_advert *hdr;
1407 struct sockaddr_in6 saddr;
1409 __connman_inet_rs_cb_t cb = data->callback;
1413 iov.iov_len = sizeof(buf);
1416 mhdr.msg_name = (void *)&saddr;
1417 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1419 mhdr.msg_iov = &iov;
1420 mhdr.msg_iovlen = 1;
1421 mhdr.msg_control = (void *)chdr;
1422 mhdr.msg_controllen = CMSG_BUF_LEN;
1424 len = recvmsg(fd, &mhdr, 0);
1426 cb(NULL, 0, data->user_data);
1430 hdr = (struct nd_router_advert *)buf;
1431 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1432 sizeof(struct nd_router_advert));
1433 if (hdr->nd_ra_code != 0)
1436 cb(hdr, len, data->user_data);
1441 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1444 struct xs_cb_data *xs_data = data;
1448 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1451 fd = g_io_channel_unix_get_fd(chan);
1452 ret = icmpv6_recv(fd, xs_data);
1457 xs_cleanup(xs_data);
1461 /* Adapted from RFC 1071 "C" Implementation Example */
1462 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1463 const void *extra_data, socklen_t extra_datalen)
1465 register unsigned long sum = 0;
1470 /* caller must make sure datalen is even */
1472 addr = (uint16_t *)phdr;
1473 for (i = 0; i < 20; i++)
1477 addr = (uint16_t *)data;
1485 count = extra_datalen;
1486 addr = (uint16_t *)extra_data;
1495 sum = (sum & 0xffff) + (sum >> 16);
1497 return (uint16_t)~sum;
1500 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1501 const struct in6_addr *source,
1502 unsigned char *buf, size_t len, uint16_t lifetime)
1505 struct in6_addr src;
1506 struct in6_addr dst;
1508 uint8_t reserved[3];
1515 struct icmp6_hdr icmp;
1516 struct nd_neighbor_solicit ns;
1517 struct nd_router_solicit rs;
1518 struct nd_router_advert ra;
1523 struct cmsghdr *cmsg;
1524 struct in6_pktinfo *pinfo;
1525 struct sockaddr_in6 dst, src;
1526 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1527 struct iovec iov[2];
1528 int fd, datalen, ret, iovlen = 1;
1532 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1536 memset(&frame, 0, sizeof(frame));
1537 memset(&dst, 0, sizeof(dst));
1539 if (type == ND_ROUTER_SOLICIT)
1540 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1541 else if (type == ND_ROUTER_ADVERT) {
1542 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1543 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1544 } else if (type == ND_NEIGHBOR_SOLICIT) {
1545 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1546 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1552 dst.sin6_addr = *dest;
1555 src.sin6_addr = *source;
1557 src.sin6_addr = in6addr_any;
1559 /* Fill in the IPv6 header */
1560 frame.ip.ip6_vfc = 0x60;
1561 frame.ip.ip6_plen = htons(datalen + len);
1562 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1563 frame.ip.ip6_hlim = 255;
1564 frame.ip.ip6_dst = dst.sin6_addr;
1565 frame.ip.ip6_src = src.sin6_addr;
1566 /* all other fields are already set to zero */
1568 /* Prepare pseudo header for csum */
1569 memset(&phdr, 0, sizeof(phdr));
1570 phdr.dst = dst.sin6_addr;
1571 phdr.src = src.sin6_addr;
1572 phdr.plen = htonl(datalen + len);
1573 phdr.nxt = IPPROTO_ICMPV6;
1575 /* Fill in remaining ICMP header fields */
1576 frame.i.icmp.icmp6_type = type;
1577 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1579 iov[0].iov_base = &frame;
1580 iov[0].iov_len = sizeof(frame.ip) + datalen;
1583 iov[1].iov_base = buf;
1584 iov[1].iov_len = len;
1588 dst.sin6_family = AF_INET6;
1589 msgh.msg_name = &dst;
1590 msgh.msg_namelen = sizeof(dst);
1592 msgh.msg_iovlen = iovlen;
1595 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1596 cmsg = (struct cmsghdr *)cbuf;
1597 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1598 pinfo->ipi6_ifindex = oif;
1600 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1601 cmsg->cmsg_level = IPPROTO_IPV6;
1602 cmsg->cmsg_type = IPV6_PKTINFO;
1603 msgh.msg_control = cmsg;
1604 msgh.msg_controllen = cmsg->cmsg_len;
1606 ret = sendmsg(fd, &msgh, 0);
1612 static inline void ipv6_addr_set(struct in6_addr *addr,
1613 uint32_t w1, uint32_t w2,
1614 uint32_t w3, uint32_t w4)
1616 addr->s6_addr32[0] = w1;
1617 addr->s6_addr32[1] = w2;
1618 addr->s6_addr32[2] = w3;
1619 addr->s6_addr32[3] = w4;
1622 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1623 struct in6_addr *solicited)
1625 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1626 htonl(0xFF000000) | addr->s6_addr32[3]);
1629 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1632 unsigned int val = 0;
1633 struct ipv6_mreq mreq;
1636 memset(&mreq, 0, sizeof(mreq));
1637 mreq.ipv6mr_interface = ifindex;
1638 mreq.ipv6mr_multiaddr = *mc_addr;
1640 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1644 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1649 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1652 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1659 int __connman_inet_ipv6_send_rs(int index, int timeout,
1660 __connman_inet_rs_cb_t callback, void *user_data)
1662 struct xs_cb_data *data;
1663 struct icmp6_filter filter;
1664 struct in6_addr solicit;
1665 struct in6_addr dst = in6addr_all_routers_mc;
1671 data = g_try_malloc0(sizeof(struct xs_cb_data));
1675 data->callback = callback;
1676 data->user_data = user_data;
1677 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1679 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1685 ICMP6_FILTER_SETBLOCKALL(&filter);
1686 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1688 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1689 sizeof(struct icmp6_filter));
1691 ipv6_addr_solict_mult(&dst, &solicit);
1692 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1693 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1695 data->channel = g_io_channel_unix_new(sk);
1696 g_io_channel_set_close_on_unref(data->channel, TRUE);
1698 g_io_channel_set_encoding(data->channel, NULL, NULL);
1699 g_io_channel_set_buffered(data->channel, FALSE);
1701 data->watch_id = g_io_add_watch(data->channel,
1702 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1703 icmpv6_event, data);
1705 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1710 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1711 struct in6_addr *advert)
1713 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1714 htonl(0xFF000000) | addr->s6_addr32[3]);
1717 #define MSG_SIZE_SEND 1452
1719 static int inc_len(int len, int inc)
1721 if (len > MSG_SIZE_SEND)
1728 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1729 GSList *prefixes, int router_lifetime)
1732 struct in6_addr src, *source;
1733 struct in6_addr dst = in6addr_all_nodes_mc;
1734 GDHCPIAPrefix *prefix;
1735 unsigned char buf[MSG_SIZE_SEND];
1736 char addr_str[INET6_ADDRSTRLEN];
1743 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1748 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1753 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1754 prefixes, inet_ntop(AF_INET6, source, addr_str,
1758 memset(buf, 0, MSG_SIZE_SEND);
1761 for (list = prefixes; list; list = list->next) {
1762 struct nd_opt_prefix_info *pinfo;
1764 prefix = list->data;
1765 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1767 len = inc_len(len, sizeof(*pinfo));
1773 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1774 pinfo->nd_opt_pi_len = 4;
1775 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1776 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1777 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1778 if (router_lifetime > 0) {
1779 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1780 pinfo->nd_opt_pi_preferred_time =
1781 htonl(prefix->preferred);
1783 pinfo->nd_opt_pi_reserved2 = 0;
1785 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1786 sizeof(struct in6_addr));
1788 DBG("[%d] index %d prefix %s/%d", count, index,
1789 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1790 INET6_ADDRSTRLEN), prefix->prefixlen);
1796 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1797 buf, len, router_lifetime);
1799 DBG("cannot send RA %d/%s", err, strerror(-err));
1807 void __connman_inet_ipv6_stop_recv_rs(void *context)
1812 xs_cleanup(context);
1815 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1819 unsigned char chdr[CMSG_BUF_LEN];
1820 unsigned char buf[1540];
1821 struct nd_router_solicit *hdr;
1822 struct sockaddr_in6 saddr;
1824 __connman_inet_recv_rs_cb_t cb = data->callback;
1828 iov.iov_len = sizeof(buf);
1831 mhdr.msg_name = (void *)&saddr;
1832 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1834 mhdr.msg_iov = &iov;
1835 mhdr.msg_iovlen = 1;
1836 mhdr.msg_control = (void *)chdr;
1837 mhdr.msg_controllen = CMSG_BUF_LEN;
1839 len = recvmsg(fd, &mhdr, 0);
1841 cb(NULL, 0, data->user_data);
1845 hdr = (struct nd_router_solicit *)buf;
1846 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1847 sizeof(struct nd_router_solicit));
1848 if (hdr->nd_rs_code != 0)
1851 cb(hdr, len, data->user_data);
1855 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1859 struct xs_cb_data *xs_data = data;
1863 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1866 fd = g_io_channel_unix_get_fd(chan);
1867 ret = icmpv6_rs_recv(fd, xs_data);
1872 xs_data->watch_id = 0;
1876 int __connman_inet_ipv6_start_recv_rs(int index,
1877 __connman_inet_recv_rs_cb_t callback,
1881 struct xs_cb_data *data;
1882 struct icmp6_filter filter;
1883 char addr_str[INET6_ADDRSTRLEN];
1886 data = g_try_malloc0(sizeof(struct xs_cb_data));
1890 data->callback = callback;
1891 data->user_data = user_data;
1893 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1901 ICMP6_FILTER_SETBLOCKALL(&filter);
1902 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1904 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1905 sizeof(struct icmp6_filter));
1907 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1909 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1910 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1911 err, strerror(-err));
1913 data->channel = g_io_channel_unix_new(sk);
1914 g_io_channel_set_close_on_unref(data->channel, TRUE);
1916 g_io_channel_set_encoding(data->channel, NULL, NULL);
1917 g_io_channel_set_buffered(data->channel, FALSE);
1919 data->watch_id = g_io_add_watch(data->channel,
1920 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1921 icmpv6_rs_event, data);
1928 static gboolean ns_timeout_cb(gpointer user_data)
1930 struct xs_cb_data *data = user_data;
1932 DBG("user data %p", user_data);
1937 if (data->callback) {
1938 __connman_inet_ns_cb_t cb = data->callback;
1939 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1947 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
1951 unsigned char chdr[CMSG_BUF_LEN];
1952 unsigned char buf[1540];
1953 struct nd_neighbor_advert *hdr;
1954 struct sockaddr_in6 saddr;
1956 __connman_inet_ns_cb_t cb = data->callback;
1960 iov.iov_len = sizeof(buf);
1963 mhdr.msg_name = (void *)&saddr;
1964 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1966 mhdr.msg_iov = &iov;
1967 mhdr.msg_iovlen = 1;
1968 mhdr.msg_control = (void *)chdr;
1969 mhdr.msg_controllen = CMSG_BUF_LEN;
1971 len = recvmsg(fd, &mhdr, 0);
1973 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1977 hdr = (struct nd_neighbor_advert *)buf;
1978 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1979 sizeof(struct nd_neighbor_advert));
1980 if (hdr->nd_na_code != 0)
1984 * We can receive any neighbor advertisement so we need to check if the
1985 * packet was meant for us and ignore the packet otherwise.
1987 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1988 sizeof(struct in6_addr)))
1991 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1996 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
2000 struct xs_cb_data *xs_data = data;
2004 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2007 fd = g_io_channel_unix_get_fd(chan);
2008 ret = icmpv6_nd_recv(fd, xs_data);
2013 xs_cleanup(xs_data);
2017 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
2018 struct in6_addr *addr,
2019 __connman_inet_ns_cb_t callback,
2022 struct xs_cb_data *data;
2023 struct icmp6_filter filter;
2024 struct in6_addr solicit;
2025 int sk, err, val = 1;
2027 if (timeout_ms <= 0)
2030 data = g_try_malloc0(sizeof(struct xs_cb_data));
2034 data->callback = callback;
2035 data->user_data = user_data;
2036 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
2041 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
2043 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2049 ICMP6_FILTER_SETBLOCKALL(&filter);
2050 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
2052 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2053 sizeof(struct icmp6_filter));
2055 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2056 &val, sizeof(val)) < 0) {
2058 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2064 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2065 &val, sizeof(val)) < 0) {
2067 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2074 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2076 ipv6_addr_solict_mult(addr, &solicit);
2077 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2078 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2080 data->channel = g_io_channel_unix_new(sk);
2081 g_io_channel_set_close_on_unref(data->channel, TRUE);
2083 g_io_channel_set_encoding(data->channel, NULL, NULL);
2084 g_io_channel_set_buffered(data->channel, FALSE);
2086 data->watch_id = g_io_add_watch(data->channel,
2087 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2088 icmpv6_nd_event, data);
2090 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2091 (unsigned char *)addr, 0, 0);
2093 DBG("Cannot send NS %d/%s", err, strerror(-err));
2100 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2101 unsigned int length)
2103 GSList *prefixes = NULL;
2107 if (length <= sizeof(struct nd_router_advert))
2110 len = length - sizeof(struct nd_router_advert);
2111 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2114 struct nd_opt_prefix_info *pinfo;
2115 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2122 optlen = pos[1] << 3;
2123 if (optlen == 0 || optlen > len)
2127 case ND_OPT_PREFIX_INFORMATION:
2128 pinfo = (struct nd_opt_prefix_info *)pos;
2129 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2130 prefix_str, INET6_ADDRSTRLEN);
2134 str = g_strdup_printf("%s/%d", prefix,
2135 pinfo->nd_opt_pi_prefix_len);
2136 prefixes = g_slist_prepend(prefixes, str);
2138 DBG("prefix %s", str);
2150 static int get_dest_addr(int family, int index, char *buf, int len)
2156 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2160 memset(&ifr, 0, sizeof(ifr));
2161 ifr.ifr_ifindex = index;
2163 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2164 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2169 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2170 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2175 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2181 DBG("index %d %s", index, ifr.ifr_name);
2183 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2184 connman_error("Get destination address failed (%s)",
2194 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2197 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2204 if (!inet_ntop(family, addr, buf, len)) {
2205 DBG("error %d/%s", errno, strerror(errno));
2212 int connman_inet_get_dest_addr(int index, char **dest)
2214 char addr[INET_ADDRSTRLEN];
2217 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2221 *dest = g_strdup(addr);
2223 DBG("destination %s", *dest);
2228 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2230 char addr[INET6_ADDRSTRLEN];
2233 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2237 *dest = g_strdup(addr);
2239 DBG("destination %s", *dest);
2244 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2247 int rcvbuf = 1024 * 4;
2249 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2251 connman_error("Can not open netlink socket: %s",
2256 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2257 sizeof(sndbuf)) < 0) {
2258 connman_error("SO_SNDBUF: %s", strerror(errno));
2262 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2263 sizeof(rcvbuf)) < 0) {
2264 connman_error("SO_RCVBUF: %s", strerror(errno));
2268 memset(&rth->local, 0, sizeof(rth->local));
2269 rth->local.nl_family = AF_NETLINK;
2270 rth->local.nl_groups = 0;
2272 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2273 sizeof(rth->local)) < 0) {
2274 connman_error("Can not bind netlink socket: %s",
2279 rth->seq = time(NULL);
2281 DBG("fd %d", rth->fd);
2286 struct inet_rtnl_cb_data {
2287 GIOChannel *channel;
2288 __connman_inet_rtnl_cb_t callback;
2291 struct __connman_inet_rtnl_handle *rtnl;
2295 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2297 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2299 if (data->channel) {
2300 g_io_channel_shutdown(data->channel, TRUE, NULL);
2301 g_io_channel_unref(data->channel);
2302 data->channel = NULL;
2305 DBG("data %p", data);
2307 if (data->rtnl_timeout > 0)
2308 g_source_remove(data->rtnl_timeout);
2310 if (data->watch_id > 0)
2311 g_source_remove(data->watch_id);
2314 __connman_inet_rtnl_close(rth);
2321 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2323 struct inet_rtnl_cb_data *data = user_data;
2325 DBG("user data %p", user_data);
2331 data->callback(NULL, data->user_data);
2333 data->rtnl_timeout = 0;
2334 inet_rtnl_cleanup(data);
2338 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2340 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2341 struct nlmsghdr *h = NULL;
2342 struct sockaddr_nl nladdr;
2343 socklen_t addr_len = sizeof(nladdr);
2344 unsigned char buf[4096];
2349 memset(buf, 0, sizeof(buf));
2350 memset(&nladdr, 0, sizeof(nladdr));
2352 fd = g_io_channel_unix_get_fd(chan);
2354 status = recvfrom(fd, buf, sizeof(buf), 0,
2355 (struct sockaddr *) &nladdr, &addr_len);
2357 if (errno == EINTR || errno == EAGAIN)
2366 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2367 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2374 struct nlmsgerr *err;
2378 if (!NLMSG_OK(h, len))
2381 if (h->nlmsg_seq != rth->seq) {
2383 DBG("skip %d/%d len %d", rth->seq,
2384 h->nlmsg_seq, h->nlmsg_len);
2386 len -= h->nlmsg_len;
2387 ptr += h->nlmsg_len;
2391 switch (h->nlmsg_type) {
2397 err = (struct nlmsgerr *)NLMSG_DATA(h);
2398 connman_error("RTNETLINK answers %s (%d)",
2399 strerror(-err->error), -err->error);
2406 if (h->nlmsg_seq == rth->seq) {
2407 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2409 rtnl_data->callback(h, rtnl_data->user_data);
2411 inet_rtnl_cleanup(rtnl_data);
2417 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2421 struct inet_rtnl_cb_data *rtnl_data = user_data;
2425 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2428 ret = inet_rtnl_recv(chan, rtnl_data);
2433 rtnl_data->callback(NULL, rtnl_data->user_data);
2434 inet_rtnl_cleanup(rtnl_data);
2438 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2439 struct nlmsghdr *n, int timeout,
2440 __connman_inet_rtnl_cb_t callback, void *user_data)
2442 struct sockaddr_nl nladdr;
2443 struct inet_rtnl_cb_data *data;
2446 memset(&nladdr, 0, sizeof(nladdr));
2447 nladdr.nl_family = AF_NETLINK;
2449 n->nlmsg_seq = ++rtnl->seq;
2452 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2456 data->callback = callback;
2457 data->user_data = user_data;
2459 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2460 inet_rtnl_timeout_cb, data);
2462 data->channel = g_io_channel_unix_new(rtnl->fd);
2464 g_io_channel_set_encoding(data->channel, NULL, NULL);
2465 g_io_channel_set_buffered(data->channel, FALSE);
2467 data->watch_id = g_io_add_watch(data->channel,
2468 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2469 inet_rtnl_event, data);
2471 n->nlmsg_flags |= NLM_F_ACK;
2473 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2474 (struct sockaddr *) &nladdr, sizeof(nladdr));
2475 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2477 connman_error("Can not talk to rtnetlink err %d %s",
2478 -errno, strerror(errno));
2482 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2483 connman_error("Sent %d bytes, msg truncated", err);
2490 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2492 DBG("handle %p", rth);
2500 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2503 int len = RTA_LENGTH(4);
2506 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2507 DBG("Error! max allowed bound %zd exceeded", maxlen);
2510 rta = NLMSG_TAIL(n);
2511 rta->rta_type = type;
2513 memcpy(RTA_DATA(rta), &data, 4);
2514 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2519 static int parse_rtattr(struct rtattr *tb[], int max,
2520 struct rtattr *rta, int len)
2522 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2523 while (RTA_OK(rta, len)) {
2524 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2525 tb[rta->rta_type] = rta;
2526 rta = RTA_NEXT(rta, len);
2529 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2534 struct get_route_cb_data {
2535 connman_inet_addr_cb_t callback;
2539 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2541 struct get_route_cb_data *data = user_data;
2542 struct rtattr *tb[RTA_MAX+1];
2543 struct rtmsg *r = NLMSG_DATA(answer);
2544 int len, index = -1;
2546 const char *addr = NULL;
2548 DBG("answer %p data %p", answer, user_data);
2553 len = answer->nlmsg_len;
2555 if (answer->nlmsg_type != RTM_NEWROUTE &&
2556 answer->nlmsg_type != RTM_DELROUTE) {
2557 connman_error("Not a route: %08x %08x %08x",
2558 answer->nlmsg_len, answer->nlmsg_type,
2559 answer->nlmsg_flags);
2563 len -= NLMSG_LENGTH(sizeof(*r));
2565 connman_error("BUG: wrong nlmsg len %d", len);
2569 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2572 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2574 if (tb[RTA_GATEWAY])
2575 addr = inet_ntop(r->rtm_family,
2576 RTA_DATA(tb[RTA_GATEWAY]),
2577 abuf, sizeof(abuf));
2579 DBG("addr %s index %d user %p", addr, index, data->user_data);
2582 if (data && data->callback)
2583 data->callback(addr, index, data->user_data);
2589 * Return the interface index that contains route to host.
2591 int __connman_inet_get_route(const char *dest_address,
2592 connman_inet_addr_cb_t callback, void *user_data)
2594 struct get_route_cb_data *data;
2595 struct addrinfo hints, *rp;
2596 struct __connman_inet_rtnl_handle *rth;
2599 DBG("dest %s", dest_address);
2604 memset(&hints, 0, sizeof(hints));
2605 hints.ai_family = AF_UNSPEC;
2606 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2608 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2612 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2618 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2619 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2620 rth->req.n.nlmsg_type = RTM_GETROUTE;
2621 rth->req.u.r.rt.rtm_family = rp->ai_family;
2622 rth->req.u.r.rt.rtm_table = 0;
2623 rth->req.u.r.rt.rtm_protocol = 0;
2624 rth->req.u.r.rt.rtm_scope = 0;
2625 rth->req.u.r.rt.rtm_type = 0;
2626 rth->req.u.r.rt.rtm_src_len = 0;
2627 rth->req.u.r.rt.rtm_tos = 0;
2629 if (rp->ai_family == AF_INET) {
2630 struct sockaddr_in *sin = (struct sockaddr_in *)rp->ai_addr;
2632 rth->req.u.r.rt.rtm_dst_len = 32;
2633 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2634 RTA_DST, &sin->sin_addr, sizeof(sin->sin_addr));
2635 } else if (rp->ai_family == AF_INET6) {
2636 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rp->ai_addr;
2638 rth->req.u.r.rt.rtm_dst_len = 128;
2639 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2640 RTA_DST, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
2645 err = __connman_inet_rtnl_open(rth);
2649 data = g_try_malloc(sizeof(struct get_route_cb_data));
2655 data->callback = callback;
2656 data->user_data = user_data;
2658 #define GET_ROUTE_TIMEOUT 2
2659 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2660 get_route_cb, data);
2669 __connman_inet_rtnl_close(rth);
2676 int connman_inet_check_ipaddress(const char *host)
2678 struct addrinfo hints;
2679 struct addrinfo *addr;
2682 memset(&hints, 0, sizeof(struct addrinfo));
2683 hints.ai_flags = AI_NUMERICHOST;
2686 result = getaddrinfo(host, NULL, &hints, &addr);
2688 result = addr->ai_family;
2695 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2696 bool connman_inet_check_hostname(const char *ptr, size_t len)
2701 * Not empty or complete length not over 255 characters.
2703 if ((len == 0) || (len > 256))
2707 * Consists of [[:alnum:]-]+ labels separated by [.]
2708 * a [_] is against RFC but seems to be "widely used"
2710 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2712 if ((*p == '-') || (*p == '_')) {
2714 * Not allowed at begin or end of a label.
2716 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2719 } else if (*p == '.') {
2721 * Each label has to be 1-63 characters;
2722 * we allow [.] at the end ('foo.bar.')
2726 if ((d <= 0) || (d >= 64))
2729 ptr = p + 1; /* Jump to the next label */
2731 } else if (isalnum((unsigned char)*p) == 0) {
2733 * Also numbers at the begin are fine
2742 char **__connman_inet_get_running_interfaces(void)
2746 struct ifreq *ifr = NULL;
2747 int sk, i, numif, count = 0;
2749 memset(&ifc, 0, sizeof(ifc));
2751 sk = socket(AF_INET, SOCK_DGRAM, 0);
2755 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2759 * Allocate some extra bytes just in case there will
2760 * be new interfaces added between two SIOCGIFCONF
2763 ifr = g_try_malloc0(ifc.ifc_len * 2);
2769 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2772 numif = ifc.ifc_len / sizeof(struct ifreq);
2774 result = g_try_malloc0((numif + 1) * sizeof(char *));
2780 for (i = 0; i < numif; i++) {
2781 struct ifreq *r = &ifr[i];
2782 struct in6_addr *addr6;
2786 * Note that we do not return loopback interfaces here as they
2787 * are not needed for our purposes.
2789 switch (r->ifr_addr.sa_family) {
2791 addr4 = ntohl(((struct sockaddr_in *)
2792 &r->ifr_addr)->sin_addr.s_addr);
2793 if (((addr4 & 0xff000000) >> 24) == 127)
2797 addr6 = &((struct sockaddr_in6 *)
2798 &r->ifr_addr)->sin6_addr;
2799 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2804 result[count++] = g_strdup(r->ifr_name);
2809 if (count < numif) {
2810 char **prev_result = result;
2811 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2813 g_free(prev_result);
2826 bool connman_inet_is_ipv6_supported()
2830 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2838 int __connman_inet_get_interface_address(int index, int family, void *address)
2840 struct ifaddrs *ifaddr, *ifa;
2842 char name[IF_NAMESIZE];
2844 if (!if_indextoname(index, name))
2847 DBG("index %d interface %s", index, name);
2849 if (getifaddrs(&ifaddr) < 0) {
2851 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2855 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2859 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2860 ifa->ifa_addr->sa_family == family) {
2861 if (family == AF_INET) {
2862 struct sockaddr_in *in4 = (struct sockaddr_in *)
2864 if (in4->sin_addr.s_addr == INADDR_ANY)
2866 memcpy(address, &in4->sin_addr,
2867 sizeof(struct in_addr));
2868 } else if (family == AF_INET6) {
2869 struct sockaddr_in6 *in6 =
2870 (struct sockaddr_in6 *)ifa->ifa_addr;
2871 if (memcmp(&in6->sin6_addr, &in6addr_any,
2872 sizeof(struct in6_addr)) == 0)
2874 memcpy(address, &in6->sin6_addr,
2875 sizeof(struct in6_addr));
2888 freeifaddrs(ifaddr);
2892 int __connman_inet_get_interface_mac_address(int index, uint8_t *mac_address)
2898 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2900 DBG("Open socket error");
2904 memset(&ifr, 0, sizeof(ifr));
2905 ifr.ifr_ifindex = index;
2907 err = ioctl(sk, SIOCGIFNAME, &ifr);
2909 DBG("Get interface name error");
2913 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
2915 DBG("Get MAC address error");
2919 memcpy(mac_address, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
2927 static int iprule_modify(int cmd, int family, uint32_t table_id,
2930 struct __connman_inet_rtnl_handle rth;
2933 memset(&rth, 0, sizeof(rth));
2935 rth.req.n.nlmsg_type = cmd;
2936 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2937 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2938 rth.req.u.r.rt.rtm_family = family;
2939 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2940 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2941 rth.req.u.r.rt.rtm_table = table_id;
2942 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2943 rth.req.u.r.rt.rtm_flags = 0;
2945 if (cmd == RTM_NEWRULE) {
2946 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2947 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2950 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2951 FRA_FWMARK, fwmark);
2953 if (table_id < 256) {
2954 rth.req.u.r.rt.rtm_table = table_id;
2956 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2957 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2958 FRA_TABLE, table_id);
2961 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2962 rth.req.u.r.rt.rtm_family = AF_INET;
2964 ret = __connman_inet_rtnl_open(&rth);
2968 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2971 __connman_inet_rtnl_close(&rth);
2976 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2978 /* ip rule add fwmark 9876 table 1234 */
2980 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2983 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2985 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2988 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2989 const char *gateway, unsigned char prefixlen)
2991 struct __connman_inet_rtnl_handle rth;
2992 unsigned char buf[sizeof(struct in6_addr)];
2994 int family = connman_inet_check_ipaddress(gateway);
2997 DBG("gateway %s/%u table %u", gateway, prefixlen, table_id);
3011 struct in_addr ipv4_subnet_addr, ipv4_mask;
3013 memset(&ipv4_subnet_addr, 0, sizeof(ipv4_subnet_addr));
3014 ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
3015 ipv4_subnet_addr.s_addr = inet_addr(gateway);
3016 ipv4_subnet_addr.s_addr &= ipv4_mask.s_addr;
3018 dst = g_strdup(inet_ntoa(ipv4_subnet_addr));
3021 ret = inet_pton(family, dst ? dst : gateway, buf);
3026 memset(&rth, 0, sizeof(rth));
3028 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3029 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
3030 rth.req.n.nlmsg_type = cmd;
3031 rth.req.u.r.rt.rtm_family = family;
3032 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
3033 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
3034 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3035 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3036 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3037 rth.req.u.r.rt.rtm_dst_len = prefixlen;
3039 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req),
3040 prefixlen > 0 ? RTA_DST : RTA_GATEWAY, buf, len);
3042 if (table_id < 256) {
3043 rth.req.u.r.rt.rtm_table = table_id;
3045 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3046 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3047 RTA_TABLE, table_id);
3050 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3053 ret = __connman_inet_rtnl_open(&rth);
3057 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3060 __connman_inet_rtnl_close(&rth);
3065 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
3066 const char *gateway)
3068 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
3070 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 0);
3073 int __connman_inet_add_subnet_to_table(uint32_t table_id, int ifindex,
3074 const char *gateway, unsigned char prefixlen)
3076 /* ip route add 1.2.3.4/24 dev eth0 table 1234 */
3077 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, prefixlen);
3080 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
3081 const char *gateway)
3083 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
3085 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 0);
3088 int __connman_inet_del_subnet_from_table(uint32_t table_id, int ifindex,
3089 const char *gateway, unsigned char prefixlen)
3091 /* ip route del 1.2.3.4/24 dev eth0 table 1234 */
3092 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, prefixlen);
3095 int __connman_inet_get_interface_ll_address(int index, int family,
3098 struct ifaddrs *ifaddr, *ifa;
3100 char name[IF_NAMESIZE];
3102 if (!if_indextoname(index, name))
3105 DBG("index %d interface %s", index, name);
3107 if (getifaddrs(&ifaddr) < 0) {
3109 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
3113 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3117 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
3118 ifa->ifa_addr->sa_family == family) {
3119 if (family == AF_INET) {
3120 struct sockaddr_in *in4 = (struct sockaddr_in *)
3122 if (in4->sin_addr.s_addr == INADDR_ANY)
3124 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
3125 ((in_addr_t) 0xa9fe0000))
3127 memcpy(address, &in4->sin_addr,
3128 sizeof(struct in_addr));
3129 } else if (family == AF_INET6) {
3130 struct sockaddr_in6 *in6 =
3131 (struct sockaddr_in6 *)ifa->ifa_addr;
3132 if (memcmp(&in6->sin6_addr, &in6addr_any,
3133 sizeof(struct in6_addr)) == 0)
3135 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
3138 memcpy(address, &in6->sin6_addr,
3139 sizeof(struct in6_addr));
3151 freeifaddrs(ifaddr);
3155 int __connman_inet_get_address_netmask(int ifindex,
3156 struct sockaddr_in *address,
3157 struct sockaddr_in *netmask)
3159 int sk, ret = -EINVAL;
3162 DBG("index %d", ifindex);
3164 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3168 memset(&ifr, 0, sizeof(ifr));
3169 ifr.ifr_ifindex = ifindex;
3171 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3174 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3177 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3178 sizeof(struct sockaddr_in));
3180 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3183 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3184 sizeof(struct sockaddr_in));
3192 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3193 struct in_addr *addr)
3197 char addrstr[INET_ADDRSTRLEN];
3198 struct in_addr taddr;
3199 GError *error = NULL;
3200 char *cmdline = NULL;
3203 char **pnpent = NULL;
3208 cmdline_file = "/proc/cmdline";
3210 pnp_file = "/proc/net/pnp";
3213 addr->s_addr = INADDR_NONE;
3215 if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3216 connman_error("%s: Cannot read %s %s\n", __func__,
3217 cmdline_file, error->message);
3221 if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3222 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3223 connman_error("%s: Cannot read %s %s\n", __func__,
3224 pnp_file, error->message);
3230 len = strlen(cmdline);
3235 /* remove newline */
3236 if (cmdline[len - 1] == '\n')
3237 cmdline[--len] = '\0';
3239 /* split in arguments (separated by space) */
3240 args = g_strsplit(cmdline, " ", 0);
3242 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3247 /* split in entries (by newlines) */
3248 pnpent = g_strsplit(pnp, "\n", 0);
3250 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3255 /* first find root argument */
3256 for (pp = args; *pp; pp++) {
3257 if (!strcmp(*pp, "root=/dev/nfs"))
3260 /* no rootnfs found */
3264 /* locate nfsroot argument */
3265 for (pp = args; *pp; pp++) {
3266 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3269 /* no nfsroot argument found */
3273 /* determine if nfsroot server is provided */
3274 nfsargs = strchr(*pp, '=');
3279 /* find whether serverip is present */
3280 s = strchr(nfsargs, ':');
3285 /* no serverip, use bootserver */
3286 for (pp = pnpent; *pp; pp++) {
3287 if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3290 /* no bootserver found */
3293 s = *pp + strlen("bootserver ");
3297 /* copy to addr string buffer */
3298 if (len >= sizeof(addrstr)) {
3299 connman_error("%s: Bad server\n", __func__);
3302 memcpy(addrstr, s, len);
3303 addrstr[len] = '\0';
3305 err = inet_pton(AF_INET, addrstr, addr);
3307 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3319 g_error_free(error);
3326 /* get interface out of which peer is reachable (IPv4 only) */
3327 static int get_peer_iface(struct in_addr *addr, char *ifname)
3329 struct ifaddrs *ifaddr, *ifa;
3330 struct sockaddr_in saddr, *ifsaddr;
3335 /* Obtain address(es) matching host/port */
3336 err = getifaddrs(&ifaddr);
3338 connman_error("%s: getifaddrs() failed %d (%s)\n",
3339 __func__, errno, strerror(errno));
3343 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3345 connman_error("%s: socket() failed %d (%s)\n",
3346 __func__, errno, strerror(errno));
3350 memset(&saddr, 0, sizeof(saddr));
3351 saddr.sin_family = AF_INET;
3352 saddr.sin_port = 0; /* any port */
3353 saddr.sin_addr = *addr;
3355 /* no need to bind, connect will select iface */
3356 err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3358 connman_error("%s: connect() failed: %d (%s)\n",
3359 __func__, errno, strerror(errno));
3363 socklen = sizeof(saddr);
3364 err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3366 connman_error("%s: getsockname() failed: %d (%s)\n",
3367 __func__, errno, strerror(errno));
3372 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3376 /* only IPv4 address */
3377 if (ifa->ifa_addr->sa_family != AF_INET)
3380 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3382 /* match address? */
3383 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3390 strcpy(ifname, ifa->ifa_name);
3396 freeifaddrs(ifaddr);
3401 bool __connman_inet_isrootnfs_device(const char *devname)
3403 struct in_addr addr;
3404 char ifname[IFNAMSIZ];
3406 return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3407 get_peer_iface(&addr, ifname) == 0 &&
3408 strcmp(devname, ifname) == 0;
3411 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3416 GError *error = NULL;
3418 char **pnpent = NULL;
3419 char **nameservers = NULL;
3422 pnp_file = "/proc/net/pnp";
3424 if (!g_file_test(pnp_file, G_FILE_TEST_EXISTS))
3427 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3428 connman_error("%s: Cannot read %s %s\n", __func__,
3429 pnp_file, error->message);
3433 /* split in entries (by newlines) */
3434 pnpent = g_strsplit(pnp, "\n", 0);
3436 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3442 * Perform two passes to retrieve a char ** array of
3443 * nameservers that are not 0.0.0.0
3445 * The first pass counts them, the second fills in the
3450 for (pass = 1; pass <= 2; pass++) {
3452 /* at the start of the second pass allocate */
3454 nameservers = g_new(char *, count + 1);
3457 for (pp = pnpent; *pp; pp++) {
3458 /* match 'nameserver ' at the start of each line */
3459 if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3462 /* compare it against 0.0.0.0 */
3463 s = *pp + strlen("nameserver ");
3464 if (!strcmp(s, "0.0.0.0"))
3467 /* on second pass fill in array */
3469 nameservers[count] = g_strdup(s);
3473 /* no nameservers? */
3477 /* and terminate char ** array with NULL */
3479 nameservers[count] = NULL;
3487 g_error_free(error);