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 #if defined TIZEN_EXT_WIFI_MESH
193 char *connman_inet_ifaddr(const char *name)
196 struct ether_addr eth;
200 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
204 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
206 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
216 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
217 snprintf(str, 13, "%02x%02x%02x%02x%02x%02x",
218 eth.ether_addr_octet[0],
219 eth.ether_addr_octet[1],
220 eth.ether_addr_octet[2],
221 eth.ether_addr_octet[3],
222 eth.ether_addr_octet[4],
223 eth.ether_addr_octet[5]);
228 char *connman_inet_ifname2addr(const char *name)
231 struct ether_addr eth;
235 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
239 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
241 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
251 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
252 snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
253 eth.ether_addr_octet[0],
254 eth.ether_addr_octet[1],
255 eth.ether_addr_octet[2],
256 eth.ether_addr_octet[3],
257 eth.ether_addr_octet[4],
258 eth.ether_addr_octet[5]);
264 bool __connman_inet_is_any_addr(const char *address, int family)
267 struct addrinfo hints;
268 struct addrinfo *result = NULL;
269 struct sockaddr_in6 *in6 = NULL;
270 struct sockaddr_in *in4 = NULL;
272 if (!address || !*address)
275 memset(&hints, 0, sizeof(struct addrinfo));
277 hints.ai_family = family;
279 if (getaddrinfo(address, NULL, &hints, &result))
283 if (result->ai_family == AF_INET6) {
284 in6 = (struct sockaddr_in6*)result->ai_addr;
285 ret = IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr);
286 } else if (result->ai_family == AF_INET) {
287 in4 = (struct sockaddr_in*)result->ai_addr;
288 ret = in4->sin_addr.s_addr == INADDR_ANY;
291 freeaddrinfo(result);
298 int connman_inet_ifindex(const char *name)
306 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
310 memset(&ifr, 0, sizeof(ifr));
311 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
313 err = ioctl(sk, SIOCGIFINDEX, &ifr);
320 return ifr.ifr_ifindex;
323 char *connman_inet_ifname(int index)
331 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
335 memset(&ifr, 0, sizeof(ifr));
336 ifr.ifr_ifindex = index;
338 err = ioctl(sk, SIOCGIFNAME, &ifr);
345 return g_strdup(ifr.ifr_name);
348 int connman_inet_ifup(int index)
353 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
357 memset(&ifr, 0, sizeof(ifr));
358 ifr.ifr_ifindex = index;
360 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
365 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
370 if (ifr.ifr_flags & IFF_UP) {
375 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
377 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
390 int connman_inet_ifdown(int index)
392 struct ifreq ifr, addr_ifr;
393 struct sockaddr_in *addr;
396 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
400 memset(&ifr, 0, sizeof(ifr));
401 ifr.ifr_ifindex = index;
403 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
408 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
413 memset(&addr_ifr, 0, sizeof(addr_ifr));
414 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
415 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
416 addr->sin_family = AF_INET;
417 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
418 connman_warn("Could not clear IPv4 address index %d", index);
420 if (!(ifr.ifr_flags & IFF_UP)) {
425 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
427 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
438 #if defined TIZEN_EXT
439 void connman_inet_update_device_ident(struct connman_device *device)
442 enum connman_device_type type;
443 char *ident = NULL, *addr = NULL;
445 index = connman_device_get_index(device);
446 type = connman_device_get_type(device);
449 case CONNMAN_DEVICE_TYPE_UNKNOWN:
451 case CONNMAN_DEVICE_TYPE_ETHERNET:
452 case CONNMAN_DEVICE_TYPE_GADGET:
453 case CONNMAN_DEVICE_TYPE_WIFI:
454 if (type == CONNMAN_DEVICE_TYPE_WIFI)
455 addr = _get_wifi_addr();
457 addr = index2addr(index);
459 if (type == CONNMAN_DEVICE_TYPE_WIFI)
460 ident = _get_wifi_ident();
462 ident = index2ident(index, NULL);
464 case CONNMAN_DEVICE_TYPE_CELLULAR:
465 ident = index2ident(index, NULL);
467 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
468 case CONNMAN_DEVICE_TYPE_GPS:
469 case CONNMAN_DEVICE_TYPE_VENDOR:
474 connman_device_set_ident(device, ident);
479 connman_device_set_string(device, "Address", addr);
485 bool connman_inet_is_ifup(int index)
491 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
493 connman_warn("Failed to open socket");
497 memset(&ifr, 0, sizeof(ifr));
498 ifr.ifr_ifindex = index;
500 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
501 connman_warn("Failed to get interface name for interface %d", index);
505 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
506 connman_warn("Failed to get interface flags for index %d", index);
510 if (ifr.ifr_flags & IFF_UP)
520 struct in6_addr ifr6_addr;
521 __u32 ifr6_prefixlen;
522 unsigned int ifr6_ifindex;
525 int connman_inet_set_ipv6_address(int index,
526 struct connman_ipaddress *ipaddress)
529 unsigned char prefix_len;
532 if (!ipaddress->local)
535 prefix_len = ipaddress->prefixlen;
536 address = ipaddress->local;
538 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
540 err = __connman_inet_modify_address(RTM_NEWADDR,
541 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
542 address, NULL, prefix_len, NULL);
544 connman_error("%s: %s", __func__, strerror(-err));
551 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
554 unsigned char prefix_len;
555 const char *address, *broadcast, *peer;
557 if (!ipaddress->local)
560 prefix_len = ipaddress->prefixlen;
561 address = ipaddress->local;
562 broadcast = ipaddress->broadcast;
563 peer = ipaddress->peer;
565 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
567 err = __connman_inet_modify_address(RTM_NEWADDR,
568 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
569 address, peer, prefix_len, broadcast);
571 connman_error("%s: %s", __func__, strerror(-err));
578 int connman_inet_clear_ipv6_address(int index, const char *address,
583 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
588 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
589 address, NULL, prefix_len, NULL);
591 connman_error("%s: %s", __func__, strerror(-err));
598 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
601 unsigned char prefix_len;
602 const char *address, *broadcast, *peer;
604 prefix_len = ipaddress->prefixlen;
605 address = ipaddress->local;
606 broadcast = ipaddress->broadcast;
607 peer = ipaddress->peer;
609 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
610 address, prefix_len, peer, broadcast);
615 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
616 address, peer, prefix_len, broadcast);
618 connman_error("%s: %s", __func__, strerror(-err));
625 int connman_inet_add_host_route(int index, const char *host,
628 return connman_inet_add_network_route(index, host, gateway, NULL);
631 int connman_inet_del_host_route(int index, const char *host)
633 return connman_inet_del_network_route(index, host);
636 int connman_inet_add_network_route(int index, const char *host,
642 struct sockaddr_in addr;
645 DBG("index %d host %s gateway %s netmask %s", index,
646 host, gateway, netmask);
648 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
654 memset(&ifr, 0, sizeof(ifr));
655 ifr.ifr_ifindex = index;
657 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
663 DBG("ifname %s", ifr.ifr_name);
665 memset(&rt, 0, sizeof(rt));
666 rt.rt_flags = RTF_UP;
669 * Set RTF_GATEWAY only when gateway is set and the gateway IP address
670 * is not IPv4 any address (0.0.0.0). If the given gateway IP address is
671 * any address adding of route will fail when RTF_GATEWAY set. Passing
672 * gateway as NULL or INADDR_ANY should have the same effect. Setting
673 * the gateway address later to the struct is not affected by this,
674 * since given IPv4 any address (0.0.0.0) equals the value set with
677 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET))
678 rt.rt_flags |= RTF_GATEWAY;
680 rt.rt_flags |= RTF_HOST;
682 memset(&addr, 0, sizeof(addr));
683 addr.sin_family = AF_INET;
684 addr.sin_addr.s_addr = inet_addr(host);
685 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
687 memset(&addr, 0, sizeof(addr));
688 addr.sin_family = AF_INET;
690 addr.sin_addr.s_addr = inet_addr(gateway);
692 addr.sin_addr.s_addr = INADDR_ANY;
693 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
695 memset(&addr, 0, sizeof(addr));
696 addr.sin_family = AF_INET;
697 addr.sin_addr.s_addr = INADDR_ANY;
699 addr.sin_addr.s_addr = inet_addr(netmask);
701 addr.sin_addr.s_addr = INADDR_ANY;
702 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
704 rt.rt_dev = ifr.ifr_name;
706 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
713 connman_error("Adding host route failed (%s)",
719 int connman_inet_del_network_route(int index, const char *host)
723 struct sockaddr_in addr;
726 DBG("index %d host %s", index, host);
728 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
734 memset(&ifr, 0, sizeof(ifr));
735 ifr.ifr_ifindex = index;
737 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
743 DBG("ifname %s", ifr.ifr_name);
745 memset(&rt, 0, sizeof(rt));
746 rt.rt_flags = RTF_UP | RTF_HOST;
748 memset(&addr, 0, sizeof(addr));
749 addr.sin_family = AF_INET;
750 addr.sin_addr.s_addr = inet_addr(host);
751 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
753 rt.rt_dev = ifr.ifr_name;
755 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
762 connman_error("Deleting host route failed (%s)",
768 int connman_inet_del_ipv6_network_route(int index, const char *host,
769 unsigned char prefix_len)
774 DBG("index %d host %s", index, host);
779 memset(&rt, 0, sizeof(rt));
781 rt.rtmsg_dst_len = prefix_len;
783 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
788 rt.rtmsg_flags = RTF_UP | RTF_HOST;
791 rt.rtmsg_ifindex = index;
793 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
799 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
806 connman_error("Del IPv6 host route error (%s)",
812 int connman_inet_del_ipv6_host_route(int index, const char *host)
814 return connman_inet_del_ipv6_network_route(index, host, 128);
817 int connman_inet_add_ipv6_network_route(int index, const char *host,
819 unsigned char prefix_len)
824 DBG("index %d host %s gateway %s", index, host, gateway);
829 memset(&rt, 0, sizeof(rt));
831 rt.rtmsg_dst_len = prefix_len;
833 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
838 rt.rtmsg_flags = RTF_UP | RTF_HOST;
841 * Set RTF_GATEWAY only when gateway is set, the gateway IP address is
842 * not IPv6 any address (e.g., ::) and the address is valid (conversion
843 * succeeds). If the given gateway IP address is any address then
844 * adding of route will fail when RTF_GATEWAY set. Passing gateway as
845 * NULL or IPv6 any address should have the same effect.
848 if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET6) &&
849 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) > 0)
850 rt.rtmsg_flags |= RTF_GATEWAY;
853 rt.rtmsg_ifindex = index;
855 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
861 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
868 connman_error("Set IPv6 host route error (%s)",
874 int connman_inet_add_ipv6_host_route(int index, const char *host,
877 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
880 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
885 DBG("index %d gateway %s", index, gateway);
890 memset(&rt, 0, sizeof(rt));
892 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
897 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
899 rt.rtmsg_dst_len = 0;
900 rt.rtmsg_ifindex = index;
902 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
908 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
915 connman_error("Clear default IPv6 gateway error (%s)",
921 int connman_inet_set_gateway_interface(int index)
925 struct sockaddr_in addr;
928 DBG("index %d", index);
930 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
936 memset(&ifr, 0, sizeof(ifr));
937 ifr.ifr_ifindex = index;
939 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
945 DBG("ifname %s", ifr.ifr_name);
947 memset(&rt, 0, sizeof(rt));
948 rt.rt_flags = RTF_UP;
950 memset(&addr, 0, sizeof(addr));
951 addr.sin_family = AF_INET;
952 addr.sin_addr.s_addr = INADDR_ANY;
954 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
955 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
956 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
958 rt.rt_dev = ifr.ifr_name;
960 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
967 connman_error("Setting default interface route failed (%s)",
973 int connman_inet_set_ipv6_gateway_interface(int index)
977 struct sockaddr_in6 addr;
978 const struct in6_addr any = IN6ADDR_ANY_INIT;
981 DBG("index %d", index);
983 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
989 memset(&ifr, 0, sizeof(ifr));
990 ifr.ifr_ifindex = index;
992 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
998 DBG("ifname %s", ifr.ifr_name);
1000 memset(&rt, 0, sizeof(rt));
1001 rt.rt_flags = RTF_UP;
1003 memset(&addr, 0, sizeof(addr));
1004 addr.sin6_family = AF_INET6;
1005 addr.sin6_addr = any;
1007 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1008 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1009 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1011 rt.rt_dev = ifr.ifr_name;
1013 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
1020 connman_error("Setting default interface route failed (%s)",
1026 int connman_inet_clear_gateway_address(int index, const char *gateway)
1030 struct sockaddr_in addr;
1033 DBG("index %d gateway %s", index, gateway);
1035 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1041 memset(&ifr, 0, sizeof(ifr));
1042 ifr.ifr_ifindex = index;
1044 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1050 DBG("ifname %s", ifr.ifr_name);
1052 memset(&rt, 0, sizeof(rt));
1053 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1055 memset(&addr, 0, sizeof(addr));
1056 addr.sin_family = AF_INET;
1057 addr.sin_addr.s_addr = INADDR_ANY;
1058 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1060 memset(&addr, 0, sizeof(addr));
1061 addr.sin_family = AF_INET;
1062 addr.sin_addr.s_addr = inet_addr(gateway);
1063 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1065 memset(&addr, 0, sizeof(addr));
1066 addr.sin_family = AF_INET;
1067 addr.sin_addr.s_addr = INADDR_ANY;
1068 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1070 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1077 connman_error("Removing default gateway route failed (%s)",
1083 int connman_inet_clear_gateway_interface(int index)
1087 struct sockaddr_in addr;
1090 DBG("index %d", index);
1092 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1098 memset(&ifr, 0, sizeof(ifr));
1099 ifr.ifr_ifindex = index;
1101 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1107 DBG("ifname %s", ifr.ifr_name);
1109 memset(&rt, 0, sizeof(rt));
1110 rt.rt_flags = RTF_UP;
1112 memset(&addr, 0, sizeof(addr));
1113 addr.sin_family = AF_INET;
1114 addr.sin_addr.s_addr = INADDR_ANY;
1116 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1117 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1118 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1120 rt.rt_dev = ifr.ifr_name;
1122 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1129 connman_error("Removing default interface route failed (%s)",
1135 int connman_inet_clear_ipv6_gateway_interface(int index)
1139 struct sockaddr_in6 addr;
1140 const struct in6_addr any = IN6ADDR_ANY_INIT;
1143 DBG("index %d", index);
1145 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1151 memset(&ifr, 0, sizeof(ifr));
1152 ifr.ifr_ifindex = index;
1154 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1160 DBG("ifname %s", ifr.ifr_name);
1162 memset(&rt, 0, sizeof(rt));
1163 rt.rt_flags = RTF_UP;
1165 memset(&addr, 0, sizeof(addr));
1166 addr.sin6_family = AF_INET6;
1167 addr.sin6_addr = any;
1169 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1170 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1171 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1173 rt.rt_dev = ifr.ifr_name;
1175 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1182 connman_error("Removing default interface route failed (%s)",
1188 bool connman_inet_compare_subnet(int index, const char *host)
1191 struct in_addr _host_addr;
1192 in_addr_t host_addr, netmask_addr, if_addr;
1193 struct sockaddr_in *netmask, *addr;
1196 DBG("host %s", host);
1201 if (inet_aton(host, &_host_addr) == 0)
1203 host_addr = _host_addr.s_addr;
1205 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1209 memset(&ifr, 0, sizeof(ifr));
1210 ifr.ifr_ifindex = index;
1212 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1217 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1222 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1223 netmask_addr = netmask->sin_addr.s_addr;
1225 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1232 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1233 if_addr = addr->sin_addr.s_addr;
1235 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1238 static bool mem_mask_equal(const void *a, const void *b,
1239 const void *mask, size_t n)
1241 const unsigned char *addr1 = a;
1242 const unsigned char *addr2 = b;
1243 const unsigned char *bitmask = mask;
1246 for (i = 0; i < n; i++) {
1247 if ((addr1[i] ^ addr2[i]) & bitmask[i])
1254 bool connman_inet_compare_ipv6_subnet(int index, const char *host)
1256 struct ifaddrs *ifaddr, *ifa;
1258 char name[IF_NAMESIZE];
1259 struct in6_addr haddr;
1261 if (inet_pton(AF_INET6, host, &haddr) <= 0)
1264 if (!if_indextoname(index, name))
1267 DBG("index %d interface %s", index, name);
1269 if (getifaddrs(&ifaddr) < 0) {
1270 DBG("Cannot get addresses err %d/%s", errno, strerror(errno));
1274 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1275 struct sockaddr_in6 *iaddr;
1276 struct sockaddr_in6 *imask;
1281 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) != 0 ||
1282 ifa->ifa_addr->sa_family != AF_INET6)
1285 iaddr = (struct sockaddr_in6 *)ifa->ifa_addr;
1286 imask = (struct sockaddr_in6 *)ifa->ifa_netmask;
1288 rv = mem_mask_equal(&iaddr->sin6_addr, &haddr,
1295 freeifaddrs(ifaddr);
1299 int connman_inet_remove_from_bridge(int index, const char *bridge)
1307 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1313 memset(&ifr, 0, sizeof(ifr));
1314 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1315 ifr.ifr_ifindex = index;
1317 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1324 connman_error("Remove interface from bridge error %s",
1330 int connman_inet_add_to_bridge(int index, const char *bridge)
1338 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1344 memset(&ifr, 0, sizeof(ifr));
1345 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1346 ifr.ifr_ifindex = index;
1348 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1355 connman_error("Add interface to bridge error %s",
1361 int connman_inet_set_mtu(int index, int mtu)
1366 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1370 memset(&ifr, 0, sizeof(ifr));
1371 ifr.ifr_ifindex = index;
1373 err = ioctl(sk, SIOCGIFNAME, &ifr);
1376 err = ioctl(sk, SIOCSIFMTU, &ifr);
1383 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1393 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1397 index = if_nametoindex(tunnel);
1399 err = connman_inet_set_mtu(index, mtu);
1403 memset(&ifr, 0, sizeof(ifr));
1404 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1405 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1412 if ((ifr.ifr_flags ^ flags) & mask) {
1413 ifr.ifr_flags &= ~mask;
1414 ifr.ifr_flags |= mask & flags;
1415 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1417 connman_error("SIOCSIFFLAGS failed: %s",
1426 int connman_inet_create_tunnel(char **iface)
1431 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1434 connman_error("Failed to open /dev/net/tun: %s",
1439 memset(&ifr, 0, sizeof(ifr));
1440 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1442 for (i = 0; i < 256; i++) {
1443 sprintf(ifr.ifr_name, "tun%d", i);
1445 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1450 connman_error("Failed to find available tun device");
1455 *iface = g_strdup(ifr.ifr_name);
1461 * This callback struct is used when sending router and neighbor
1462 * solicitation and advertisement messages.
1465 GIOChannel *channel;
1467 struct sockaddr_in6 addr;
1473 #define CMSG_BUF_LEN 512
1474 #define IN6ADDR_ALL_NODES_MC_INIT \
1475 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1476 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1477 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1479 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1480 static const struct in6_addr in6addr_all_routers_mc =
1481 IN6ADDR_ALL_ROUTERS_MC_INIT;
1483 static void xs_cleanup(struct xs_cb_data *data)
1485 if (data->channel) {
1486 g_io_channel_shutdown(data->channel, TRUE, NULL);
1487 g_io_channel_unref(data->channel);
1488 data->channel = NULL;
1491 if (data->timeout > 0)
1492 g_source_remove(data->timeout);
1494 if (data->watch_id > 0)
1495 g_source_remove(data->watch_id);
1500 static gboolean rs_timeout_cb(gpointer user_data)
1502 struct xs_cb_data *data = user_data;
1504 DBG("user data %p", user_data);
1509 if (data->callback) {
1510 __connman_inet_rs_cb_t cb = data->callback;
1511 cb(NULL, 0, data->user_data);
1519 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1523 unsigned char chdr[CMSG_BUF_LEN];
1524 unsigned char buf[1540];
1525 struct nd_router_advert *hdr;
1526 struct sockaddr_in6 saddr;
1528 __connman_inet_rs_cb_t cb = data->callback;
1532 iov.iov_len = sizeof(buf);
1535 mhdr.msg_name = (void *)&saddr;
1536 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1538 mhdr.msg_iov = &iov;
1539 mhdr.msg_iovlen = 1;
1540 mhdr.msg_control = (void *)chdr;
1541 mhdr.msg_controllen = CMSG_BUF_LEN;
1543 len = recvmsg(fd, &mhdr, 0);
1545 cb(NULL, 0, data->user_data);
1549 #if defined TIZEN_EXT
1550 /* Set Received Source Address from router as IPv6 Gateway Address */
1551 char src_addr[INET6_ADDRSTRLEN];
1552 if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
1556 DBG("Received Source Address %s from router", src_addr);
1558 /* icmpv6_recv() function can be called in two scenarios :
1559 * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
1560 * 2. When __connman_inet_ipv6_send_rs() is called from
1561 * __connman_6to4_probe()
1562 * In the second case it is not required to set DHCPv6 Gateway Address
1563 * as DHCPv6 was not started and network structure was not passed as
1564 * user_data. If it is tried to add Source Address as Gateway Address
1565 * then it will lead to crash because of user_data being ip_address
1566 * instead of network structure. So Adding Gateway Address in case 1st
1569 char *address = data->user_data;
1571 unsigned char buffer[sizeof(struct in6_addr)] = {0, };
1572 /* Checking if user_data is an ip_address */
1573 err = inet_pton(AF_INET, address, buffer);
1574 /* Setting Received Source Address from
1575 * router as Gateway Address */
1577 __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
1579 hdr = (struct nd_router_advert *)buf;
1580 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1581 sizeof(struct nd_router_advert));
1582 if (hdr->nd_ra_code != 0)
1585 cb(hdr, len, data->user_data);
1590 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1593 struct xs_cb_data *xs_data = data;
1597 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1600 fd = g_io_channel_unix_get_fd(chan);
1601 ret = icmpv6_recv(fd, xs_data);
1606 xs_cleanup(xs_data);
1610 /* Adapted from RFC 1071 "C" Implementation Example */
1611 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1612 const void *extra_data, socklen_t extra_datalen)
1614 register unsigned long sum = 0;
1619 /* caller must make sure datalen is even */
1621 addr = (uint16_t *)phdr;
1622 for (i = 0; i < 20; i++)
1626 addr = (uint16_t *)data;
1634 count = extra_datalen;
1635 addr = (uint16_t *)extra_data;
1644 sum = (sum & 0xffff) + (sum >> 16);
1646 return (uint16_t)~sum;
1649 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1650 const struct in6_addr *source,
1651 unsigned char *buf, size_t len, uint16_t lifetime)
1654 struct in6_addr src;
1655 struct in6_addr dst;
1657 uint8_t reserved[3];
1664 struct icmp6_hdr icmp;
1665 struct nd_neighbor_solicit ns;
1666 struct nd_router_solicit rs;
1667 struct nd_router_advert ra;
1672 struct cmsghdr *cmsg;
1673 struct in6_pktinfo *pinfo;
1674 struct sockaddr_in6 dst, src;
1675 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1676 struct iovec iov[2];
1677 int fd, datalen, ret, iovlen = 1;
1678 #if defined TIZEN_EXT
1684 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1688 memset(&frame, 0, sizeof(frame));
1689 memset(&dst, 0, sizeof(dst));
1691 if (type == ND_ROUTER_SOLICIT)
1692 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1693 else if (type == ND_ROUTER_ADVERT) {
1694 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1695 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1696 } else if (type == ND_NEIGHBOR_SOLICIT) {
1697 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1698 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1704 dst.sin6_addr = *dest;
1707 src.sin6_addr = *source;
1709 src.sin6_addr = in6addr_any;
1711 /* Fill in the IPv6 header */
1712 frame.ip.ip6_vfc = 0x60;
1713 frame.ip.ip6_plen = htons(datalen + len);
1714 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1715 frame.ip.ip6_hlim = 255;
1716 frame.ip.ip6_dst = dst.sin6_addr;
1717 frame.ip.ip6_src = src.sin6_addr;
1718 /* all other fields are already set to zero */
1720 /* Prepare pseudo header for csum */
1721 memset(&phdr, 0, sizeof(phdr));
1722 phdr.dst = dst.sin6_addr;
1723 phdr.src = src.sin6_addr;
1724 phdr.plen = htonl(datalen + len);
1725 phdr.nxt = IPPROTO_ICMPV6;
1727 /* Fill in remaining ICMP header fields */
1728 frame.i.icmp.icmp6_type = type;
1729 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1731 iov[0].iov_base = &frame;
1732 iov[0].iov_len = sizeof(frame.ip) + datalen;
1735 iov[1].iov_base = buf;
1736 iov[1].iov_len = len;
1740 dst.sin6_family = AF_INET6;
1741 msgh.msg_name = &dst;
1742 msgh.msg_namelen = sizeof(dst);
1744 msgh.msg_iovlen = iovlen;
1747 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1748 cmsg = (struct cmsghdr *)cbuf;
1749 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1750 pinfo->ipi6_ifindex = oif;
1752 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1753 cmsg->cmsg_level = IPPROTO_IPV6;
1754 cmsg->cmsg_type = IPV6_PKTINFO;
1755 msgh.msg_control = cmsg;
1756 msgh.msg_controllen = cmsg->cmsg_len;
1758 ret = sendmsg(fd, &msgh, 0);
1759 #if defined TIZEN_EXT
1760 DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
1767 static inline void ipv6_addr_set(struct in6_addr *addr,
1768 uint32_t w1, uint32_t w2,
1769 uint32_t w3, uint32_t w4)
1771 addr->s6_addr32[0] = w1;
1772 addr->s6_addr32[1] = w2;
1773 addr->s6_addr32[2] = w3;
1774 addr->s6_addr32[3] = w4;
1777 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1778 struct in6_addr *solicited)
1780 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1781 htonl(0xFF000000) | addr->s6_addr32[3]);
1784 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1787 unsigned int val = 0;
1788 struct ipv6_mreq mreq;
1791 memset(&mreq, 0, sizeof(mreq));
1792 mreq.ipv6mr_interface = ifindex;
1793 mreq.ipv6mr_multiaddr = *mc_addr;
1795 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1799 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1804 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1807 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1814 int __connman_inet_ipv6_send_rs(int index, int timeout,
1815 __connman_inet_rs_cb_t callback, void *user_data)
1817 struct xs_cb_data *data;
1818 struct icmp6_filter filter;
1819 struct in6_addr solicit;
1820 struct in6_addr dst = in6addr_all_routers_mc;
1826 data = g_try_malloc0(sizeof(struct xs_cb_data));
1830 data->callback = callback;
1831 data->user_data = user_data;
1832 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1834 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1840 ICMP6_FILTER_SETBLOCKALL(&filter);
1841 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1843 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1844 sizeof(struct icmp6_filter));
1846 ipv6_addr_solict_mult(&dst, &solicit);
1847 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1848 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1850 data->channel = g_io_channel_unix_new(sk);
1851 g_io_channel_set_close_on_unref(data->channel, TRUE);
1853 g_io_channel_set_encoding(data->channel, NULL, NULL);
1854 g_io_channel_set_buffered(data->channel, FALSE);
1856 data->watch_id = g_io_add_watch(data->channel,
1857 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1858 icmpv6_event, data);
1860 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1865 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1866 struct in6_addr *advert)
1868 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1869 htonl(0xFF000000) | addr->s6_addr32[3]);
1872 #define MSG_SIZE_SEND 1452
1874 static int inc_len(int len, int inc)
1876 if (len > MSG_SIZE_SEND)
1883 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1884 GSList *prefixes, int router_lifetime)
1887 struct in6_addr src, *source;
1888 struct in6_addr dst = in6addr_all_nodes_mc;
1889 GDHCPIAPrefix *prefix;
1890 unsigned char buf[MSG_SIZE_SEND];
1891 char addr_str[INET6_ADDRSTRLEN];
1898 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1903 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1908 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1909 prefixes, inet_ntop(AF_INET6, source, addr_str,
1913 memset(buf, 0, MSG_SIZE_SEND);
1916 for (list = prefixes; list; list = list->next) {
1917 struct nd_opt_prefix_info *pinfo;
1919 prefix = list->data;
1920 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1922 len = inc_len(len, sizeof(*pinfo));
1928 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1929 pinfo->nd_opt_pi_len = 4;
1930 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1931 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1932 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1933 if (router_lifetime > 0) {
1934 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1935 pinfo->nd_opt_pi_preferred_time =
1936 htonl(prefix->preferred);
1938 pinfo->nd_opt_pi_reserved2 = 0;
1940 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1941 sizeof(struct in6_addr));
1943 DBG("[%d] index %d prefix %s/%d", count, index,
1944 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1945 INET6_ADDRSTRLEN), prefix->prefixlen);
1951 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1952 buf, len, router_lifetime);
1954 DBG("cannot send RA %d/%s", err, strerror(-err));
1962 void __connman_inet_ipv6_stop_recv_rs(void *context)
1967 xs_cleanup(context);
1970 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1974 unsigned char chdr[CMSG_BUF_LEN];
1975 unsigned char buf[1540];
1976 struct nd_router_solicit *hdr;
1977 struct sockaddr_in6 saddr;
1979 __connman_inet_recv_rs_cb_t cb = data->callback;
1983 iov.iov_len = sizeof(buf);
1986 mhdr.msg_name = (void *)&saddr;
1987 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1989 mhdr.msg_iov = &iov;
1990 mhdr.msg_iovlen = 1;
1991 mhdr.msg_control = (void *)chdr;
1992 mhdr.msg_controllen = CMSG_BUF_LEN;
1994 len = recvmsg(fd, &mhdr, 0);
1996 cb(NULL, 0, data->user_data);
2000 hdr = (struct nd_router_solicit *)buf;
2001 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
2002 sizeof(struct nd_router_solicit));
2003 if (hdr->nd_rs_code != 0)
2006 cb(hdr, len, data->user_data);
2010 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
2014 struct xs_cb_data *xs_data = data;
2018 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2021 fd = g_io_channel_unix_get_fd(chan);
2022 ret = icmpv6_rs_recv(fd, xs_data);
2027 xs_data->watch_id = 0;
2031 int __connman_inet_ipv6_start_recv_rs(int index,
2032 __connman_inet_recv_rs_cb_t callback,
2036 struct xs_cb_data *data;
2037 struct icmp6_filter filter;
2038 char addr_str[INET6_ADDRSTRLEN];
2041 data = g_try_malloc0(sizeof(struct xs_cb_data));
2045 data->callback = callback;
2046 data->user_data = user_data;
2048 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2056 ICMP6_FILTER_SETBLOCKALL(&filter);
2057 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
2059 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2060 sizeof(struct icmp6_filter));
2062 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
2064 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
2065 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
2066 err, strerror(-err));
2068 data->channel = g_io_channel_unix_new(sk);
2069 g_io_channel_set_close_on_unref(data->channel, TRUE);
2071 g_io_channel_set_encoding(data->channel, NULL, NULL);
2072 g_io_channel_set_buffered(data->channel, FALSE);
2074 data->watch_id = g_io_add_watch(data->channel,
2075 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2076 icmpv6_rs_event, data);
2083 static gboolean ns_timeout_cb(gpointer user_data)
2085 struct xs_cb_data *data = user_data;
2087 DBG("user data %p", user_data);
2092 if (data->callback) {
2093 __connman_inet_ns_cb_t cb = data->callback;
2094 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2102 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
2106 unsigned char chdr[CMSG_BUF_LEN];
2107 unsigned char buf[1540];
2108 struct nd_neighbor_advert *hdr;
2109 struct sockaddr_in6 saddr;
2111 __connman_inet_ns_cb_t cb = data->callback;
2115 iov.iov_len = sizeof(buf);
2118 mhdr.msg_name = (void *)&saddr;
2119 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
2121 mhdr.msg_iov = &iov;
2122 mhdr.msg_iovlen = 1;
2123 mhdr.msg_control = (void *)chdr;
2124 mhdr.msg_controllen = CMSG_BUF_LEN;
2126 len = recvmsg(fd, &mhdr, 0);
2128 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2132 hdr = (struct nd_neighbor_advert *)buf;
2133 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
2134 sizeof(struct nd_neighbor_advert));
2135 if (hdr->nd_na_code != 0)
2139 * We can receive any neighbor advertisement so we need to check if the
2140 * packet was meant for us and ignore the packet otherwise.
2142 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
2143 sizeof(struct in6_addr)))
2146 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
2151 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
2155 struct xs_cb_data *xs_data = data;
2159 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2162 fd = g_io_channel_unix_get_fd(chan);
2163 ret = icmpv6_nd_recv(fd, xs_data);
2168 xs_cleanup(xs_data);
2172 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
2173 struct in6_addr *addr,
2174 __connman_inet_ns_cb_t callback,
2177 struct xs_cb_data *data;
2178 struct icmp6_filter filter;
2179 struct in6_addr solicit;
2180 int sk, err, val = 1;
2182 if (timeout_ms <= 0)
2185 data = g_try_malloc0(sizeof(struct xs_cb_data));
2189 data->callback = callback;
2190 data->user_data = user_data;
2191 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
2196 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
2198 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2204 ICMP6_FILTER_SETBLOCKALL(&filter);
2205 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
2207 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2208 sizeof(struct icmp6_filter));
2210 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2211 &val, sizeof(val)) < 0) {
2213 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2219 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2220 &val, sizeof(val)) < 0) {
2222 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2229 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2231 ipv6_addr_solict_mult(addr, &solicit);
2232 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2233 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2235 data->channel = g_io_channel_unix_new(sk);
2236 g_io_channel_set_close_on_unref(data->channel, TRUE);
2238 g_io_channel_set_encoding(data->channel, NULL, NULL);
2239 g_io_channel_set_buffered(data->channel, FALSE);
2241 data->watch_id = g_io_add_watch(data->channel,
2242 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2243 icmpv6_nd_event, data);
2245 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2246 (unsigned char *)addr, 0, 0);
2248 DBG("Cannot send NS %d/%s", err, strerror(-err));
2255 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2256 unsigned int length)
2258 GSList *prefixes = NULL;
2262 if (length <= sizeof(struct nd_router_advert))
2265 len = length - sizeof(struct nd_router_advert);
2266 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2269 struct nd_opt_prefix_info *pinfo;
2270 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2277 optlen = pos[1] << 3;
2278 if (optlen == 0 || optlen > len)
2282 case ND_OPT_PREFIX_INFORMATION:
2283 pinfo = (struct nd_opt_prefix_info *)pos;
2284 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2285 prefix_str, INET6_ADDRSTRLEN);
2289 str = g_strdup_printf("%s/%d", prefix,
2290 pinfo->nd_opt_pi_prefix_len);
2291 prefixes = g_slist_prepend(prefixes, str);
2293 DBG("prefix %s", str);
2305 static int get_dest_addr(int family, int index, char *buf, int len)
2311 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2315 memset(&ifr, 0, sizeof(ifr));
2316 ifr.ifr_ifindex = index;
2318 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2319 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2324 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2325 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2330 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2336 DBG("index %d %s", index, ifr.ifr_name);
2338 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2339 connman_error("Get destination address failed (%s)",
2349 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2352 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2359 if (!inet_ntop(family, addr, buf, len)) {
2360 DBG("error %d/%s", errno, strerror(errno));
2367 int connman_inet_get_dest_addr(int index, char **dest)
2369 char addr[INET_ADDRSTRLEN];
2372 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2376 *dest = g_strdup(addr);
2378 DBG("destination %s", *dest);
2383 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2385 char addr[INET6_ADDRSTRLEN];
2388 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2392 *dest = g_strdup(addr);
2394 DBG("destination %s", *dest);
2399 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2402 int rcvbuf = 1024 * 4;
2404 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2406 connman_error("Can not open netlink socket: %s",
2411 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2412 sizeof(sndbuf)) < 0) {
2413 connman_error("SO_SNDBUF: %s", strerror(errno));
2417 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2418 sizeof(rcvbuf)) < 0) {
2419 connman_error("SO_RCVBUF: %s", strerror(errno));
2423 memset(&rth->local, 0, sizeof(rth->local));
2424 rth->local.nl_family = AF_NETLINK;
2425 rth->local.nl_groups = 0;
2427 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2428 sizeof(rth->local)) < 0) {
2429 connman_error("Can not bind netlink socket: %s",
2434 rth->seq = time(NULL);
2436 DBG("fd %d", rth->fd);
2441 struct inet_rtnl_cb_data {
2442 GIOChannel *channel;
2443 __connman_inet_rtnl_cb_t callback;
2446 struct __connman_inet_rtnl_handle *rtnl;
2450 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2452 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2454 if (data->channel) {
2455 g_io_channel_shutdown(data->channel, TRUE, NULL);
2456 g_io_channel_unref(data->channel);
2457 data->channel = NULL;
2460 DBG("data %p", data);
2462 if (data->rtnl_timeout > 0)
2463 g_source_remove(data->rtnl_timeout);
2465 if (data->watch_id > 0)
2466 g_source_remove(data->watch_id);
2469 __connman_inet_rtnl_close(rth);
2476 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2478 struct inet_rtnl_cb_data *data = user_data;
2480 DBG("user data %p", user_data);
2486 data->callback(NULL, data->user_data);
2488 data->rtnl_timeout = 0;
2489 inet_rtnl_cleanup(data);
2493 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2495 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2496 struct nlmsghdr *h = NULL;
2497 struct sockaddr_nl nladdr;
2498 socklen_t addr_len = sizeof(nladdr);
2499 unsigned char buf[4096];
2504 memset(buf, 0, sizeof(buf));
2505 memset(&nladdr, 0, sizeof(nladdr));
2507 fd = g_io_channel_unix_get_fd(chan);
2509 status = recvfrom(fd, buf, sizeof(buf), 0,
2510 (struct sockaddr *) &nladdr, &addr_len);
2512 if (errno == EINTR || errno == EAGAIN)
2521 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2522 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2529 struct nlmsgerr *err;
2533 if (!NLMSG_OK(h, len))
2536 if (h->nlmsg_seq != rth->seq) {
2538 DBG("skip %d/%d len %d", rth->seq,
2539 h->nlmsg_seq, h->nlmsg_len);
2541 len -= h->nlmsg_len;
2542 ptr += h->nlmsg_len;
2546 switch (h->nlmsg_type) {
2552 err = (struct nlmsgerr *)NLMSG_DATA(h);
2553 connman_error("RTNETLINK answers %s (%d)",
2554 strerror(-err->error), -err->error);
2561 if (h->nlmsg_seq == rth->seq) {
2562 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2564 rtnl_data->callback(h, rtnl_data->user_data);
2566 inet_rtnl_cleanup(rtnl_data);
2572 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2576 struct inet_rtnl_cb_data *rtnl_data = user_data;
2580 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2583 ret = inet_rtnl_recv(chan, rtnl_data);
2588 rtnl_data->callback(NULL, rtnl_data->user_data);
2589 inet_rtnl_cleanup(rtnl_data);
2593 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2594 struct nlmsghdr *n, int timeout,
2595 __connman_inet_rtnl_cb_t callback, void *user_data)
2597 struct sockaddr_nl nladdr;
2598 struct inet_rtnl_cb_data *data;
2601 memset(&nladdr, 0, sizeof(nladdr));
2602 nladdr.nl_family = AF_NETLINK;
2604 n->nlmsg_seq = ++rtnl->seq;
2607 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2611 data->callback = callback;
2612 data->user_data = user_data;
2614 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2615 inet_rtnl_timeout_cb, data);
2617 data->channel = g_io_channel_unix_new(rtnl->fd);
2619 g_io_channel_set_encoding(data->channel, NULL, NULL);
2620 g_io_channel_set_buffered(data->channel, FALSE);
2622 data->watch_id = g_io_add_watch(data->channel,
2623 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2624 inet_rtnl_event, data);
2626 n->nlmsg_flags |= NLM_F_ACK;
2628 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2629 (struct sockaddr *) &nladdr, sizeof(nladdr));
2630 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2632 connman_error("Can not talk to rtnetlink err %d %s",
2633 -errno, strerror(errno));
2637 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2638 connman_error("Sent %d bytes, msg truncated", err);
2645 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2647 DBG("handle %p", rth);
2655 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2658 int len = RTA_LENGTH(4);
2661 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2662 DBG("Error! max allowed bound %zd exceeded", maxlen);
2665 rta = NLMSG_TAIL(n);
2666 rta->rta_type = type;
2668 memcpy(RTA_DATA(rta), &data, 4);
2669 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2674 static int parse_rtattr(struct rtattr *tb[], int max,
2675 struct rtattr *rta, int len)
2677 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2678 while (RTA_OK(rta, len)) {
2679 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2680 tb[rta->rta_type] = rta;
2681 rta = RTA_NEXT(rta, len);
2684 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2689 struct get_route_cb_data {
2690 connman_inet_addr_cb_t callback;
2694 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2696 struct get_route_cb_data *data = user_data;
2697 struct rtattr *tb[RTA_MAX+1];
2698 struct rtmsg *r = NLMSG_DATA(answer);
2699 int len, index = -1;
2701 const char *addr = NULL;
2703 DBG("answer %p data %p", answer, user_data);
2708 len = answer->nlmsg_len;
2710 if (answer->nlmsg_type != RTM_NEWROUTE &&
2711 answer->nlmsg_type != RTM_DELROUTE) {
2712 connman_error("Not a route: %08x %08x %08x",
2713 answer->nlmsg_len, answer->nlmsg_type,
2714 answer->nlmsg_flags);
2718 len -= NLMSG_LENGTH(sizeof(*r));
2720 connman_error("BUG: wrong nlmsg len %d", len);
2724 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2727 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2729 if (tb[RTA_GATEWAY])
2730 addr = inet_ntop(r->rtm_family,
2731 RTA_DATA(tb[RTA_GATEWAY]),
2732 abuf, sizeof(abuf));
2734 DBG("addr %s index %d user %p", addr, index, data->user_data);
2737 if (data && data->callback)
2738 data->callback(addr, index, data->user_data);
2744 * Return the interface index that contains route to host.
2746 int __connman_inet_get_route(const char *dest_address,
2747 connman_inet_addr_cb_t callback, void *user_data)
2749 struct get_route_cb_data *data;
2750 struct addrinfo hints, *rp;
2751 struct __connman_inet_rtnl_handle *rth;
2754 DBG("dest %s", dest_address);
2759 memset(&hints, 0, sizeof(hints));
2760 hints.ai_family = AF_UNSPEC;
2761 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2763 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2767 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2773 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2774 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2775 rth->req.n.nlmsg_type = RTM_GETROUTE;
2776 rth->req.u.r.rt.rtm_family = rp->ai_family;
2777 rth->req.u.r.rt.rtm_table = 0;
2778 rth->req.u.r.rt.rtm_protocol = 0;
2779 rth->req.u.r.rt.rtm_scope = 0;
2780 rth->req.u.r.rt.rtm_type = 0;
2781 rth->req.u.r.rt.rtm_src_len = 0;
2782 rth->req.u.r.rt.rtm_tos = 0;
2784 if (rp->ai_family == AF_INET) {
2785 struct sockaddr_in *sin = (struct sockaddr_in *)rp->ai_addr;
2787 rth->req.u.r.rt.rtm_dst_len = 32;
2788 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2789 RTA_DST, &sin->sin_addr, sizeof(sin->sin_addr));
2790 } else if (rp->ai_family == AF_INET6) {
2791 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rp->ai_addr;
2793 rth->req.u.r.rt.rtm_dst_len = 128;
2794 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2795 RTA_DST, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
2800 err = __connman_inet_rtnl_open(rth);
2804 data = g_try_malloc(sizeof(struct get_route_cb_data));
2810 data->callback = callback;
2811 data->user_data = user_data;
2813 #define GET_ROUTE_TIMEOUT 2
2814 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2815 get_route_cb, data);
2824 __connman_inet_rtnl_close(rth);
2831 int connman_inet_check_ipaddress(const char *host)
2833 struct addrinfo hints;
2834 struct addrinfo *addr;
2837 memset(&hints, 0, sizeof(struct addrinfo));
2838 hints.ai_flags = AI_NUMERICHOST;
2841 result = getaddrinfo(host, NULL, &hints, &addr);
2843 result = addr->ai_family;
2850 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2851 bool connman_inet_check_hostname(const char *ptr, size_t len)
2856 * Not empty or complete length not over 255 characters.
2858 if ((len == 0) || (len > 256))
2862 * Consists of [[:alnum:]-]+ labels separated by [.]
2863 * a [_] is against RFC but seems to be "widely used"
2865 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2867 if ((*p == '-') || (*p == '_')) {
2869 * Not allowed at begin or end of a label.
2871 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2874 } else if (*p == '.') {
2876 * Each label has to be 1-63 characters;
2877 * we allow [.] at the end ('foo.bar.')
2881 if ((d <= 0) || (d >= 64))
2884 ptr = p + 1; /* Jump to the next label */
2886 } else if (isalnum((unsigned char)*p) == 0) {
2888 * Also numbers at the begin are fine
2897 char **__connman_inet_get_running_interfaces(void)
2901 struct ifreq *ifr = NULL;
2902 int sk, i, numif, count = 0;
2904 memset(&ifc, 0, sizeof(ifc));
2906 sk = socket(AF_INET, SOCK_DGRAM, 0);
2910 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2914 * Allocate some extra bytes just in case there will
2915 * be new interfaces added between two SIOCGIFCONF
2918 ifr = g_try_malloc0(ifc.ifc_len * 2);
2924 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2927 numif = ifc.ifc_len / sizeof(struct ifreq);
2929 result = g_try_malloc0((numif + 1) * sizeof(char *));
2935 for (i = 0; i < numif; i++) {
2936 struct ifreq *r = &ifr[i];
2937 struct in6_addr *addr6;
2941 * Note that we do not return loopback interfaces here as they
2942 * are not needed for our purposes.
2944 switch (r->ifr_addr.sa_family) {
2946 addr4 = ntohl(((struct sockaddr_in *)
2947 &r->ifr_addr)->sin_addr.s_addr);
2948 if (((addr4 & 0xff000000) >> 24) == 127)
2952 addr6 = &((struct sockaddr_in6 *)
2953 &r->ifr_addr)->sin6_addr;
2954 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2959 result[count++] = g_strdup(r->ifr_name);
2964 if (count < numif) {
2965 char **prev_result = result;
2966 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2968 g_free(prev_result);
2981 bool connman_inet_is_ipv6_supported()
2985 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2993 int __connman_inet_get_interface_address(int index, int family, void *address)
2995 struct ifaddrs *ifaddr, *ifa;
2997 char name[IF_NAMESIZE];
2999 if (!if_indextoname(index, name))
3002 DBG("index %d interface %s", index, name);
3004 if (getifaddrs(&ifaddr) < 0) {
3006 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
3010 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3014 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
3015 ifa->ifa_addr->sa_family == family) {
3016 if (family == AF_INET) {
3017 struct sockaddr_in *in4 = (struct sockaddr_in *)
3019 if (in4->sin_addr.s_addr == INADDR_ANY)
3021 memcpy(address, &in4->sin_addr,
3022 sizeof(struct in_addr));
3023 } else if (family == AF_INET6) {
3024 struct sockaddr_in6 *in6 =
3025 (struct sockaddr_in6 *)ifa->ifa_addr;
3026 if (memcmp(&in6->sin6_addr, &in6addr_any,
3027 sizeof(struct in6_addr)) == 0)
3029 memcpy(address, &in6->sin6_addr,
3030 sizeof(struct in6_addr));
3043 freeifaddrs(ifaddr);
3047 int __connman_inet_get_interface_mac_address(int index, uint8_t *mac_address)
3053 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3055 DBG("Open socket error");
3059 memset(&ifr, 0, sizeof(ifr));
3060 ifr.ifr_ifindex = index;
3062 err = ioctl(sk, SIOCGIFNAME, &ifr);
3064 DBG("Get interface name error");
3068 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
3070 DBG("Get MAC address error");
3074 memcpy(mac_address, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
3082 static int iprule_modify(int cmd, int family, uint32_t table_id,
3085 struct __connman_inet_rtnl_handle rth;
3088 memset(&rth, 0, sizeof(rth));
3090 rth.req.n.nlmsg_type = cmd;
3091 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3092 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
3093 rth.req.u.r.rt.rtm_family = family;
3094 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3095 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3096 rth.req.u.r.rt.rtm_table = table_id;
3097 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
3098 rth.req.u.r.rt.rtm_flags = 0;
3100 if (cmd == RTM_NEWRULE) {
3101 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
3102 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3105 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3106 FRA_FWMARK, fwmark);
3108 if (table_id < 256) {
3109 rth.req.u.r.rt.rtm_table = table_id;
3111 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3112 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3113 FRA_TABLE, table_id);
3116 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
3117 rth.req.u.r.rt.rtm_family = AF_INET;
3119 ret = __connman_inet_rtnl_open(&rth);
3123 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3126 __connman_inet_rtnl_close(&rth);
3131 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3133 /* ip rule add fwmark 9876 table 1234 */
3135 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
3138 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3140 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
3143 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
3144 const char *gateway, unsigned char prefixlen)
3146 struct __connman_inet_rtnl_handle rth;
3147 unsigned char buf[sizeof(struct in6_addr)];
3149 int family = connman_inet_check_ipaddress(gateway);
3152 DBG("gateway %s/%u table %u", gateway, prefixlen, table_id);
3166 struct in_addr ipv4_subnet_addr, ipv4_mask;
3168 memset(&ipv4_subnet_addr, 0, sizeof(ipv4_subnet_addr));
3169 ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
3170 ipv4_subnet_addr.s_addr = inet_addr(gateway);
3171 ipv4_subnet_addr.s_addr &= ipv4_mask.s_addr;
3173 dst = g_strdup(inet_ntoa(ipv4_subnet_addr));
3176 ret = inet_pton(family, dst ? dst : gateway, buf);
3181 memset(&rth, 0, sizeof(rth));
3183 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3184 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
3185 rth.req.n.nlmsg_type = cmd;
3186 rth.req.u.r.rt.rtm_family = family;
3187 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
3188 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
3189 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3190 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3191 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3192 rth.req.u.r.rt.rtm_dst_len = prefixlen;
3194 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req),
3195 prefixlen > 0 ? RTA_DST : RTA_GATEWAY, buf, len);
3197 if (table_id < 256) {
3198 rth.req.u.r.rt.rtm_table = table_id;
3200 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3201 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3202 RTA_TABLE, table_id);
3205 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3208 ret = __connman_inet_rtnl_open(&rth);
3212 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3215 __connman_inet_rtnl_close(&rth);
3220 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
3221 const char *gateway)
3223 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
3225 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 0);
3228 int __connman_inet_add_subnet_to_table(uint32_t table_id, int ifindex,
3229 const char *gateway, unsigned char prefixlen)
3231 /* ip route add 1.2.3.4/24 dev eth0 table 1234 */
3232 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, prefixlen);
3235 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
3236 const char *gateway)
3238 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
3240 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 0);
3243 int __connman_inet_del_subnet_from_table(uint32_t table_id, int ifindex,
3244 const char *gateway, unsigned char prefixlen)
3246 /* ip route del 1.2.3.4/24 dev eth0 table 1234 */
3247 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, prefixlen);
3250 int __connman_inet_get_interface_ll_address(int index, int family,
3253 struct ifaddrs *ifaddr, *ifa;
3255 char name[IF_NAMESIZE];
3257 if (!if_indextoname(index, name))
3260 DBG("index %d interface %s", index, name);
3262 if (getifaddrs(&ifaddr) < 0) {
3264 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
3268 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3272 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
3273 ifa->ifa_addr->sa_family == family) {
3274 if (family == AF_INET) {
3275 struct sockaddr_in *in4 = (struct sockaddr_in *)
3277 if (in4->sin_addr.s_addr == INADDR_ANY)
3279 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
3280 ((in_addr_t) 0xa9fe0000))
3282 memcpy(address, &in4->sin_addr,
3283 sizeof(struct in_addr));
3284 } else if (family == AF_INET6) {
3285 struct sockaddr_in6 *in6 =
3286 (struct sockaddr_in6 *)ifa->ifa_addr;
3287 if (memcmp(&in6->sin6_addr, &in6addr_any,
3288 sizeof(struct in6_addr)) == 0)
3290 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
3293 memcpy(address, &in6->sin6_addr,
3294 sizeof(struct in6_addr));
3306 freeifaddrs(ifaddr);
3310 int __connman_inet_get_address_netmask(int ifindex,
3311 struct sockaddr_in *address,
3312 struct sockaddr_in *netmask)
3314 int sk, ret = -EINVAL;
3317 DBG("index %d", ifindex);
3319 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3323 memset(&ifr, 0, sizeof(ifr));
3324 ifr.ifr_ifindex = ifindex;
3326 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3329 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3332 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3333 sizeof(struct sockaddr_in));
3335 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3338 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3339 sizeof(struct sockaddr_in));
3347 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3348 struct in_addr *addr)
3352 char addrstr[INET_ADDRSTRLEN];
3353 struct in_addr taddr;
3354 GError *error = NULL;
3355 char *cmdline = NULL;
3358 char **pnpent = NULL;
3363 cmdline_file = "/proc/cmdline";
3365 pnp_file = "/proc/net/pnp";
3368 addr->s_addr = INADDR_NONE;
3370 if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3371 connman_error("%s: Cannot read %s %s\n", __func__,
3372 cmdline_file, error->message);
3376 if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3377 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3378 connman_error("%s: Cannot read %s %s\n", __func__,
3379 pnp_file, error->message);
3385 len = strlen(cmdline);
3390 /* remove newline */
3391 if (cmdline[len - 1] == '\n')
3392 cmdline[--len] = '\0';
3394 /* split in arguments (separated by space) */
3395 args = g_strsplit(cmdline, " ", 0);
3397 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3402 /* split in entries (by newlines) */
3403 pnpent = g_strsplit(pnp, "\n", 0);
3405 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3410 /* first find root argument */
3411 for (pp = args; *pp; pp++) {
3412 if (!strcmp(*pp, "root=/dev/nfs"))
3415 /* no rootnfs found */
3419 /* locate nfsroot argument */
3420 for (pp = args; *pp; pp++) {
3421 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3424 /* no nfsroot argument found */
3428 /* determine if nfsroot server is provided */
3429 nfsargs = strchr(*pp, '=');
3434 /* find whether serverip is present */
3435 s = strchr(nfsargs, ':');
3440 /* no serverip, use bootserver */
3441 for (pp = pnpent; *pp; pp++) {
3442 if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3445 /* no bootserver found */
3448 s = *pp + strlen("bootserver ");
3452 /* copy to addr string buffer */
3453 if (len >= sizeof(addrstr)) {
3454 connman_error("%s: Bad server\n", __func__);
3457 memcpy(addrstr, s, len);
3458 addrstr[len] = '\0';
3460 err = inet_pton(AF_INET, addrstr, addr);
3462 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3474 g_error_free(error);
3481 /* get interface out of which peer is reachable (IPv4 only) */
3482 static int get_peer_iface(struct in_addr *addr, char *ifname)
3484 struct ifaddrs *ifaddr, *ifa;
3485 struct sockaddr_in saddr, *ifsaddr;
3490 /* Obtain address(es) matching host/port */
3491 err = getifaddrs(&ifaddr);
3493 connman_error("%s: getifaddrs() failed %d (%s)\n",
3494 __func__, errno, strerror(errno));
3498 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3500 connman_error("%s: socket() failed %d (%s)\n",
3501 __func__, errno, strerror(errno));
3505 memset(&saddr, 0, sizeof(saddr));
3506 saddr.sin_family = AF_INET;
3507 saddr.sin_port = 0; /* any port */
3508 saddr.sin_addr = *addr;
3510 /* no need to bind, connect will select iface */
3511 err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3513 connman_error("%s: connect() failed: %d (%s)\n",
3514 __func__, errno, strerror(errno));
3518 socklen = sizeof(saddr);
3519 err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3521 connman_error("%s: getsockname() failed: %d (%s)\n",
3522 __func__, errno, strerror(errno));
3527 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3531 /* only IPv4 address */
3532 if (ifa->ifa_addr->sa_family != AF_INET)
3535 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3537 /* match address? */
3538 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3545 strcpy(ifname, ifa->ifa_name);
3551 freeifaddrs(ifaddr);
3556 bool __connman_inet_isrootnfs_device(const char *devname)
3558 struct in_addr addr;
3559 char ifname[IFNAMSIZ];
3561 return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3562 get_peer_iface(&addr, ifname) == 0 &&
3563 strcmp(devname, ifname) == 0;
3566 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3571 GError *error = NULL;
3573 char **pnpent = NULL;
3574 char **nameservers = NULL;
3577 pnp_file = "/proc/net/pnp";
3579 if (!g_file_test(pnp_file, G_FILE_TEST_EXISTS))
3582 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3583 connman_error("%s: Cannot read %s %s\n", __func__,
3584 pnp_file, error->message);
3588 /* split in entries (by newlines) */
3589 pnpent = g_strsplit(pnp, "\n", 0);
3591 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3597 * Perform two passes to retrieve a char ** array of
3598 * nameservers that are not 0.0.0.0
3600 * The first pass counts them, the second fills in the
3605 for (pass = 1; pass <= 2; pass++) {
3607 /* at the start of the second pass allocate */
3609 nameservers = g_new(char *, count + 1);
3612 for (pp = pnpent; *pp; pp++) {
3613 /* match 'nameserver ' at the start of each line */
3614 if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3617 /* compare it against 0.0.0.0 */
3618 s = *pp + strlen("nameserver ");
3619 if (!strcmp(s, "0.0.0.0"))
3622 /* on second pass fill in array */
3624 nameservers[count] = g_strdup(s);
3628 /* no nameservers? */
3632 /* and terminate char ** array with NULL */
3634 nameservers[count] = NULL;
3642 g_error_free(error);