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,
85 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
86 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
87 RTA_LENGTH(sizeof(struct in6_addr)) +
88 RTA_LENGTH(sizeof(struct in6_addr))];
90 struct nlmsghdr *header;
91 struct sockaddr_nl nl_addr;
92 struct ifaddrmsg *ifaddrmsg;
93 struct in6_addr ipv6_addr;
94 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
97 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
98 "prefixlen %hhu broadcast %s p2p %s", cmd, flags, index,
99 family, address, peer, prefixlen, broadcast,
100 is_p2p ? "true" : "false");
105 if (family != AF_INET && family != AF_INET6)
108 memset(&request, 0, sizeof(request));
110 header = (struct nlmsghdr *)request;
111 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
112 header->nlmsg_type = cmd;
113 header->nlmsg_flags = NLM_F_REQUEST | flags;
114 header->nlmsg_seq = 1;
116 ifaddrmsg = NLMSG_DATA(header);
117 ifaddrmsg->ifa_family = family;
118 ifaddrmsg->ifa_prefixlen = prefixlen;
119 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
120 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
121 ifaddrmsg->ifa_index = index;
123 if (family == AF_INET) {
124 if (inet_pton(AF_INET, address, &ipv4_addr) != 1)
128 if (inet_pton(AF_INET, peer, &ipv4_dest) != 1)
131 err = __connman_inet_rtnl_addattr_l(header,
140 err = __connman_inet_rtnl_addattr_l(header,
149 * Broadcast address must not be added for P2P / VPN as
150 * getifaddrs() cannot interpret destination address.
154 inet_pton(AF_INET, broadcast, &ipv4_bcast);
156 ipv4_bcast.s_addr = ipv4_addr.s_addr |
157 htonl(0xfffffffflu >> prefixlen);
159 err = __connman_inet_rtnl_addattr_l(header,
167 } else if (family == AF_INET6) {
168 if (inet_pton(AF_INET6, address, &ipv6_addr) != 1)
171 err = __connman_inet_rtnl_addattr_l(header,
180 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
184 memset(&nl_addr, 0, sizeof(nl_addr));
185 nl_addr.nl_family = AF_NETLINK;
187 if ((err = sendto(sk, request, header->nlmsg_len, 0,
188 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
199 #if defined TIZEN_EXT_WIFI_MESH
200 char *connman_inet_ifaddr(const char *name)
203 struct ether_addr eth;
207 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
211 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
213 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
223 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
224 snprintf(str, 13, "%02x%02x%02x%02x%02x%02x",
225 eth.ether_addr_octet[0],
226 eth.ether_addr_octet[1],
227 eth.ether_addr_octet[2],
228 eth.ether_addr_octet[3],
229 eth.ether_addr_octet[4],
230 eth.ether_addr_octet[5]);
235 char *connman_inet_ifname2addr(const char *name)
238 struct ether_addr eth;
242 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
246 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
248 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
258 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
259 snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
260 eth.ether_addr_octet[0],
261 eth.ether_addr_octet[1],
262 eth.ether_addr_octet[2],
263 eth.ether_addr_octet[3],
264 eth.ether_addr_octet[4],
265 eth.ether_addr_octet[5]);
271 static bool is_addr_unspec(int family, struct sockaddr *addr)
273 struct sockaddr_in *in4;
274 struct sockaddr_in6 *in6;
278 in4 = (struct sockaddr_in*) addr;
279 return in4->sin_addr.s_addr == INADDR_ANY;
281 in6 = (struct sockaddr_in6*) addr;
282 return IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr);
288 static bool is_addr_ll(int family, struct sockaddr *addr)
290 struct sockaddr_in *in4;
291 struct sockaddr_in6 *in6;
295 in4 = (struct sockaddr_in*) addr;
296 return (in4->sin_addr.s_addr & IN_CLASSB_NET) ==
297 ((in_addr_t) htonl(0xa9fe0000));
299 in6 = (struct sockaddr_in6*) addr;
300 return IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr);
306 bool __connman_inet_is_any_addr(const char *address, int family)
309 struct addrinfo hints;
310 struct addrinfo *result = NULL;
312 if (!address || !*address)
315 memset(&hints, 0, sizeof(struct addrinfo));
317 hints.ai_family = family;
319 if (getaddrinfo(address, NULL, &hints, &result))
323 ret = is_addr_unspec(result->ai_family, result->ai_addr);
324 freeaddrinfo(result);
331 int connman_inet_ifindex(const char *name)
339 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
343 memset(&ifr, 0, sizeof(ifr));
344 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
346 err = ioctl(sk, SIOCGIFINDEX, &ifr);
353 return ifr.ifr_ifindex;
356 char *connman_inet_ifname(int index)
364 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
368 memset(&ifr, 0, sizeof(ifr));
369 ifr.ifr_ifindex = index;
371 err = ioctl(sk, SIOCGIFNAME, &ifr);
378 return g_strdup(ifr.ifr_name);
381 int connman_inet_ifup(int index)
386 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
390 memset(&ifr, 0, sizeof(ifr));
391 ifr.ifr_ifindex = index;
393 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
398 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
403 if (ifr.ifr_flags & IFF_UP) {
408 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
410 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
423 int connman_inet_ifdown(int index)
425 struct ifreq ifr, addr_ifr;
426 struct sockaddr_in *addr;
429 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
433 memset(&ifr, 0, sizeof(ifr));
434 ifr.ifr_ifindex = index;
436 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
441 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
446 memset(&addr_ifr, 0, sizeof(addr_ifr));
447 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
448 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
449 addr->sin_family = AF_INET;
450 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
451 connman_warn("Could not clear IPv4 address index %d", index);
453 if (!(ifr.ifr_flags & IFF_UP)) {
458 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
460 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
471 #if defined TIZEN_EXT
472 void connman_inet_update_device_ident(struct connman_device *device)
475 enum connman_device_type type;
476 char *ident = NULL, *addr = NULL;
478 index = connman_device_get_index(device);
479 type = connman_device_get_type(device);
482 case CONNMAN_DEVICE_TYPE_UNKNOWN:
484 case CONNMAN_DEVICE_TYPE_ETHERNET:
485 case CONNMAN_DEVICE_TYPE_GADGET:
486 case CONNMAN_DEVICE_TYPE_WIFI:
487 addr = index2addr(index);
488 ident = index2ident(index, NULL);
490 case CONNMAN_DEVICE_TYPE_CELLULAR:
491 ident = index2ident(index, NULL);
493 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
494 case CONNMAN_DEVICE_TYPE_GPS:
495 case CONNMAN_DEVICE_TYPE_VENDOR:
500 connman_device_set_ident(device, ident);
505 connman_device_set_string(device, "Address", addr);
511 bool connman_inet_is_ifup(int index)
517 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
519 connman_warn("Failed to open socket");
523 memset(&ifr, 0, sizeof(ifr));
524 ifr.ifr_ifindex = index;
526 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
527 connman_warn("Failed to get interface name for interface %d", index);
531 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
532 connman_warn("Failed to get interface flags for index %d", index);
536 if (ifr.ifr_flags & IFF_UP)
546 struct in6_addr ifr6_addr;
547 __u32 ifr6_prefixlen;
548 unsigned int ifr6_ifindex;
551 int connman_inet_set_ipv6_address(int index,
552 struct connman_ipaddress *ipaddress)
555 unsigned char prefix_len;
559 if (!ipaddress->local)
562 prefix_len = ipaddress->prefixlen;
563 address = ipaddress->local;
564 is_p2p = ipaddress->is_p2p;
566 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
568 err = __connman_inet_modify_address(RTM_NEWADDR,
569 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
570 address, NULL, prefix_len, NULL, is_p2p);
572 connman_error("%s: %s", __func__, strerror(-err));
579 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
582 unsigned char prefix_len;
583 const char *address, *broadcast, *peer;
586 if (!ipaddress->local)
589 prefix_len = ipaddress->prefixlen;
590 address = ipaddress->local;
591 broadcast = ipaddress->broadcast;
592 peer = ipaddress->peer;
593 is_p2p = ipaddress->is_p2p;
595 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
597 err = __connman_inet_modify_address(RTM_NEWADDR,
598 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
599 address, peer, prefix_len, broadcast, is_p2p);
601 connman_error("%s: %s", __func__, strerror(-err));
608 int connman_inet_clear_ipv6_address(int index,
609 struct connman_ipaddress *ipaddress)
616 address = ipaddress->local;
617 prefix_len = ipaddress->prefixlen;
618 is_p2p = ipaddress->is_p2p;
620 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
625 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
626 address, NULL, prefix_len, NULL, is_p2p);
628 connman_error("%s: %s", __func__, strerror(-err));
635 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
638 unsigned char prefix_len;
639 const char *address, *broadcast, *peer;
642 prefix_len = ipaddress->prefixlen;
643 address = ipaddress->local;
644 broadcast = ipaddress->broadcast;
645 peer = ipaddress->peer;
646 is_p2p = ipaddress->is_p2p;
648 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
649 address, prefix_len, peer, broadcast);
654 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
655 address, peer, prefix_len, broadcast, is_p2p);
657 connman_error("%s: %s", __func__, strerror(-err));
664 int connman_inet_add_host_route(int index, const char *host,
667 return connman_inet_add_network_route(index, host, gateway, NULL);
670 int connman_inet_del_host_route(int index, const char *host)
672 return connman_inet_del_network_route(index, host);
675 int connman_inet_add_network_route(int index, const char *host,
681 struct sockaddr_in addr;
684 DBG("index %d host %s gateway %s netmask %s", index,
685 host, gateway, netmask);
687 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
693 memset(&ifr, 0, sizeof(ifr));
694 ifr.ifr_ifindex = index;
696 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
702 DBG("ifname %s", ifr.ifr_name);
704 memset(&rt, 0, sizeof(rt));
705 rt.rt_flags = RTF_UP;
708 * Set RTF_GATEWAY only when gateway is set and the gateway IP address
709 * is not IPv4 any address (0.0.0.0). If the given gateway IP address is
710 * any address adding of route will fail when RTF_GATEWAY set. Passing
711 * gateway as NULL or INADDR_ANY should have the same effect. Setting
712 * the gateway address later to the struct is not affected by this,
713 * since given IPv4 any address (0.0.0.0) equals the value set with
716 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET))
717 rt.rt_flags |= RTF_GATEWAY;
719 rt.rt_flags |= RTF_HOST;
721 memset(&addr, 0, sizeof(addr));
722 addr.sin_family = AF_INET;
723 addr.sin_addr.s_addr = inet_addr(host);
724 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
726 memset(&addr, 0, sizeof(addr));
727 addr.sin_family = AF_INET;
729 addr.sin_addr.s_addr = inet_addr(gateway);
731 addr.sin_addr.s_addr = INADDR_ANY;
732 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
734 memset(&addr, 0, sizeof(addr));
735 addr.sin_family = AF_INET;
736 addr.sin_addr.s_addr = INADDR_ANY;
738 addr.sin_addr.s_addr = inet_addr(netmask);
740 addr.sin_addr.s_addr = INADDR_ANY;
741 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
743 rt.rt_dev = ifr.ifr_name;
745 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
752 connman_error("Adding host route failed (%s)",
758 int connman_inet_del_network_route(int index, const char *host)
762 struct sockaddr_in addr;
765 DBG("index %d host %s", index, host);
767 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
773 memset(&ifr, 0, sizeof(ifr));
774 ifr.ifr_ifindex = index;
776 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
782 DBG("ifname %s", ifr.ifr_name);
784 memset(&rt, 0, sizeof(rt));
785 rt.rt_flags = RTF_UP | RTF_HOST;
787 memset(&addr, 0, sizeof(addr));
788 addr.sin_family = AF_INET;
789 addr.sin_addr.s_addr = inet_addr(host);
790 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
792 rt.rt_dev = ifr.ifr_name;
794 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
801 connman_error("Deleting host route failed (%s)",
807 int connman_inet_del_ipv6_network_route(int index, const char *host,
808 unsigned char prefix_len)
813 DBG("index %d host %s", index, host);
818 memset(&rt, 0, sizeof(rt));
820 rt.rtmsg_dst_len = prefix_len;
822 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) != 1) {
827 rt.rtmsg_flags = RTF_UP | RTF_HOST;
830 rt.rtmsg_ifindex = index;
832 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
838 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
845 connman_error("Del IPv6 host route error (%s)",
851 int connman_inet_del_ipv6_host_route(int index, const char *host)
853 return connman_inet_del_ipv6_network_route(index, host, 128);
856 int connman_inet_add_ipv6_network_route(int index, const char *host,
858 unsigned char prefix_len)
863 DBG("index %d host %s gateway %s", index, host, gateway);
868 memset(&rt, 0, sizeof(rt));
870 rt.rtmsg_dst_len = prefix_len;
872 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) != 1) {
877 rt.rtmsg_flags = RTF_UP | RTF_HOST;
880 * Set RTF_GATEWAY only when gateway is set, the gateway IP address is
881 * not IPv6 any address (e.g., ::) and the address is valid (conversion
882 * succeeds). If the given gateway IP address is any address then
883 * adding of route will fail when RTF_GATEWAY set. Passing gateway as
884 * NULL or IPv6 any address should have the same effect.
887 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET6) &&
888 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) == 1)
889 rt.rtmsg_flags |= RTF_GATEWAY;
892 rt.rtmsg_ifindex = index;
894 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
900 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
907 connman_error("Set IPv6 host route error (%s)",
913 int connman_inet_add_ipv6_host_route(int index, const char *host,
916 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
919 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
924 DBG("index %d gateway %s", index, gateway);
929 memset(&rt, 0, sizeof(rt));
931 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) != 1) {
936 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
938 rt.rtmsg_dst_len = 0;
939 rt.rtmsg_ifindex = index;
941 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
947 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
954 connman_error("Clear default IPv6 gateway error (%s)",
960 int connman_inet_set_gateway_interface(int index)
964 struct sockaddr_in addr;
967 DBG("index %d", index);
969 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
975 memset(&ifr, 0, sizeof(ifr));
976 ifr.ifr_ifindex = index;
978 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
984 DBG("ifname %s", ifr.ifr_name);
986 memset(&rt, 0, sizeof(rt));
987 rt.rt_flags = RTF_UP;
989 memset(&addr, 0, sizeof(addr));
990 addr.sin_family = AF_INET;
991 addr.sin_addr.s_addr = INADDR_ANY;
993 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
994 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
995 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
997 rt.rt_dev = ifr.ifr_name;
999 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
1006 connman_error("Setting default interface route failed (%s)",
1012 int connman_inet_set_ipv6_gateway_interface(int index)
1016 struct sockaddr_in6 addr;
1017 const struct in6_addr any = IN6ADDR_ANY_INIT;
1020 DBG("index %d", index);
1022 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1028 memset(&ifr, 0, sizeof(ifr));
1029 ifr.ifr_ifindex = index;
1031 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1037 DBG("ifname %s", ifr.ifr_name);
1039 memset(&rt, 0, sizeof(rt));
1040 rt.rt_flags = RTF_UP;
1042 memset(&addr, 0, sizeof(addr));
1043 addr.sin6_family = AF_INET6;
1044 addr.sin6_addr = any;
1046 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1047 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1048 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1050 rt.rt_dev = ifr.ifr_name;
1052 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
1059 connman_error("Setting default interface route failed (%s)",
1065 int connman_inet_clear_gateway_address(int index, const char *gateway)
1069 struct sockaddr_in addr;
1072 DBG("index %d gateway %s", index, gateway);
1074 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1080 memset(&ifr, 0, sizeof(ifr));
1081 ifr.ifr_ifindex = index;
1083 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1089 DBG("ifname %s", ifr.ifr_name);
1091 memset(&rt, 0, sizeof(rt));
1092 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1094 memset(&addr, 0, sizeof(addr));
1095 addr.sin_family = AF_INET;
1096 addr.sin_addr.s_addr = INADDR_ANY;
1097 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1099 memset(&addr, 0, sizeof(addr));
1100 addr.sin_family = AF_INET;
1101 addr.sin_addr.s_addr = inet_addr(gateway);
1102 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1104 memset(&addr, 0, sizeof(addr));
1105 addr.sin_family = AF_INET;
1106 addr.sin_addr.s_addr = INADDR_ANY;
1107 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1109 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1116 connman_error("Removing default gateway route failed (%s)",
1122 int connman_inet_clear_gateway_interface(int index)
1126 struct sockaddr_in addr;
1129 DBG("index %d", index);
1131 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1137 memset(&ifr, 0, sizeof(ifr));
1138 ifr.ifr_ifindex = index;
1140 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1146 DBG("ifname %s", ifr.ifr_name);
1148 memset(&rt, 0, sizeof(rt));
1149 rt.rt_flags = RTF_UP;
1151 memset(&addr, 0, sizeof(addr));
1152 addr.sin_family = AF_INET;
1153 addr.sin_addr.s_addr = INADDR_ANY;
1155 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1156 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1157 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1159 rt.rt_dev = ifr.ifr_name;
1161 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1168 connman_error("Removing default interface route failed (%s)",
1174 int connman_inet_clear_ipv6_gateway_interface(int index)
1178 struct sockaddr_in6 addr;
1179 const struct in6_addr any = IN6ADDR_ANY_INIT;
1182 DBG("index %d", index);
1184 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1190 memset(&ifr, 0, sizeof(ifr));
1191 ifr.ifr_ifindex = index;
1193 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1199 DBG("ifname %s", ifr.ifr_name);
1201 memset(&rt, 0, sizeof(rt));
1202 rt.rt_flags = RTF_UP;
1204 memset(&addr, 0, sizeof(addr));
1205 addr.sin6_family = AF_INET6;
1206 addr.sin6_addr = any;
1208 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1209 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1210 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1212 rt.rt_dev = ifr.ifr_name;
1214 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1221 connman_error("Removing default interface route failed (%s)",
1227 #define ADDR_TYPE_MAX 4
1229 struct interface_address {
1233 /* Applies only to ADDR_TYPE_IPADDR in ipaddrs */
1235 /* Real types must be in_addr for AF_INET and in6_addr for AF_INET6 */
1236 void *ipaddrs[ADDR_TYPE_MAX];
1240 ADDR_TYPE_IPADDR = 0,
1246 static int get_interface_addresses(struct interface_address *if_addr)
1248 struct ifaddrs *ifaddr;
1249 struct ifaddrs *ifa;
1250 struct sockaddr *addrs[ADDR_TYPE_MAX] = { 0 };
1251 struct sockaddr_in *addr_in;
1252 struct sockaddr_in6 *addr_in6;
1253 char name[IF_NAMESIZE] = { 0 };
1261 if (!if_indextoname(if_addr->index, name))
1264 DBG("index %d interface %s", if_addr->index, name);
1266 if (getifaddrs(&ifaddr) < 0) {
1267 connman_error("Cannot get addresses err %d/%s", errno,
1272 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1276 if (g_strcmp0(ifa->ifa_name, name) ||
1277 ifa->ifa_addr->sa_family !=
1282 if (if_addr->ipaddrs[ADDR_TYPE_IPADDR]) {
1283 if (!if_addr->allow_unspec && is_addr_unspec(
1288 if (if_addr->require_ll && !is_addr_ll(if_addr->family,
1292 addrs[ADDR_TYPE_IPADDR] = ifa->ifa_addr;
1295 if (if_addr->ipaddrs[ADDR_TYPE_NETMASK]) {
1296 if (!if_addr->allow_unspec && is_addr_unspec(
1301 addrs[ADDR_TYPE_NETMASK] = ifa->ifa_netmask;
1304 if (if_addr->ipaddrs[ADDR_TYPE_BRDADDR] &&
1305 (ifa->ifa_flags & IFF_BROADCAST)) {
1306 if (!if_addr->allow_unspec && is_addr_unspec(
1308 ifa->ifa_ifu.ifu_broadaddr))
1311 addrs[ADDR_TYPE_BRDADDR] = ifa->ifa_ifu.ifu_broadaddr;
1314 if (if_addr->ipaddrs[ADDR_TYPE_DSTADDR] &&
1315 (ifa->ifa_flags & IFF_POINTOPOINT)) {
1316 if (!if_addr->allow_unspec && is_addr_unspec(
1318 ifa->ifa_ifu.ifu_dstaddr))
1321 addrs[ADDR_TYPE_DSTADDR] = ifa->ifa_ifu.ifu_dstaddr;
1332 for (i = 0; i < ADDR_TYPE_MAX; i++) {
1336 switch (if_addr->family) {
1338 len = sizeof(struct in_addr);
1339 addr_in = (struct sockaddr_in*) addrs[i];
1340 memcpy(if_addr->ipaddrs[i], &addr_in->sin_addr, len);
1343 len = sizeof(struct in6_addr);
1344 addr_in6 = (struct sockaddr_in6*) addrs[i];
1345 memcpy(if_addr->ipaddrs[i], &addr_in6->sin6_addr, len);
1354 freeifaddrs(ifaddr);
1358 bool connman_inet_compare_subnet(int index, const char *host)
1360 struct interface_address if_addr = { 0 };
1361 struct in_addr iaddr = { 0 };
1362 struct in_addr imask = { 0 };
1363 struct in_addr haddr = { 0 };
1365 DBG("host %s", host);
1370 if (inet_pton(AF_INET, host, &haddr) != 1)
1373 if_addr.index = index;
1374 if_addr.family = AF_INET;
1375 if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &iaddr;
1376 if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &imask;
1378 if (get_interface_addresses(&if_addr))
1381 return (iaddr.s_addr & imask.s_addr) == (haddr.s_addr & imask.s_addr);
1384 static bool mem_mask_equal(const void *a, const void *b,
1385 const void *mask, size_t n)
1387 const unsigned char *addr1 = a;
1388 const unsigned char *addr2 = b;
1389 const unsigned char *bitmask = mask;
1392 for (i = 0; i < n; i++) {
1393 if ((addr1[i] ^ addr2[i]) & bitmask[i])
1400 bool connman_inet_compare_ipv6_subnet(int index, const char *host)
1402 struct interface_address addr = { 0 };
1403 struct in6_addr iaddr = { 0 };
1404 struct in6_addr imask = { 0 };
1405 struct in6_addr haddr = { 0 };
1407 if (inet_pton(AF_INET6, host, &haddr) != 1)
1411 addr.family = AF_INET6;
1412 addr.ipaddrs[ADDR_TYPE_IPADDR] = &iaddr;
1413 addr.ipaddrs[ADDR_TYPE_NETMASK] = &imask;
1415 if (get_interface_addresses(&addr))
1418 return mem_mask_equal(&iaddr, &haddr, &imask, sizeof(haddr));
1421 int connman_inet_remove_from_bridge(int index, const char *bridge)
1429 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1435 memset(&ifr, 0, sizeof(ifr));
1436 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1437 ifr.ifr_ifindex = index;
1439 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1446 connman_error("Remove interface from bridge error %s",
1452 int connman_inet_add_to_bridge(int index, const char *bridge)
1460 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1466 memset(&ifr, 0, sizeof(ifr));
1467 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1468 ifr.ifr_ifindex = index;
1470 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1477 connman_error("Add interface to bridge error %s",
1483 int connman_inet_set_mtu(int index, int mtu)
1488 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1492 memset(&ifr, 0, sizeof(ifr));
1493 ifr.ifr_ifindex = index;
1495 err = ioctl(sk, SIOCGIFNAME, &ifr);
1498 err = ioctl(sk, SIOCSIFMTU, &ifr);
1505 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1515 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1519 index = if_nametoindex(tunnel);
1521 err = connman_inet_set_mtu(index, mtu);
1525 memset(&ifr, 0, sizeof(ifr));
1526 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1527 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1534 if ((ifr.ifr_flags ^ flags) & mask) {
1535 ifr.ifr_flags &= ~mask;
1536 ifr.ifr_flags |= mask & flags;
1537 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1539 connman_error("SIOCSIFFLAGS failed: %s",
1548 int connman_inet_create_tunnel(char **iface)
1553 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1556 connman_error("Failed to open /dev/net/tun: %s",
1561 memset(&ifr, 0, sizeof(ifr));
1562 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1564 for (i = 0; i < 256; i++) {
1565 sprintf(ifr.ifr_name, "tun%d", i);
1567 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1572 connman_error("Failed to find available tun device");
1577 *iface = g_strdup(ifr.ifr_name);
1583 * This callback struct is used when sending router and neighbor
1584 * solicitation and advertisement messages.
1587 GIOChannel *channel;
1589 struct sockaddr_in6 addr;
1595 #define CMSG_BUF_LEN 512
1596 #define IN6ADDR_ALL_NODES_MC_INIT \
1597 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1598 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1599 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1601 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1602 static const struct in6_addr in6addr_all_routers_mc =
1603 IN6ADDR_ALL_ROUTERS_MC_INIT;
1605 static void xs_cleanup(struct xs_cb_data *data)
1607 if (data->channel) {
1608 g_io_channel_shutdown(data->channel, TRUE, NULL);
1609 g_io_channel_unref(data->channel);
1610 data->channel = NULL;
1613 if (data->timeout > 0)
1614 g_source_remove(data->timeout);
1616 if (data->watch_id > 0)
1617 g_source_remove(data->watch_id);
1622 static gboolean rs_timeout_cb(gpointer user_data)
1624 struct xs_cb_data *data = user_data;
1626 DBG("user data %p", user_data);
1631 if (data->callback) {
1632 __connman_inet_rs_cb_t cb = data->callback;
1633 cb(NULL, 0, data->user_data);
1641 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1645 unsigned char chdr[CMSG_BUF_LEN];
1646 unsigned char buf[1540];
1647 struct nd_router_advert *hdr;
1648 struct sockaddr_in6 saddr;
1650 __connman_inet_rs_cb_t cb = data->callback;
1654 iov.iov_len = sizeof(buf);
1657 mhdr.msg_name = (void *)&saddr;
1658 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1660 mhdr.msg_iov = &iov;
1661 mhdr.msg_iovlen = 1;
1662 mhdr.msg_control = (void *)chdr;
1663 mhdr.msg_controllen = CMSG_BUF_LEN;
1665 len = recvmsg(fd, &mhdr, 0);
1667 cb(NULL, 0, data->user_data);
1671 #if defined TIZEN_EXT
1672 /* Set Received Source Address from router as IPv6 Gateway Address */
1673 char src_addr[INET6_ADDRSTRLEN];
1674 if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
1678 DBG("Received Source Address %s from router", src_addr);
1680 /* icmpv6_recv() function can be called in two scenarios :
1681 * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
1682 * 2. When __connman_inet_ipv6_send_rs() is called from
1683 * __connman_6to4_probe()
1684 * In the second case it is not required to set DHCPv6 Gateway Address
1685 * as DHCPv6 was not started and network structure was not passed as
1686 * user_data. If it is tried to add Source Address as Gateway Address
1687 * then it will lead to crash because of user_data being ip_address
1688 * instead of network structure. So Adding Gateway Address in case 1st
1691 char *address = data->user_data;
1693 unsigned char buffer[sizeof(struct in6_addr)] = {0, };
1694 /* Checking if user_data is an ip_address */
1695 err = inet_pton(AF_INET, address, buffer);
1696 /* Setting Received Source Address from
1697 * router as Gateway Address */
1699 __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
1701 hdr = (struct nd_router_advert *)buf;
1702 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1703 sizeof(struct nd_router_advert));
1704 if (hdr->nd_ra_code != 0)
1707 cb(hdr, len, data->user_data);
1712 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1715 struct xs_cb_data *xs_data = data;
1719 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1722 fd = g_io_channel_unix_get_fd(chan);
1723 ret = icmpv6_recv(fd, xs_data);
1728 xs_cleanup(xs_data);
1732 /* Adapted from RFC 1071 "C" Implementation Example */
1733 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1734 const void *extra_data, socklen_t extra_datalen)
1736 register unsigned long sum = 0;
1741 /* caller must make sure datalen is even */
1743 addr = (uint16_t *)phdr;
1744 for (i = 0; i < 20; i++)
1748 addr = (uint16_t *)data;
1756 count = extra_datalen;
1757 addr = (uint16_t *)extra_data;
1766 sum = (sum & 0xffff) + (sum >> 16);
1768 return (uint16_t)~sum;
1771 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1772 const struct in6_addr *source,
1773 unsigned char *buf, size_t len, uint16_t lifetime)
1776 struct in6_addr src;
1777 struct in6_addr dst;
1779 uint8_t reserved[3];
1786 struct icmp6_hdr icmp;
1787 struct nd_neighbor_solicit ns;
1788 struct nd_router_solicit rs;
1789 struct nd_router_advert ra;
1794 struct cmsghdr *cmsg;
1795 struct in6_pktinfo *pinfo;
1796 struct sockaddr_in6 dst, src;
1797 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1798 struct iovec iov[2];
1799 int fd, datalen, ret, iovlen = 1;
1800 #if defined TIZEN_EXT
1806 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1810 memset(&frame, 0, sizeof(frame));
1811 memset(&dst, 0, sizeof(dst));
1813 if (type == ND_ROUTER_SOLICIT)
1814 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1815 else if (type == ND_ROUTER_ADVERT) {
1816 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1817 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1818 } else if (type == ND_NEIGHBOR_SOLICIT) {
1819 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1820 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1826 dst.sin6_addr = *dest;
1829 src.sin6_addr = *source;
1831 src.sin6_addr = in6addr_any;
1833 /* Fill in the IPv6 header */
1834 frame.ip.ip6_vfc = 0x60;
1835 frame.ip.ip6_plen = htons(datalen + len);
1836 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1837 frame.ip.ip6_hlim = 255;
1838 frame.ip.ip6_dst = dst.sin6_addr;
1839 frame.ip.ip6_src = src.sin6_addr;
1840 /* all other fields are already set to zero */
1842 /* Prepare pseudo header for csum */
1843 memset(&phdr, 0, sizeof(phdr));
1844 phdr.dst = dst.sin6_addr;
1845 phdr.src = src.sin6_addr;
1846 phdr.plen = htonl(datalen + len);
1847 phdr.nxt = IPPROTO_ICMPV6;
1849 /* Fill in remaining ICMP header fields */
1850 frame.i.icmp.icmp6_type = type;
1851 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1853 iov[0].iov_base = &frame;
1854 iov[0].iov_len = sizeof(frame.ip) + datalen;
1857 iov[1].iov_base = buf;
1858 iov[1].iov_len = len;
1862 dst.sin6_family = AF_INET6;
1863 msgh.msg_name = &dst;
1864 msgh.msg_namelen = sizeof(dst);
1866 msgh.msg_iovlen = iovlen;
1869 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1870 cmsg = (struct cmsghdr *)cbuf;
1871 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1872 pinfo->ipi6_ifindex = oif;
1874 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1875 cmsg->cmsg_level = IPPROTO_IPV6;
1876 cmsg->cmsg_type = IPV6_PKTINFO;
1877 msgh.msg_control = cmsg;
1878 msgh.msg_controllen = cmsg->cmsg_len;
1880 ret = sendmsg(fd, &msgh, 0);
1881 #if defined TIZEN_EXT
1882 DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
1889 static inline void ipv6_addr_set(struct in6_addr *addr,
1890 uint32_t w1, uint32_t w2,
1891 uint32_t w3, uint32_t w4)
1893 addr->s6_addr32[0] = w1;
1894 addr->s6_addr32[1] = w2;
1895 addr->s6_addr32[2] = w3;
1896 addr->s6_addr32[3] = w4;
1899 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1900 struct in6_addr *solicited)
1902 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1903 htonl(0xFF000000) | addr->s6_addr32[3]);
1906 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1909 unsigned int val = 0;
1910 struct ipv6_mreq mreq;
1913 memset(&mreq, 0, sizeof(mreq));
1914 mreq.ipv6mr_interface = ifindex;
1915 mreq.ipv6mr_multiaddr = *mc_addr;
1917 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1921 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1926 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1929 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1936 int __connman_inet_ipv6_send_rs(int index, int timeout,
1937 __connman_inet_rs_cb_t callback, void *user_data)
1939 struct xs_cb_data *data;
1940 struct icmp6_filter filter;
1941 struct in6_addr solicit;
1942 struct in6_addr dst = in6addr_all_routers_mc;
1948 data = g_try_malloc0(sizeof(struct xs_cb_data));
1952 data->callback = callback;
1953 data->user_data = user_data;
1954 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1956 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1962 ICMP6_FILTER_SETBLOCKALL(&filter);
1963 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1965 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1966 sizeof(struct icmp6_filter));
1968 ipv6_addr_solict_mult(&dst, &solicit);
1969 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1970 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1972 data->channel = g_io_channel_unix_new(sk);
1973 g_io_channel_set_close_on_unref(data->channel, TRUE);
1975 g_io_channel_set_encoding(data->channel, NULL, NULL);
1976 g_io_channel_set_buffered(data->channel, FALSE);
1978 data->watch_id = g_io_add_watch(data->channel,
1979 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1980 icmpv6_event, data);
1982 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1987 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1988 struct in6_addr *advert)
1990 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1991 htonl(0xFF000000) | addr->s6_addr32[3]);
1994 #define MSG_SIZE_SEND 1452
1996 static int inc_len(int len, int inc)
1998 if (len > MSG_SIZE_SEND)
2005 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
2006 GSList *prefixes, int router_lifetime)
2009 struct in6_addr src, *source;
2010 struct in6_addr dst = in6addr_all_nodes_mc;
2011 GDHCPIAPrefix *prefix;
2012 unsigned char buf[MSG_SIZE_SEND];
2013 char addr_str[INET6_ADDRSTRLEN];
2020 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2025 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
2030 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
2031 prefixes, inet_ntop(AF_INET6, source, addr_str,
2035 memset(buf, 0, MSG_SIZE_SEND);
2038 for (list = prefixes; list; list = list->next) {
2039 struct nd_opt_prefix_info *pinfo;
2041 prefix = list->data;
2042 pinfo = (struct nd_opt_prefix_info *)(buf + len);
2044 len = inc_len(len, sizeof(*pinfo));
2050 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
2051 pinfo->nd_opt_pi_len = 4;
2052 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
2053 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
2054 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
2055 if (router_lifetime > 0) {
2056 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
2057 pinfo->nd_opt_pi_preferred_time =
2058 htonl(prefix->preferred);
2060 pinfo->nd_opt_pi_reserved2 = 0;
2062 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
2063 sizeof(struct in6_addr));
2065 DBG("[%d] index %d prefix %s/%d", count, index,
2066 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
2067 INET6_ADDRSTRLEN), prefix->prefixlen);
2073 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
2074 buf, len, router_lifetime);
2076 DBG("cannot send RA %d/%s", err, strerror(-err));
2084 void __connman_inet_ipv6_stop_recv_rs(void *context)
2089 xs_cleanup(context);
2092 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
2096 unsigned char chdr[CMSG_BUF_LEN];
2097 unsigned char buf[1540];
2098 struct nd_router_solicit *hdr;
2099 struct sockaddr_in6 saddr;
2101 __connman_inet_recv_rs_cb_t cb = data->callback;
2105 iov.iov_len = sizeof(buf);
2108 mhdr.msg_name = (void *)&saddr;
2109 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
2111 mhdr.msg_iov = &iov;
2112 mhdr.msg_iovlen = 1;
2113 mhdr.msg_control = (void *)chdr;
2114 mhdr.msg_controllen = CMSG_BUF_LEN;
2116 len = recvmsg(fd, &mhdr, 0);
2118 cb(NULL, 0, data->user_data);
2122 hdr = (struct nd_router_solicit *)buf;
2123 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
2124 sizeof(struct nd_router_solicit));
2125 if (hdr->nd_rs_code != 0)
2128 cb(hdr, len, data->user_data);
2132 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
2136 struct xs_cb_data *xs_data = data;
2140 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2143 fd = g_io_channel_unix_get_fd(chan);
2144 ret = icmpv6_rs_recv(fd, xs_data);
2149 xs_data->watch_id = 0;
2153 int __connman_inet_ipv6_start_recv_rs(int index,
2154 __connman_inet_recv_rs_cb_t callback,
2158 struct xs_cb_data *data;
2159 struct icmp6_filter filter;
2160 char addr_str[INET6_ADDRSTRLEN];
2163 data = g_try_malloc0(sizeof(struct xs_cb_data));
2167 data->callback = callback;
2168 data->user_data = user_data;
2170 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2178 ICMP6_FILTER_SETBLOCKALL(&filter);
2179 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
2181 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2182 sizeof(struct icmp6_filter));
2184 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
2186 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
2187 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
2188 err, strerror(-err));
2190 data->channel = g_io_channel_unix_new(sk);
2191 g_io_channel_set_close_on_unref(data->channel, TRUE);
2193 g_io_channel_set_encoding(data->channel, NULL, NULL);
2194 g_io_channel_set_buffered(data->channel, FALSE);
2196 data->watch_id = g_io_add_watch(data->channel,
2197 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2198 icmpv6_rs_event, data);
2205 static gboolean ns_timeout_cb(gpointer user_data)
2207 struct xs_cb_data *data = user_data;
2209 DBG("user data %p", user_data);
2214 if (data->callback) {
2215 __connman_inet_ns_cb_t cb = data->callback;
2216 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2224 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
2228 unsigned char chdr[CMSG_BUF_LEN];
2229 unsigned char buf[1540];
2230 struct nd_neighbor_advert *hdr;
2231 struct sockaddr_in6 saddr;
2233 __connman_inet_ns_cb_t cb = data->callback;
2237 iov.iov_len = sizeof(buf);
2240 mhdr.msg_name = (void *)&saddr;
2241 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
2243 mhdr.msg_iov = &iov;
2244 mhdr.msg_iovlen = 1;
2245 mhdr.msg_control = (void *)chdr;
2246 mhdr.msg_controllen = CMSG_BUF_LEN;
2248 len = recvmsg(fd, &mhdr, 0);
2250 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2254 hdr = (struct nd_neighbor_advert *)buf;
2255 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
2256 sizeof(struct nd_neighbor_advert));
2257 if (hdr->nd_na_code != 0)
2261 * We can receive any neighbor advertisement so we need to check if the
2262 * packet was meant for us and ignore the packet otherwise.
2264 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
2265 sizeof(struct in6_addr)))
2268 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
2273 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
2277 struct xs_cb_data *xs_data = data;
2281 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2284 fd = g_io_channel_unix_get_fd(chan);
2285 ret = icmpv6_nd_recv(fd, xs_data);
2290 xs_cleanup(xs_data);
2294 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
2295 struct in6_addr *addr,
2296 __connman_inet_ns_cb_t callback,
2299 struct xs_cb_data *data;
2300 struct icmp6_filter filter;
2301 struct in6_addr solicit;
2302 int sk, err, val = 1;
2304 if (timeout_ms <= 0)
2307 data = g_try_malloc0(sizeof(struct xs_cb_data));
2311 data->callback = callback;
2312 data->user_data = user_data;
2313 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
2318 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
2320 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2326 ICMP6_FILTER_SETBLOCKALL(&filter);
2327 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
2329 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2330 sizeof(struct icmp6_filter));
2332 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2333 &val, sizeof(val)) < 0) {
2335 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2341 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2342 &val, sizeof(val)) < 0) {
2344 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2351 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2353 ipv6_addr_solict_mult(addr, &solicit);
2354 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2355 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2357 data->channel = g_io_channel_unix_new(sk);
2358 g_io_channel_set_close_on_unref(data->channel, TRUE);
2360 g_io_channel_set_encoding(data->channel, NULL, NULL);
2361 g_io_channel_set_buffered(data->channel, FALSE);
2363 data->watch_id = g_io_add_watch(data->channel,
2364 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2365 icmpv6_nd_event, data);
2367 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2368 (unsigned char *)addr, 0, 0);
2370 DBG("Cannot send NS %d/%s", err, strerror(-err));
2377 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2378 unsigned int length)
2380 GSList *prefixes = NULL;
2384 if (length <= sizeof(struct nd_router_advert))
2387 len = length - sizeof(struct nd_router_advert);
2388 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2391 struct nd_opt_prefix_info *pinfo;
2392 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2399 optlen = pos[1] << 3;
2400 if (optlen == 0 || optlen > len)
2404 case ND_OPT_PREFIX_INFORMATION:
2405 pinfo = (struct nd_opt_prefix_info *)pos;
2406 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2407 prefix_str, INET6_ADDRSTRLEN);
2411 str = g_strdup_printf("%s/%d", prefix,
2412 pinfo->nd_opt_pi_prefix_len);
2413 prefixes = g_slist_prepend(prefixes, str);
2415 DBG("prefix %s", str);
2427 int connman_inet_get_dest_addr(int index, char **dest)
2429 struct interface_address if_addr = { 0 };
2430 struct in_addr dstaddr = { 0 };
2431 char buf[INET_ADDRSTRLEN] = { 0 };
2437 if_addr.index = index;
2438 if_addr.family = AF_INET;
2439 if_addr.allow_unspec = true;
2440 if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dstaddr;
2442 err = get_interface_addresses(&if_addr);
2446 if (inet_ntop(AF_INET, &dstaddr, buf, INET_ADDRSTRLEN))
2447 *dest = g_strdup(buf);
2449 DBG("destination %s", *dest);
2451 return *dest && **dest ? 0 : -ENOENT;
2454 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2456 struct interface_address if_addr = { 0 };
2457 struct in_addr dstaddr = { 0 };
2458 char buf[INET6_ADDRSTRLEN] = { 0 };
2464 if_addr.index = index;
2465 if_addr.family = AF_INET6;
2466 if_addr.allow_unspec = true;
2467 if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dstaddr;
2469 err = get_interface_addresses(&if_addr);
2473 if (inet_ntop(AF_INET6, &dstaddr, buf, INET6_ADDRSTRLEN))
2474 *dest = g_strdup(buf);
2476 DBG("destination %s", *dest);
2478 return *dest && **dest ? 0 : -ENOENT;
2481 /* destination is optional */
2482 int connman_inet_get_route_addresses(int index, char **network, char **netmask,
2485 struct interface_address if_addr = { 0 };
2486 struct in_addr addr = { 0 };
2487 struct in_addr mask = { 0 };
2488 struct in_addr dest = { 0 };
2489 struct in_addr nw_addr = { 0 };
2490 char buf[INET_ADDRSTRLEN] = { 0 };
2493 if (!network || !netmask)
2496 if_addr.index = index;
2497 if_addr.family = AF_INET;
2498 if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &addr;
2499 if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &mask;
2500 if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dest;
2502 err = get_interface_addresses(&if_addr);
2506 nw_addr.s_addr = (addr.s_addr & mask.s_addr);
2508 if (inet_ntop(AF_INET, &nw_addr, buf, INET_ADDRSTRLEN))
2509 *network = g_strdup(buf);
2511 memset(&buf, 0, INET_ADDRSTRLEN);
2513 if (inet_ntop(AF_INET, &mask, buf, INET_ADDRSTRLEN))
2514 *netmask = g_strdup(buf);
2517 memset(&buf, 0, INET_ADDRSTRLEN);
2519 if (inet_ntop(AF_INET, &dest, buf, INET_ADDRSTRLEN))
2520 *destination = g_strdup(buf);
2523 DBG("network %s netmask %s destination %s", *network, *netmask,
2524 destination ? *destination : NULL);
2526 return *network && **network && *netmask && **netmask ? 0 : -ENOENT;
2529 int connman_inet_ipv6_get_route_addresses(int index, char **network,
2530 char **netmask, char **destination)
2532 struct interface_address if_addr = { 0 };
2533 struct in6_addr addr = { 0 };
2534 struct in6_addr mask = { 0 };
2535 struct in6_addr dest = { 0 };
2536 struct in6_addr nw_addr = { 0 };
2537 char buf[INET6_ADDRSTRLEN] = { 0 };
2543 if_addr.index = index;
2544 if_addr.family = AF_INET6;
2545 if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &addr;
2546 if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &mask;
2547 if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dest;
2549 err = get_interface_addresses(&if_addr);
2553 ipv6_addr_set(&nw_addr, addr.s6_addr32[0] & mask.s6_addr32[0],
2554 addr.s6_addr32[1] & mask.s6_addr32[1],
2555 addr.s6_addr32[2] & mask.s6_addr32[2],
2556 addr.s6_addr32[3] & mask.s6_addr32[3]);
2558 if (inet_ntop(AF_INET6, &nw_addr, buf, INET6_ADDRSTRLEN))
2559 *network = g_strdup(buf);
2561 memset(&buf, 0, INET6_ADDRSTRLEN);
2563 if (inet_ntop(AF_INET6, &mask, buf, INET6_ADDRSTRLEN))
2564 *netmask = g_strdup(buf);
2567 memset(&buf, 0, INET6_ADDRSTRLEN);
2569 if (inet_ntop(AF_INET6, &dest, buf, INET6_ADDRSTRLEN))
2570 *destination = g_strdup(buf);
2573 DBG("network %s netmask %s destination %s", *network, *netmask,
2574 destination ? *destination : NULL);
2576 return *network && **network && *netmask && **netmask ? 0 : -ENOENT;
2579 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2582 int rcvbuf = 1024 * 4;
2584 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2586 connman_error("Can not open netlink socket: %s",
2591 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2592 sizeof(sndbuf)) < 0) {
2593 connman_error("SO_SNDBUF: %s", strerror(errno));
2597 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2598 sizeof(rcvbuf)) < 0) {
2599 connman_error("SO_RCVBUF: %s", strerror(errno));
2603 memset(&rth->local, 0, sizeof(rth->local));
2604 rth->local.nl_family = AF_NETLINK;
2605 rth->local.nl_groups = 0;
2607 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2608 sizeof(rth->local)) < 0) {
2609 connman_error("Can not bind netlink socket: %s",
2614 rth->seq = time(NULL);
2616 DBG("fd %d", rth->fd);
2621 struct inet_rtnl_cb_data {
2622 GIOChannel *channel;
2623 __connman_inet_rtnl_cb_t callback;
2626 struct __connman_inet_rtnl_handle *rtnl;
2630 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2632 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2634 if (data->channel) {
2635 g_io_channel_shutdown(data->channel, TRUE, NULL);
2636 g_io_channel_unref(data->channel);
2637 data->channel = NULL;
2640 DBG("data %p", data);
2642 if (data->rtnl_timeout > 0)
2643 g_source_remove(data->rtnl_timeout);
2645 if (data->watch_id > 0)
2646 g_source_remove(data->watch_id);
2649 __connman_inet_rtnl_close(rth);
2656 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2658 struct inet_rtnl_cb_data *data = user_data;
2660 DBG("user data %p", user_data);
2666 data->callback(NULL, data->user_data);
2668 data->rtnl_timeout = 0;
2669 inet_rtnl_cleanup(data);
2673 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2675 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2676 struct nlmsghdr *h = NULL;
2677 struct sockaddr_nl nladdr;
2678 socklen_t addr_len = sizeof(nladdr);
2679 unsigned char buf[4096];
2684 memset(buf, 0, sizeof(buf));
2685 memset(&nladdr, 0, sizeof(nladdr));
2687 fd = g_io_channel_unix_get_fd(chan);
2689 status = recvfrom(fd, buf, sizeof(buf), 0,
2690 (struct sockaddr *) &nladdr, &addr_len);
2692 if (errno == EINTR || errno == EAGAIN)
2701 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2702 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2709 struct nlmsgerr *err;
2713 if (!NLMSG_OK(h, len))
2716 if (h->nlmsg_seq != rth->seq) {
2718 DBG("skip %d/%d len %d", rth->seq,
2719 h->nlmsg_seq, h->nlmsg_len);
2721 len -= h->nlmsg_len;
2722 ptr += h->nlmsg_len;
2726 switch (h->nlmsg_type) {
2732 err = (struct nlmsgerr *)NLMSG_DATA(h);
2733 connman_error("RTNETLINK answers %s (%d)",
2734 strerror(-err->error), -err->error);
2741 if (h->nlmsg_seq == rth->seq) {
2742 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2744 rtnl_data->callback(h, rtnl_data->user_data);
2746 inet_rtnl_cleanup(rtnl_data);
2752 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2756 struct inet_rtnl_cb_data *rtnl_data = user_data;
2760 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2763 ret = inet_rtnl_recv(chan, rtnl_data);
2768 rtnl_data->callback(NULL, rtnl_data->user_data);
2769 inet_rtnl_cleanup(rtnl_data);
2773 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2774 struct nlmsghdr *n, int timeout,
2775 __connman_inet_rtnl_cb_t callback, void *user_data)
2777 struct sockaddr_nl nladdr;
2778 struct inet_rtnl_cb_data *data;
2781 memset(&nladdr, 0, sizeof(nladdr));
2782 nladdr.nl_family = AF_NETLINK;
2784 n->nlmsg_seq = ++rtnl->seq;
2787 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2791 data->callback = callback;
2792 data->user_data = user_data;
2794 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2795 inet_rtnl_timeout_cb, data);
2797 data->channel = g_io_channel_unix_new(rtnl->fd);
2799 g_io_channel_set_encoding(data->channel, NULL, NULL);
2800 g_io_channel_set_buffered(data->channel, FALSE);
2802 data->watch_id = g_io_add_watch(data->channel,
2803 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2804 inet_rtnl_event, data);
2806 n->nlmsg_flags |= NLM_F_ACK;
2808 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2809 (struct sockaddr *) &nladdr, sizeof(nladdr));
2810 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2812 connman_error("Can not talk to rtnetlink err %d %s",
2813 -errno, strerror(errno));
2817 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2818 connman_error("Sent %d bytes, msg truncated", err);
2825 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2827 DBG("handle %p", rth);
2835 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2838 int len = RTA_LENGTH(4);
2841 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2842 DBG("Error! max allowed bound %zd exceeded", maxlen);
2845 rta = NLMSG_TAIL(n);
2846 rta->rta_type = type;
2848 memcpy(RTA_DATA(rta), &data, 4);
2849 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2854 static int parse_rtattr(struct rtattr *tb[], int max,
2855 struct rtattr *rta, int len)
2857 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2858 while (RTA_OK(rta, len)) {
2859 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2860 tb[rta->rta_type] = rta;
2861 rta = RTA_NEXT(rta, len);
2864 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2869 struct get_route_cb_data {
2870 connman_inet_addr_cb_t callback;
2874 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2876 struct get_route_cb_data *data = user_data;
2877 struct rtattr *tb[RTA_MAX+1];
2878 struct rtmsg *r = NLMSG_DATA(answer);
2879 int len, index = -1;
2881 const char *addr = NULL;
2883 DBG("answer %p data %p", answer, user_data);
2888 len = answer->nlmsg_len;
2890 if (answer->nlmsg_type != RTM_NEWROUTE &&
2891 answer->nlmsg_type != RTM_DELROUTE) {
2892 connman_error("Not a route: %08x %08x %08x",
2893 answer->nlmsg_len, answer->nlmsg_type,
2894 answer->nlmsg_flags);
2898 len -= NLMSG_LENGTH(sizeof(*r));
2900 connman_error("BUG: wrong nlmsg len %d", len);
2904 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2907 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2909 if (tb[RTA_GATEWAY])
2910 addr = inet_ntop(r->rtm_family,
2911 RTA_DATA(tb[RTA_GATEWAY]),
2912 abuf, sizeof(abuf));
2914 DBG("addr %s index %d user %p", addr, index, data->user_data);
2917 if (data && data->callback)
2918 data->callback(addr, index, data->user_data);
2924 * Return the interface index that contains route to host.
2926 int __connman_inet_get_route(const char *dest_address,
2927 connman_inet_addr_cb_t callback, void *user_data)
2929 struct get_route_cb_data *data;
2930 struct addrinfo hints, *rp;
2931 struct __connman_inet_rtnl_handle *rth;
2934 DBG("dest %s", dest_address);
2939 memset(&hints, 0, sizeof(hints));
2940 hints.ai_family = AF_UNSPEC;
2941 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2943 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2947 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2953 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2954 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2955 rth->req.n.nlmsg_type = RTM_GETROUTE;
2956 rth->req.u.r.rt.rtm_family = rp->ai_family;
2957 rth->req.u.r.rt.rtm_table = 0;
2958 rth->req.u.r.rt.rtm_protocol = 0;
2959 rth->req.u.r.rt.rtm_scope = 0;
2960 rth->req.u.r.rt.rtm_type = 0;
2961 rth->req.u.r.rt.rtm_src_len = 0;
2962 rth->req.u.r.rt.rtm_tos = 0;
2964 if (rp->ai_family == AF_INET) {
2965 struct sockaddr_in *sin = (struct sockaddr_in *)rp->ai_addr;
2967 rth->req.u.r.rt.rtm_dst_len = 32;
2968 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2969 RTA_DST, &sin->sin_addr, sizeof(sin->sin_addr));
2970 } else if (rp->ai_family == AF_INET6) {
2971 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rp->ai_addr;
2973 rth->req.u.r.rt.rtm_dst_len = 128;
2974 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2975 RTA_DST, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
2980 err = __connman_inet_rtnl_open(rth);
2984 data = g_try_malloc(sizeof(struct get_route_cb_data));
2990 data->callback = callback;
2991 data->user_data = user_data;
2993 #define GET_ROUTE_TIMEOUT 2
2994 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2995 get_route_cb, data);
3004 __connman_inet_rtnl_close(rth);
3011 int connman_inet_check_ipaddress(const char *host)
3013 struct addrinfo hints;
3014 struct addrinfo *addr;
3017 memset(&hints, 0, sizeof(struct addrinfo));
3018 hints.ai_flags = AI_NUMERICHOST;
3021 result = getaddrinfo(host, NULL, &hints, &addr);
3023 result = addr->ai_family;
3030 /* Check routine modified from ics-dhcp 4.2.3-P2 */
3031 bool connman_inet_check_hostname(const char *ptr, size_t len)
3036 * Not empty or complete length not over 255 characters.
3038 if ((len == 0) || (len > 256))
3042 * Consists of [[:alnum:]-]+ labels separated by [.]
3043 * a [_] is against RFC but seems to be "widely used"
3045 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
3047 if ((*p == '-') || (*p == '_')) {
3049 * Not allowed at begin or end of a label.
3051 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
3054 } else if (*p == '.') {
3056 * Each label has to be 1-63 characters;
3057 * we allow [.] at the end ('foo.bar.')
3061 if ((d <= 0) || (d >= 64))
3064 ptr = p + 1; /* Jump to the next label */
3066 } else if (isalnum((unsigned char)*p) == 0) {
3068 * Also numbers at the begin are fine
3077 char **__connman_inet_get_running_interfaces(void)
3081 struct ifreq *ifr = NULL;
3082 int sk, i, numif, count = 0;
3084 memset(&ifc, 0, sizeof(ifc));
3086 sk = socket(AF_INET, SOCK_DGRAM, 0);
3090 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
3094 * Allocate some extra bytes just in case there will
3095 * be new interfaces added between two SIOCGIFCONF
3098 ifr = g_try_malloc0(ifc.ifc_len * 2);
3104 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
3107 numif = ifc.ifc_len / sizeof(struct ifreq);
3109 result = g_try_malloc0((numif + 1) * sizeof(char *));
3115 for (i = 0; i < numif; i++) {
3116 struct ifreq *r = &ifr[i];
3117 struct in6_addr *addr6;
3121 * Note that we do not return loopback interfaces here as they
3122 * are not needed for our purposes.
3124 switch (r->ifr_addr.sa_family) {
3126 addr4 = ntohl(((struct sockaddr_in *)
3127 &r->ifr_addr)->sin_addr.s_addr);
3128 if (((addr4 & 0xff000000) >> 24) == 127)
3132 addr6 = &((struct sockaddr_in6 *)
3133 &r->ifr_addr)->sin6_addr;
3134 if (IN6_IS_ADDR_LINKLOCAL(addr6))
3139 result[count++] = g_strdup(r->ifr_name);
3144 if (count < numif) {
3145 char **prev_result = result;
3146 result = g_try_realloc(result, (count + 1) * sizeof(char *));
3148 g_free(prev_result);
3161 bool connman_inet_is_ipv6_supported()
3165 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3174 * Omits checking of the gateway matching the actual gateway IP since both
3175 * connmand and vpnd use inet.c, getting the route is via ipconfig and ipconfig
3176 * is different for both. Gateway is left here for possible future use.
3178 * Gateway can be NULL and connection.c then assigns 0.0.0.0 address or ::,
3179 * depending on IP family.
3181 bool connman_inet_is_default_route(int family, const char *host,
3182 const char *gateway, const char *netmask)
3184 return __connman_inet_is_any_addr(host, family) &&
3185 __connman_inet_is_any_addr(netmask, family);
3188 int __connman_inet_get_interface_address(int index, int family, void *address)
3190 struct interface_address if_addr = { 0 };
3192 if_addr.index = index;
3193 if_addr.family = family;
3194 if_addr.ipaddrs[ADDR_TYPE_IPADDR] = address;
3196 return get_interface_addresses(&if_addr);
3199 int __connman_inet_get_interface_mac_address(int index, uint8_t *mac_address)
3205 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3207 DBG("Open socket error");
3211 memset(&ifr, 0, sizeof(ifr));
3212 ifr.ifr_ifindex = index;
3214 err = ioctl(sk, SIOCGIFNAME, &ifr);
3216 DBG("Get interface name error");
3220 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
3222 DBG("Get MAC address error");
3226 memcpy(mac_address, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
3234 static int iprule_modify(int cmd, int family, uint32_t table_id,
3237 struct __connman_inet_rtnl_handle rth;
3240 memset(&rth, 0, sizeof(rth));
3242 rth.req.n.nlmsg_type = cmd;
3243 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3244 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
3245 rth.req.u.r.rt.rtm_family = family;
3246 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3247 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3248 rth.req.u.r.rt.rtm_table = table_id;
3249 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
3250 rth.req.u.r.rt.rtm_flags = 0;
3252 if (cmd == RTM_NEWRULE) {
3253 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
3254 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3257 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3258 FRA_FWMARK, fwmark);
3260 if (table_id < 256) {
3261 rth.req.u.r.rt.rtm_table = table_id;
3263 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3264 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3265 FRA_TABLE, table_id);
3268 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
3269 rth.req.u.r.rt.rtm_family = AF_INET;
3271 ret = __connman_inet_rtnl_open(&rth);
3275 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3278 __connman_inet_rtnl_close(&rth);
3283 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3285 /* ip rule add fwmark 9876 table 1234 */
3287 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
3290 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3292 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
3295 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
3296 const char *gateway, unsigned char prefixlen)
3298 struct __connman_inet_rtnl_handle rth;
3299 unsigned char buf[sizeof(struct in6_addr)];
3301 int family = connman_inet_check_ipaddress(gateway);
3304 DBG("gateway %s/%u table %u", gateway, prefixlen, table_id);
3318 struct in_addr ipv4_subnet_addr, ipv4_mask;
3320 memset(&ipv4_subnet_addr, 0, sizeof(ipv4_subnet_addr));
3321 ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
3322 ipv4_subnet_addr.s_addr = inet_addr(gateway);
3323 ipv4_subnet_addr.s_addr &= ipv4_mask.s_addr;
3325 dst = g_strdup(inet_ntoa(ipv4_subnet_addr));
3328 ret = inet_pton(family, dst ? dst : gateway, buf);
3333 memset(&rth, 0, sizeof(rth));
3335 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3336 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
3337 rth.req.n.nlmsg_type = cmd;
3338 rth.req.u.r.rt.rtm_family = family;
3339 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
3340 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
3341 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3342 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3343 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3344 rth.req.u.r.rt.rtm_dst_len = prefixlen;
3346 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req),
3347 prefixlen > 0 ? RTA_DST : RTA_GATEWAY, buf, len);
3349 if (table_id < 256) {
3350 rth.req.u.r.rt.rtm_table = table_id;
3352 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3353 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3354 RTA_TABLE, table_id);
3357 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3360 ret = __connman_inet_rtnl_open(&rth);
3364 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3367 __connman_inet_rtnl_close(&rth);
3372 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
3373 const char *gateway)
3375 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
3377 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 0);
3380 int __connman_inet_add_subnet_to_table(uint32_t table_id, int ifindex,
3381 const char *gateway, unsigned char prefixlen)
3383 /* ip route add 1.2.3.4/24 dev eth0 table 1234 */
3384 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, prefixlen);
3387 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
3388 const char *gateway)
3390 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
3392 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 0);
3395 int __connman_inet_del_subnet_from_table(uint32_t table_id, int ifindex,
3396 const char *gateway, unsigned char prefixlen)
3398 /* ip route del 1.2.3.4/24 dev eth0 table 1234 */
3399 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, prefixlen);
3402 int __connman_inet_get_interface_ll_address(int index, int family,
3405 struct interface_address if_addr = { 0 };
3407 if_addr.index = index;
3408 if_addr.family = family;
3409 if_addr.require_ll = true;
3410 if_addr.ipaddrs[ADDR_TYPE_IPADDR] = address;
3412 return get_interface_addresses(&if_addr);
3415 int __connman_inet_get_address_netmask(int ifindex,
3416 struct sockaddr_in *address,
3417 struct sockaddr_in *netmask)
3419 int sk, ret = -EINVAL;
3422 DBG("index %d", ifindex);
3424 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3428 memset(&ifr, 0, sizeof(ifr));
3429 ifr.ifr_ifindex = ifindex;
3431 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3434 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3437 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3438 sizeof(struct sockaddr_in));
3440 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3443 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3444 sizeof(struct sockaddr_in));
3452 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3453 struct in_addr *addr)
3457 char addrstr[INET_ADDRSTRLEN];
3458 struct in_addr taddr;
3459 GError *error = NULL;
3460 char *cmdline = NULL;
3463 char **pnpent = NULL;
3468 cmdline_file = "/proc/cmdline";
3470 pnp_file = "/proc/net/pnp";
3473 addr->s_addr = INADDR_NONE;
3475 if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3476 connman_error("%s: Cannot read %s %s\n", __func__,
3477 cmdline_file, error->message);
3481 if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3482 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3483 connman_error("%s: Cannot read %s %s\n", __func__,
3484 pnp_file, error->message);
3490 len = strlen(cmdline);
3495 /* remove newline */
3496 if (cmdline[len - 1] == '\n')
3497 cmdline[--len] = '\0';
3499 /* split in arguments (separated by space) */
3500 args = g_strsplit(cmdline, " ", 0);
3502 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3507 /* split in entries (by newlines) */
3508 pnpent = g_strsplit(pnp, "\n", 0);
3510 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3515 /* first find root argument */
3516 for (pp = args; *pp; pp++) {
3517 if (!strcmp(*pp, "root=/dev/nfs"))
3520 /* no rootnfs found */
3524 /* locate nfsroot argument */
3525 for (pp = args; *pp; pp++) {
3526 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3529 /* no nfsroot argument found */
3533 /* determine if nfsroot server is provided */
3534 nfsargs = strchr(*pp, '=');
3539 /* find whether serverip is present */
3540 s = strchr(nfsargs, ':');
3545 /* no serverip, use bootserver */
3546 for (pp = pnpent; *pp; pp++) {
3547 if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3550 /* no bootserver found */
3553 s = *pp + strlen("bootserver ");
3557 /* copy to addr string buffer */
3558 if (len >= sizeof(addrstr)) {
3559 connman_error("%s: Bad server\n", __func__);
3562 memcpy(addrstr, s, len);
3563 addrstr[len] = '\0';
3565 err = inet_pton(AF_INET, addrstr, addr);
3567 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3579 g_error_free(error);
3586 /* get interface out of which peer is reachable (IPv4 only) */
3587 static int get_peer_iface(struct in_addr *addr, char *ifname)
3589 struct ifaddrs *ifaddr, *ifa;
3590 struct sockaddr_in saddr, *ifsaddr;
3595 /* Obtain address(es) matching host/port */
3596 err = getifaddrs(&ifaddr);
3598 connman_error("%s: getifaddrs() failed %d (%s)\n",
3599 __func__, errno, strerror(errno));
3603 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3605 connman_error("%s: socket() failed %d (%s)\n",
3606 __func__, errno, strerror(errno));
3610 memset(&saddr, 0, sizeof(saddr));
3611 saddr.sin_family = AF_INET;
3612 saddr.sin_port = 0; /* any port */
3613 saddr.sin_addr = *addr;
3615 /* no need to bind, connect will select iface */
3616 err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3618 connman_error("%s: connect() failed: %d (%s)\n",
3619 __func__, errno, strerror(errno));
3623 socklen = sizeof(saddr);
3624 err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3626 connman_error("%s: getsockname() failed: %d (%s)\n",
3627 __func__, errno, strerror(errno));
3632 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3636 /* only IPv4 address */
3637 if (ifa->ifa_addr->sa_family != AF_INET)
3640 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3642 /* match address? */
3643 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3650 strcpy(ifname, ifa->ifa_name);
3656 freeifaddrs(ifaddr);
3661 bool __connman_inet_isrootnfs_device(const char *devname)
3663 struct in_addr addr;
3664 char ifname[IFNAMSIZ];
3666 return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3667 get_peer_iface(&addr, ifname) == 0 &&
3668 strcmp(devname, ifname) == 0;
3671 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3676 GError *error = NULL;
3678 char **pnpent = NULL;
3679 char **nameservers = NULL;
3682 pnp_file = "/proc/net/pnp";
3684 if (!g_file_test(pnp_file, G_FILE_TEST_EXISTS))
3687 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3688 connman_error("%s: Cannot read %s %s\n", __func__,
3689 pnp_file, error->message);
3693 /* split in entries (by newlines) */
3694 pnpent = g_strsplit(pnp, "\n", 0);
3696 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3702 * Perform two passes to retrieve a char ** array of
3703 * nameservers that are not 0.0.0.0
3705 * The first pass counts them, the second fills in the
3710 for (pass = 1; pass <= 2; pass++) {
3712 /* at the start of the second pass allocate */
3714 nameservers = g_new(char *, count + 1);
3717 for (pp = pnpent; *pp; pp++) {
3718 /* match 'nameserver ' at the start of each line */
3719 if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3722 /* compare it against 0.0.0.0 */
3723 s = *pp + strlen("nameserver ");
3724 if (!strcmp(s, "0.0.0.0"))
3727 /* on second pass fill in array */
3729 nameservers[count] = g_strdup(s);
3733 /* no nameservers? */
3737 /* and terminate char ** array with NULL */
3739 nameservers[count] = NULL;
3747 g_error_free(error);