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
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <linux/sockios.h>
39 #include <arpa/inet.h>
40 #include <net/route.h>
41 #include <net/ethernet.h>
43 #include <net/if_arp.h>
44 #include <netinet/icmp6.h>
46 #include <linux/if_tun.h>
49 #include <linux/fib_rules.h>
52 #include <gdhcp/gdhcp.h>
54 #define NLMSG_TAIL(nmsg) \
55 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
56 NLMSG_ALIGN((nmsg)->nlmsg_len)))
58 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
59 int type, const void *data, size_t data_length)
64 length = RTA_LENGTH(data_length);
66 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
71 rta->rta_len = length;
72 memcpy(RTA_DATA(rta), data, data_length);
73 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
78 int __connman_inet_modify_address(int cmd, int flags,
79 int index, int family,
82 unsigned char prefixlen,
83 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", cmd, flags, index, family,
99 address, peer, prefixlen, broadcast);
104 if (family != AF_INET && family != AF_INET6)
107 memset(&request, 0, sizeof(request));
109 header = (struct nlmsghdr *)request;
110 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
111 header->nlmsg_type = cmd;
112 header->nlmsg_flags = NLM_F_REQUEST | flags;
113 header->nlmsg_seq = 1;
115 ifaddrmsg = NLMSG_DATA(header);
116 ifaddrmsg->ifa_family = family;
117 ifaddrmsg->ifa_prefixlen = prefixlen;
118 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
119 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
120 ifaddrmsg->ifa_index = index;
122 if (family == AF_INET) {
123 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
127 inet_pton(AF_INET, broadcast, &ipv4_bcast);
129 ipv4_bcast.s_addr = ipv4_addr.s_addr |
130 htonl(0xfffffffflu >> prefixlen);
133 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
136 err = __connman_inet_rtnl_addattr_l(header,
145 err = __connman_inet_rtnl_addattr_l(header,
153 err = __connman_inet_rtnl_addattr_l(header,
161 } else if (family == AF_INET6) {
162 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
165 err = __connman_inet_rtnl_addattr_l(header,
174 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
178 memset(&nl_addr, 0, sizeof(nl_addr));
179 nl_addr.nl_family = AF_NETLINK;
181 if ((err = sendto(sk, request, header->nlmsg_len, 0,
182 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
193 #if defined TIZEN_EXT_WIFI_MESH
194 char *connman_inet_ifaddr(const char *name)
197 struct ether_addr eth;
201 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
205 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
207 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
217 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
218 snprintf(str, 13, "%02x%02x%02x%02x%02x%02x",
219 eth.ether_addr_octet[0],
220 eth.ether_addr_octet[1],
221 eth.ether_addr_octet[2],
222 eth.ether_addr_octet[3],
223 eth.ether_addr_octet[4],
224 eth.ether_addr_octet[5]);
229 char *connman_inet_ifname2addr(const char *name)
232 struct ether_addr eth;
236 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
240 strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
242 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
252 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
253 snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
254 eth.ether_addr_octet[0],
255 eth.ether_addr_octet[1],
256 eth.ether_addr_octet[2],
257 eth.ether_addr_octet[3],
258 eth.ether_addr_octet[4],
259 eth.ether_addr_octet[5]);
265 int connman_inet_ifindex(const char *name)
273 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
277 memset(&ifr, 0, sizeof(ifr));
278 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
280 err = ioctl(sk, SIOCGIFINDEX, &ifr);
287 return ifr.ifr_ifindex;
290 char *connman_inet_ifname(int index)
298 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
302 memset(&ifr, 0, sizeof(ifr));
303 ifr.ifr_ifindex = index;
305 err = ioctl(sk, SIOCGIFNAME, &ifr);
312 return g_strdup(ifr.ifr_name);
315 int connman_inet_ifup(int index)
320 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
324 memset(&ifr, 0, sizeof(ifr));
325 ifr.ifr_ifindex = index;
327 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
332 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
337 if (ifr.ifr_flags & IFF_UP) {
342 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
344 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
357 int connman_inet_ifdown(int index)
359 struct ifreq ifr, addr_ifr;
360 struct sockaddr_in *addr;
363 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
367 memset(&ifr, 0, sizeof(ifr));
368 ifr.ifr_ifindex = index;
370 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
375 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
380 memset(&addr_ifr, 0, sizeof(addr_ifr));
381 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
382 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
383 addr->sin_family = AF_INET;
384 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
385 connman_warn("Could not clear IPv4 address index %d", index);
387 if (!(ifr.ifr_flags & IFF_UP)) {
392 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
394 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
405 #if defined TIZEN_EXT
406 void connman_inet_update_device_ident(struct connman_device *device)
409 enum connman_device_type type;
410 char *ident = NULL, *addr = NULL;
412 index = connman_device_get_index(device);
413 type = connman_device_get_type(device);
416 case CONNMAN_DEVICE_TYPE_UNKNOWN:
418 case CONNMAN_DEVICE_TYPE_ETHERNET:
419 case CONNMAN_DEVICE_TYPE_GADGET:
420 case CONNMAN_DEVICE_TYPE_WIFI:
421 addr = index2addr(index);
422 ident = index2ident(index, NULL);
424 case CONNMAN_DEVICE_TYPE_CELLULAR:
425 ident = index2ident(index, NULL);
427 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
428 case CONNMAN_DEVICE_TYPE_GPS:
429 case CONNMAN_DEVICE_TYPE_VENDOR:
434 connman_device_set_ident(device, ident);
439 connman_device_set_string(device, "Address", addr);
446 struct in6_addr ifr6_addr;
447 __u32 ifr6_prefixlen;
448 unsigned int ifr6_ifindex;
451 int connman_inet_set_ipv6_address(int index,
452 struct connman_ipaddress *ipaddress)
455 unsigned char prefix_len;
458 if (!ipaddress->local)
461 prefix_len = ipaddress->prefixlen;
462 address = ipaddress->local;
464 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
466 err = __connman_inet_modify_address(RTM_NEWADDR,
467 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
468 address, NULL, prefix_len, NULL);
470 connman_error("%s: %s", __func__, strerror(-err));
477 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
480 unsigned char prefix_len;
481 const char *address, *broadcast, *peer;
483 if (!ipaddress->local)
486 prefix_len = ipaddress->prefixlen;
487 address = ipaddress->local;
488 broadcast = ipaddress->broadcast;
489 peer = ipaddress->peer;
491 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
493 err = __connman_inet_modify_address(RTM_NEWADDR,
494 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
495 address, peer, prefix_len, broadcast);
497 connman_error("%s: %s", __func__, strerror(-err));
504 int connman_inet_clear_ipv6_address(int index, const char *address,
509 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
514 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
515 address, NULL, prefix_len, NULL);
517 connman_error("%s: %s", __func__, strerror(-err));
524 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
527 unsigned char prefix_len;
528 const char *address, *broadcast, *peer;
530 prefix_len = ipaddress->prefixlen;
531 address = ipaddress->local;
532 broadcast = ipaddress->broadcast;
533 peer = ipaddress->peer;
535 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
536 address, prefix_len, peer, broadcast);
541 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
542 address, peer, prefix_len, broadcast);
544 connman_error("%s: %s", __func__, strerror(-err));
551 int connman_inet_add_host_route(int index, const char *host,
554 return connman_inet_add_network_route(index, host, gateway, NULL);
557 int connman_inet_del_host_route(int index, const char *host)
559 return connman_inet_del_network_route(index, host);
562 int connman_inet_add_network_route(int index, const char *host,
568 struct sockaddr_in addr;
571 DBG("index %d host %s gateway %s netmask %s", index,
572 host, gateway, netmask);
574 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
580 memset(&ifr, 0, sizeof(ifr));
581 ifr.ifr_ifindex = index;
583 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
589 DBG("ifname %s", ifr.ifr_name);
591 memset(&rt, 0, sizeof(rt));
592 rt.rt_flags = RTF_UP;
594 rt.rt_flags |= RTF_GATEWAY;
596 rt.rt_flags |= RTF_HOST;
598 memset(&addr, 0, sizeof(addr));
599 addr.sin_family = AF_INET;
600 addr.sin_addr.s_addr = inet_addr(host);
601 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
603 memset(&addr, 0, sizeof(addr));
604 addr.sin_family = AF_INET;
606 addr.sin_addr.s_addr = inet_addr(gateway);
608 addr.sin_addr.s_addr = INADDR_ANY;
609 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
611 memset(&addr, 0, sizeof(addr));
612 addr.sin_family = AF_INET;
613 addr.sin_addr.s_addr = INADDR_ANY;
615 addr.sin_addr.s_addr = inet_addr(netmask);
617 addr.sin_addr.s_addr = INADDR_ANY;
618 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
620 rt.rt_dev = ifr.ifr_name;
622 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
629 connman_error("Adding host route failed (%s)",
635 int connman_inet_del_network_route(int index, const char *host)
639 struct sockaddr_in addr;
642 DBG("index %d host %s", index, host);
644 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
650 memset(&ifr, 0, sizeof(ifr));
651 ifr.ifr_ifindex = index;
653 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
659 DBG("ifname %s", ifr.ifr_name);
661 memset(&rt, 0, sizeof(rt));
662 rt.rt_flags = RTF_UP | RTF_HOST;
664 memset(&addr, 0, sizeof(addr));
665 addr.sin_family = AF_INET;
666 addr.sin_addr.s_addr = inet_addr(host);
667 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
669 rt.rt_dev = ifr.ifr_name;
671 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
678 connman_error("Deleting host route failed (%s)",
684 int connman_inet_del_ipv6_network_route(int index, const char *host,
685 unsigned char prefix_len)
690 DBG("index %d host %s", index, host);
695 memset(&rt, 0, sizeof(rt));
697 rt.rtmsg_dst_len = prefix_len;
699 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
704 rt.rtmsg_flags = RTF_UP | RTF_HOST;
707 rt.rtmsg_ifindex = index;
709 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
715 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
722 connman_error("Del IPv6 host route error (%s)",
728 int connman_inet_del_ipv6_host_route(int index, const char *host)
730 return connman_inet_del_ipv6_network_route(index, host, 128);
733 int connman_inet_add_ipv6_network_route(int index, const char *host,
735 unsigned char prefix_len)
740 DBG("index %d host %s gateway %s", index, host, gateway);
745 memset(&rt, 0, sizeof(rt));
747 rt.rtmsg_dst_len = prefix_len;
749 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
754 rt.rtmsg_flags = RTF_UP | RTF_HOST;
757 rt.rtmsg_flags |= RTF_GATEWAY;
758 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
762 rt.rtmsg_ifindex = index;
764 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
770 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
777 connman_error("Set IPv6 host route error (%s)",
783 int connman_inet_add_ipv6_host_route(int index, const char *host,
786 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
789 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
794 DBG("index %d gateway %s", index, gateway);
799 memset(&rt, 0, sizeof(rt));
801 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
806 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
808 rt.rtmsg_dst_len = 0;
809 rt.rtmsg_ifindex = index;
811 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
817 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
824 connman_error("Clear default IPv6 gateway error (%s)",
830 int connman_inet_set_gateway_interface(int index)
834 struct sockaddr_in addr;
837 DBG("index %d", index);
839 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
845 memset(&ifr, 0, sizeof(ifr));
846 ifr.ifr_ifindex = index;
848 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
854 DBG("ifname %s", ifr.ifr_name);
856 memset(&rt, 0, sizeof(rt));
857 rt.rt_flags = RTF_UP;
859 memset(&addr, 0, sizeof(addr));
860 addr.sin_family = AF_INET;
861 addr.sin_addr.s_addr = INADDR_ANY;
863 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
864 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
865 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
867 rt.rt_dev = ifr.ifr_name;
869 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
876 connman_error("Setting default interface route failed (%s)",
882 int connman_inet_set_ipv6_gateway_interface(int index)
886 struct sockaddr_in6 addr;
887 const struct in6_addr any = IN6ADDR_ANY_INIT;
890 DBG("index %d", index);
892 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
898 memset(&ifr, 0, sizeof(ifr));
899 ifr.ifr_ifindex = index;
901 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
907 DBG("ifname %s", ifr.ifr_name);
909 memset(&rt, 0, sizeof(rt));
910 rt.rt_flags = RTF_UP;
912 memset(&addr, 0, sizeof(addr));
913 addr.sin6_family = AF_INET6;
914 addr.sin6_addr = any;
916 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
917 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
918 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
920 rt.rt_dev = ifr.ifr_name;
922 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
929 connman_error("Setting default interface route failed (%s)",
935 int connman_inet_clear_gateway_address(int index, const char *gateway)
939 struct sockaddr_in addr;
942 DBG("index %d gateway %s", index, gateway);
944 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
950 memset(&ifr, 0, sizeof(ifr));
951 ifr.ifr_ifindex = index;
953 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
959 DBG("ifname %s", ifr.ifr_name);
961 memset(&rt, 0, sizeof(rt));
962 rt.rt_flags = RTF_UP | RTF_GATEWAY;
964 memset(&addr, 0, sizeof(addr));
965 addr.sin_family = AF_INET;
966 addr.sin_addr.s_addr = INADDR_ANY;
967 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
969 memset(&addr, 0, sizeof(addr));
970 addr.sin_family = AF_INET;
971 addr.sin_addr.s_addr = inet_addr(gateway);
972 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
974 memset(&addr, 0, sizeof(addr));
975 addr.sin_family = AF_INET;
976 addr.sin_addr.s_addr = INADDR_ANY;
977 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
979 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
986 connman_error("Removing default gateway route failed (%s)",
992 int connman_inet_clear_gateway_interface(int index)
996 struct sockaddr_in addr;
999 DBG("index %d", index);
1001 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1007 memset(&ifr, 0, sizeof(ifr));
1008 ifr.ifr_ifindex = index;
1010 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1016 DBG("ifname %s", ifr.ifr_name);
1018 memset(&rt, 0, sizeof(rt));
1019 rt.rt_flags = RTF_UP;
1021 memset(&addr, 0, sizeof(addr));
1022 addr.sin_family = AF_INET;
1023 addr.sin_addr.s_addr = INADDR_ANY;
1025 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1026 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1027 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1029 rt.rt_dev = ifr.ifr_name;
1031 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1038 connman_error("Removing default interface route failed (%s)",
1044 int connman_inet_clear_ipv6_gateway_interface(int index)
1048 struct sockaddr_in6 addr;
1049 const struct in6_addr any = IN6ADDR_ANY_INIT;
1052 DBG("index %d", index);
1054 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1060 memset(&ifr, 0, sizeof(ifr));
1061 ifr.ifr_ifindex = index;
1063 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1069 DBG("ifname %s", ifr.ifr_name);
1071 memset(&rt, 0, sizeof(rt));
1072 rt.rt_flags = RTF_UP;
1074 memset(&addr, 0, sizeof(addr));
1075 addr.sin6_family = AF_INET6;
1076 addr.sin6_addr = any;
1078 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1079 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1080 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1082 rt.rt_dev = ifr.ifr_name;
1084 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1091 connman_error("Removing default interface route failed (%s)",
1097 bool connman_inet_compare_subnet(int index, const char *host)
1100 struct in_addr _host_addr;
1101 in_addr_t host_addr, netmask_addr, if_addr;
1102 struct sockaddr_in *netmask, *addr;
1105 DBG("host %s", host);
1110 if (inet_aton(host, &_host_addr) == 0)
1112 host_addr = _host_addr.s_addr;
1114 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1118 memset(&ifr, 0, sizeof(ifr));
1119 ifr.ifr_ifindex = index;
1121 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1126 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1131 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1132 netmask_addr = netmask->sin_addr.s_addr;
1134 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1141 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1142 if_addr = addr->sin_addr.s_addr;
1144 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1147 int connman_inet_remove_from_bridge(int index, const char *bridge)
1155 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1161 memset(&ifr, 0, sizeof(ifr));
1162 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1163 ifr.ifr_ifindex = index;
1165 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1172 connman_error("Remove interface from bridge error %s",
1178 int connman_inet_add_to_bridge(int index, const char *bridge)
1186 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1192 memset(&ifr, 0, sizeof(ifr));
1193 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1194 ifr.ifr_ifindex = index;
1196 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1203 connman_error("Add interface to bridge error %s",
1209 int connman_inet_set_mtu(int index, int mtu)
1214 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1218 memset(&ifr, 0, sizeof(ifr));
1219 ifr.ifr_ifindex = index;
1221 err = ioctl(sk, SIOCGIFNAME, &ifr);
1224 err = ioctl(sk, SIOCSIFMTU, &ifr);
1231 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1241 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1245 index = if_nametoindex(tunnel);
1247 err = connman_inet_set_mtu(index, mtu);
1251 memset(&ifr, 0, sizeof(ifr));
1252 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1253 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1260 if ((ifr.ifr_flags ^ flags) & mask) {
1261 ifr.ifr_flags &= ~mask;
1262 ifr.ifr_flags |= mask & flags;
1263 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1265 connman_error("SIOCSIFFLAGS failed: %s",
1274 int connman_inet_create_tunnel(char **iface)
1279 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1282 connman_error("Failed to open /dev/net/tun: %s",
1287 memset(&ifr, 0, sizeof(ifr));
1288 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1290 for (i = 0; i < 256; i++) {
1291 sprintf(ifr.ifr_name, "tun%d", i);
1293 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1298 connman_error("Failed to find available tun device");
1303 *iface = g_strdup(ifr.ifr_name);
1309 * This callback struct is used when sending router and neighbor
1310 * solicitation and advertisement messages.
1313 GIOChannel *channel;
1315 struct sockaddr_in6 addr;
1321 #define CMSG_BUF_LEN 512
1322 #define IN6ADDR_ALL_NODES_MC_INIT \
1323 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1324 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1325 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1327 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1328 static const struct in6_addr in6addr_all_routers_mc =
1329 IN6ADDR_ALL_ROUTERS_MC_INIT;
1331 static void xs_cleanup(struct xs_cb_data *data)
1333 if (data->channel) {
1334 g_io_channel_shutdown(data->channel, TRUE, NULL);
1335 g_io_channel_unref(data->channel);
1336 data->channel = NULL;
1339 if (data->timeout > 0)
1340 g_source_remove(data->timeout);
1342 if (data->watch_id > 0)
1343 g_source_remove(data->watch_id);
1348 static gboolean rs_timeout_cb(gpointer user_data)
1350 struct xs_cb_data *data = user_data;
1352 DBG("user data %p", user_data);
1357 if (data->callback) {
1358 __connman_inet_rs_cb_t cb = data->callback;
1359 cb(NULL, 0, data->user_data);
1367 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1371 unsigned char chdr[CMSG_BUF_LEN];
1372 unsigned char buf[1540];
1373 struct nd_router_advert *hdr;
1374 struct sockaddr_in6 saddr;
1376 __connman_inet_rs_cb_t cb = data->callback;
1380 iov.iov_len = sizeof(buf);
1383 mhdr.msg_name = (void *)&saddr;
1384 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1386 mhdr.msg_iov = &iov;
1387 mhdr.msg_iovlen = 1;
1388 mhdr.msg_control = (void *)chdr;
1389 mhdr.msg_controllen = CMSG_BUF_LEN;
1391 len = recvmsg(fd, &mhdr, 0);
1393 cb(NULL, 0, data->user_data);
1397 #if defined TIZEN_EXT
1398 /* Set Received Source Address from router as IPv6 Gateway Address */
1399 char src_addr[INET6_ADDRSTRLEN];
1400 if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
1404 DBG("Received Source Address %s from router", src_addr);
1406 /* icmpv6_recv() function can be called in two scenarios :
1407 * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
1408 * 2. When __connman_inet_ipv6_send_rs() is called from
1409 * __connman_6to4_probe()
1410 * In the second case it is not required to set DHCPv6 Gateway Address
1411 * as DHCPv6 was not started and network structure was not passed as
1412 * user_data. If it is tried to add Source Address as Gateway Address
1413 * then it will lead to crash because of user_data being ip_address
1414 * instead of network structure. So Adding Gateway Address in case 1st
1417 char *address = data->user_data;
1419 unsigned char buffer[sizeof(struct in6_addr)] = {0, };
1420 /* Checking if user_data is an ip_address */
1421 err = inet_pton(AF_INET, address, buffer);
1422 /* Setting Received Source Address from
1423 * router as Gateway Address */
1425 __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
1427 hdr = (struct nd_router_advert *)buf;
1428 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1429 sizeof(struct nd_router_advert));
1430 if (hdr->nd_ra_code != 0)
1433 cb(hdr, len, data->user_data);
1438 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1441 struct xs_cb_data *xs_data = data;
1445 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1448 fd = g_io_channel_unix_get_fd(chan);
1449 ret = icmpv6_recv(fd, xs_data);
1454 xs_cleanup(xs_data);
1458 /* Adapted from RFC 1071 "C" Implementation Example */
1459 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1460 const void *extra_data, socklen_t extra_datalen)
1462 register unsigned long sum = 0;
1467 /* caller must make sure datalen is even */
1469 addr = (uint16_t *)phdr;
1470 for (i = 0; i < 20; i++)
1474 addr = (uint16_t *)data;
1482 count = extra_datalen;
1483 addr = (uint16_t *)extra_data;
1492 sum = (sum & 0xffff) + (sum >> 16);
1494 return (uint16_t)~sum;
1497 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1498 const struct in6_addr *source,
1499 unsigned char *buf, size_t len, uint16_t lifetime)
1502 struct in6_addr src;
1503 struct in6_addr dst;
1505 uint8_t reserved[3];
1512 struct icmp6_hdr icmp;
1513 struct nd_neighbor_solicit ns;
1514 struct nd_router_solicit rs;
1515 struct nd_router_advert ra;
1520 struct cmsghdr *cmsg;
1521 struct in6_pktinfo *pinfo;
1522 struct sockaddr_in6 dst, src;
1523 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1524 struct iovec iov[2];
1525 int fd, datalen, ret, iovlen = 1;
1526 #if defined TIZEN_EXT
1532 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1536 memset(&frame, 0, sizeof(frame));
1537 memset(&dst, 0, sizeof(dst));
1539 if (type == ND_ROUTER_SOLICIT)
1540 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1541 else if (type == ND_ROUTER_ADVERT) {
1542 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1543 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1544 } else if (type == ND_NEIGHBOR_SOLICIT) {
1545 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1546 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1552 dst.sin6_addr = *dest;
1555 src.sin6_addr = *source;
1557 src.sin6_addr = in6addr_any;
1559 /* Fill in the IPv6 header */
1560 frame.ip.ip6_vfc = 0x60;
1561 frame.ip.ip6_plen = htons(datalen + len);
1562 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1563 frame.ip.ip6_hlim = 255;
1564 frame.ip.ip6_dst = dst.sin6_addr;
1565 frame.ip.ip6_src = src.sin6_addr;
1566 /* all other fields are already set to zero */
1568 /* Prepare pseudo header for csum */
1569 memset(&phdr, 0, sizeof(phdr));
1570 phdr.dst = dst.sin6_addr;
1571 phdr.src = src.sin6_addr;
1572 phdr.plen = htonl(datalen + len);
1573 phdr.nxt = IPPROTO_ICMPV6;
1575 /* Fill in remaining ICMP header fields */
1576 frame.i.icmp.icmp6_type = type;
1577 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1579 iov[0].iov_base = &frame;
1580 iov[0].iov_len = sizeof(frame.ip) + datalen;
1583 iov[1].iov_base = buf;
1584 iov[1].iov_len = len;
1588 dst.sin6_family = AF_INET6;
1589 msgh.msg_name = &dst;
1590 msgh.msg_namelen = sizeof(dst);
1592 msgh.msg_iovlen = iovlen;
1595 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1596 cmsg = (struct cmsghdr *)cbuf;
1597 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1598 pinfo->ipi6_ifindex = oif;
1600 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1601 cmsg->cmsg_level = IPPROTO_IPV6;
1602 cmsg->cmsg_type = IPV6_PKTINFO;
1603 msgh.msg_control = cmsg;
1604 msgh.msg_controllen = cmsg->cmsg_len;
1606 ret = sendmsg(fd, &msgh, 0);
1607 #if defined TIZEN_EXT
1608 DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
1615 static inline void ipv6_addr_set(struct in6_addr *addr,
1616 uint32_t w1, uint32_t w2,
1617 uint32_t w3, uint32_t w4)
1619 addr->s6_addr32[0] = w1;
1620 addr->s6_addr32[1] = w2;
1621 addr->s6_addr32[2] = w3;
1622 addr->s6_addr32[3] = w4;
1625 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1626 struct in6_addr *solicited)
1628 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1629 htonl(0xFF000000) | addr->s6_addr32[3]);
1632 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1635 unsigned int val = 0;
1636 struct ipv6_mreq mreq;
1639 memset(&mreq, 0, sizeof(mreq));
1640 mreq.ipv6mr_interface = ifindex;
1641 mreq.ipv6mr_multiaddr = *mc_addr;
1643 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1647 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1652 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1655 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1662 int __connman_inet_ipv6_send_rs(int index, int timeout,
1663 __connman_inet_rs_cb_t callback, void *user_data)
1665 struct xs_cb_data *data;
1666 struct icmp6_filter filter;
1667 struct in6_addr solicit;
1668 struct in6_addr dst = in6addr_all_routers_mc;
1674 data = g_try_malloc0(sizeof(struct xs_cb_data));
1678 data->callback = callback;
1679 data->user_data = user_data;
1680 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1682 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1688 ICMP6_FILTER_SETBLOCKALL(&filter);
1689 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1691 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1692 sizeof(struct icmp6_filter));
1694 ipv6_addr_solict_mult(&dst, &solicit);
1695 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1696 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1698 data->channel = g_io_channel_unix_new(sk);
1699 g_io_channel_set_close_on_unref(data->channel, TRUE);
1701 g_io_channel_set_encoding(data->channel, NULL, NULL);
1702 g_io_channel_set_buffered(data->channel, FALSE);
1704 data->watch_id = g_io_add_watch(data->channel,
1705 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1706 icmpv6_event, data);
1708 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1713 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1714 struct in6_addr *advert)
1716 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1717 htonl(0xFF000000) | addr->s6_addr32[3]);
1720 #define MSG_SIZE_SEND 1452
1722 static int inc_len(int len, int inc)
1724 if (len > MSG_SIZE_SEND)
1731 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1732 GSList *prefixes, int router_lifetime)
1735 struct in6_addr src, *source;
1736 struct in6_addr dst = in6addr_all_nodes_mc;
1737 GDHCPIAPrefix *prefix;
1738 unsigned char buf[MSG_SIZE_SEND];
1739 char addr_str[INET6_ADDRSTRLEN];
1746 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1751 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1756 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1757 prefixes, inet_ntop(AF_INET6, source, addr_str,
1761 memset(buf, 0, MSG_SIZE_SEND);
1764 for (list = prefixes; list; list = list->next) {
1765 struct nd_opt_prefix_info *pinfo;
1767 prefix = list->data;
1768 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1770 len = inc_len(len, sizeof(*pinfo));
1776 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1777 pinfo->nd_opt_pi_len = 4;
1778 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1779 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1780 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1781 if (router_lifetime > 0) {
1782 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1783 pinfo->nd_opt_pi_preferred_time =
1784 htonl(prefix->preferred);
1786 pinfo->nd_opt_pi_reserved2 = 0;
1788 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1789 sizeof(struct in6_addr));
1791 DBG("[%d] index %d prefix %s/%d", count, index,
1792 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1793 INET6_ADDRSTRLEN), prefix->prefixlen);
1799 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1800 buf, len, router_lifetime);
1802 DBG("cannot send RA %d/%s", err, strerror(-err));
1810 void __connman_inet_ipv6_stop_recv_rs(void *context)
1815 xs_cleanup(context);
1818 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1822 unsigned char chdr[CMSG_BUF_LEN];
1823 unsigned char buf[1540];
1824 struct nd_router_solicit *hdr;
1825 struct sockaddr_in6 saddr;
1827 __connman_inet_recv_rs_cb_t cb = data->callback;
1831 iov.iov_len = sizeof(buf);
1834 mhdr.msg_name = (void *)&saddr;
1835 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1837 mhdr.msg_iov = &iov;
1838 mhdr.msg_iovlen = 1;
1839 mhdr.msg_control = (void *)chdr;
1840 mhdr.msg_controllen = CMSG_BUF_LEN;
1842 len = recvmsg(fd, &mhdr, 0);
1844 cb(NULL, 0, data->user_data);
1848 hdr = (struct nd_router_solicit *)buf;
1849 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1850 sizeof(struct nd_router_solicit));
1851 if (hdr->nd_rs_code != 0)
1854 cb(hdr, len, data->user_data);
1858 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1862 struct xs_cb_data *xs_data = data;
1866 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1869 fd = g_io_channel_unix_get_fd(chan);
1870 ret = icmpv6_rs_recv(fd, xs_data);
1875 xs_data->watch_id = 0;
1879 int __connman_inet_ipv6_start_recv_rs(int index,
1880 __connman_inet_recv_rs_cb_t callback,
1884 struct xs_cb_data *data;
1885 struct icmp6_filter filter;
1886 char addr_str[INET6_ADDRSTRLEN];
1889 data = g_try_malloc0(sizeof(struct xs_cb_data));
1893 data->callback = callback;
1894 data->user_data = user_data;
1896 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1904 ICMP6_FILTER_SETBLOCKALL(&filter);
1905 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1907 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1908 sizeof(struct icmp6_filter));
1910 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1912 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1913 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1914 err, strerror(-err));
1916 data->channel = g_io_channel_unix_new(sk);
1917 g_io_channel_set_close_on_unref(data->channel, TRUE);
1919 g_io_channel_set_encoding(data->channel, NULL, NULL);
1920 g_io_channel_set_buffered(data->channel, FALSE);
1922 data->watch_id = g_io_add_watch(data->channel,
1923 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1924 icmpv6_rs_event, data);
1931 static gboolean ns_timeout_cb(gpointer user_data)
1933 struct xs_cb_data *data = user_data;
1935 DBG("user data %p", user_data);
1940 if (data->callback) {
1941 __connman_inet_ns_cb_t cb = data->callback;
1942 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1950 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
1954 unsigned char chdr[CMSG_BUF_LEN];
1955 unsigned char buf[1540];
1956 struct nd_neighbor_advert *hdr;
1957 struct sockaddr_in6 saddr;
1959 __connman_inet_ns_cb_t cb = data->callback;
1963 iov.iov_len = sizeof(buf);
1966 mhdr.msg_name = (void *)&saddr;
1967 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1969 mhdr.msg_iov = &iov;
1970 mhdr.msg_iovlen = 1;
1971 mhdr.msg_control = (void *)chdr;
1972 mhdr.msg_controllen = CMSG_BUF_LEN;
1974 len = recvmsg(fd, &mhdr, 0);
1976 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1980 hdr = (struct nd_neighbor_advert *)buf;
1981 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1982 sizeof(struct nd_neighbor_advert));
1983 if (hdr->nd_na_code != 0)
1987 * We can receive any neighbor advertisement so we need to check if the
1988 * packet was meant for us and ignore the packet otherwise.
1990 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1991 sizeof(struct in6_addr)))
1994 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1999 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
2003 struct xs_cb_data *xs_data = data;
2007 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2010 fd = g_io_channel_unix_get_fd(chan);
2011 ret = icmpv6_nd_recv(fd, xs_data);
2016 xs_cleanup(xs_data);
2020 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
2021 struct in6_addr *addr,
2022 __connman_inet_ns_cb_t callback,
2025 struct xs_cb_data *data;
2026 struct icmp6_filter filter;
2027 struct in6_addr solicit;
2028 int sk, err, val = 1;
2030 if (timeout_ms <= 0)
2033 data = g_try_malloc0(sizeof(struct xs_cb_data));
2037 data->callback = callback;
2038 data->user_data = user_data;
2039 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
2044 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
2046 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2052 ICMP6_FILTER_SETBLOCKALL(&filter);
2053 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
2055 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2056 sizeof(struct icmp6_filter));
2058 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2059 &val, sizeof(val)) < 0) {
2061 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2067 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2068 &val, sizeof(val)) < 0) {
2070 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2077 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2079 ipv6_addr_solict_mult(addr, &solicit);
2080 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2081 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2083 data->channel = g_io_channel_unix_new(sk);
2084 g_io_channel_set_close_on_unref(data->channel, TRUE);
2086 g_io_channel_set_encoding(data->channel, NULL, NULL);
2087 g_io_channel_set_buffered(data->channel, FALSE);
2089 data->watch_id = g_io_add_watch(data->channel,
2090 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2091 icmpv6_nd_event, data);
2093 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2094 (unsigned char *)addr, 0, 0);
2096 DBG("Cannot send NS %d/%s", err, strerror(-err));
2103 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2104 unsigned int length)
2106 GSList *prefixes = NULL;
2110 if (length <= sizeof(struct nd_router_advert))
2113 len = length - sizeof(struct nd_router_advert);
2114 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2117 struct nd_opt_prefix_info *pinfo;
2118 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2125 optlen = pos[1] << 3;
2126 if (optlen == 0 || optlen > len)
2130 case ND_OPT_PREFIX_INFORMATION:
2131 pinfo = (struct nd_opt_prefix_info *)pos;
2132 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2133 prefix_str, INET6_ADDRSTRLEN);
2137 str = g_strdup_printf("%s/%d", prefix,
2138 pinfo->nd_opt_pi_prefix_len);
2139 prefixes = g_slist_prepend(prefixes, str);
2141 DBG("prefix %s", str);
2153 static int get_dest_addr(int family, int index, char *buf, int len)
2159 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2163 memset(&ifr, 0, sizeof(ifr));
2164 ifr.ifr_ifindex = index;
2166 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2167 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2172 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2173 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2178 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2184 DBG("index %d %s", index, ifr.ifr_name);
2186 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2187 connman_error("Get destination address failed (%s)",
2197 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2200 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2207 if (!inet_ntop(family, addr, buf, len)) {
2208 DBG("error %d/%s", errno, strerror(errno));
2215 int connman_inet_get_dest_addr(int index, char **dest)
2217 char addr[INET_ADDRSTRLEN];
2220 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2224 *dest = g_strdup(addr);
2226 DBG("destination %s", *dest);
2231 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2233 char addr[INET6_ADDRSTRLEN];
2236 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2240 *dest = g_strdup(addr);
2242 DBG("destination %s", *dest);
2247 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2250 int rcvbuf = 1024 * 4;
2252 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2254 connman_error("Can not open netlink socket: %s",
2259 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2260 sizeof(sndbuf)) < 0) {
2261 connman_error("SO_SNDBUF: %s", strerror(errno));
2265 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2266 sizeof(rcvbuf)) < 0) {
2267 connman_error("SO_RCVBUF: %s", strerror(errno));
2271 memset(&rth->local, 0, sizeof(rth->local));
2272 rth->local.nl_family = AF_NETLINK;
2273 rth->local.nl_groups = 0;
2275 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2276 sizeof(rth->local)) < 0) {
2277 connman_error("Can not bind netlink socket: %s",
2282 rth->seq = time(NULL);
2284 DBG("fd %d", rth->fd);
2289 struct inet_rtnl_cb_data {
2290 GIOChannel *channel;
2291 __connman_inet_rtnl_cb_t callback;
2294 struct __connman_inet_rtnl_handle *rtnl;
2298 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2300 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2302 if (data->channel) {
2303 g_io_channel_shutdown(data->channel, TRUE, NULL);
2304 g_io_channel_unref(data->channel);
2305 data->channel = NULL;
2308 DBG("data %p", data);
2310 if (data->rtnl_timeout > 0)
2311 g_source_remove(data->rtnl_timeout);
2313 if (data->watch_id > 0)
2314 g_source_remove(data->watch_id);
2317 __connman_inet_rtnl_close(rth);
2324 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2326 struct inet_rtnl_cb_data *data = user_data;
2328 DBG("user data %p", user_data);
2334 data->callback(NULL, data->user_data);
2336 data->rtnl_timeout = 0;
2337 inet_rtnl_cleanup(data);
2341 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2343 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2344 struct nlmsghdr *h = NULL;
2345 struct sockaddr_nl nladdr;
2346 socklen_t addr_len = sizeof(nladdr);
2347 unsigned char buf[4096];
2352 memset(buf, 0, sizeof(buf));
2353 memset(&nladdr, 0, sizeof(nladdr));
2355 fd = g_io_channel_unix_get_fd(chan);
2357 status = recvfrom(fd, buf, sizeof(buf), 0,
2358 (struct sockaddr *) &nladdr, &addr_len);
2360 if (errno == EINTR || errno == EAGAIN)
2369 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2370 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2377 struct nlmsgerr *err;
2381 if (!NLMSG_OK(h, len))
2384 if (h->nlmsg_seq != rth->seq) {
2386 DBG("skip %d/%d len %d", rth->seq,
2387 h->nlmsg_seq, h->nlmsg_len);
2389 len -= h->nlmsg_len;
2390 ptr += h->nlmsg_len;
2394 switch (h->nlmsg_type) {
2400 err = (struct nlmsgerr *)NLMSG_DATA(h);
2401 connman_error("RTNETLINK answers %s (%d)",
2402 strerror(-err->error), -err->error);
2409 if (h->nlmsg_seq == rth->seq) {
2410 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2412 rtnl_data->callback(h, rtnl_data->user_data);
2414 inet_rtnl_cleanup(rtnl_data);
2420 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2424 struct inet_rtnl_cb_data *rtnl_data = user_data;
2428 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2431 ret = inet_rtnl_recv(chan, rtnl_data);
2436 inet_rtnl_cleanup(rtnl_data);
2440 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2441 struct nlmsghdr *n, int timeout,
2442 __connman_inet_rtnl_cb_t callback, void *user_data)
2444 struct sockaddr_nl nladdr;
2445 struct inet_rtnl_cb_data *data;
2448 memset(&nladdr, 0, sizeof(nladdr));
2449 nladdr.nl_family = AF_NETLINK;
2451 n->nlmsg_seq = ++rtnl->seq;
2454 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2458 data->callback = callback;
2459 data->user_data = user_data;
2461 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2462 inet_rtnl_timeout_cb, data);
2464 data->channel = g_io_channel_unix_new(rtnl->fd);
2466 g_io_channel_set_encoding(data->channel, NULL, NULL);
2467 g_io_channel_set_buffered(data->channel, FALSE);
2469 data->watch_id = g_io_add_watch(data->channel,
2470 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2471 inet_rtnl_event, data);
2473 n->nlmsg_flags |= NLM_F_ACK;
2475 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2476 (struct sockaddr *) &nladdr, sizeof(nladdr));
2477 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2479 connman_error("Can not talk to rtnetlink err %d %s",
2480 -errno, strerror(errno));
2484 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2485 connman_error("Sent %d bytes, msg truncated", err);
2492 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2494 DBG("handle %p", rth);
2502 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2505 int len = RTA_LENGTH(4);
2508 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2509 DBG("Error! max allowed bound %zd exceeded", maxlen);
2512 rta = NLMSG_TAIL(n);
2513 rta->rta_type = type;
2515 memcpy(RTA_DATA(rta), &data, 4);
2516 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2521 static int parse_rtattr(struct rtattr *tb[], int max,
2522 struct rtattr *rta, int len)
2524 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2525 while (RTA_OK(rta, len)) {
2526 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2527 tb[rta->rta_type] = rta;
2528 rta = RTA_NEXT(rta, len);
2531 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2536 struct get_route_cb_data {
2537 connman_inet_addr_cb_t callback;
2541 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2543 struct get_route_cb_data *data = user_data;
2544 struct rtattr *tb[RTA_MAX+1];
2545 struct rtmsg *r = NLMSG_DATA(answer);
2546 int len, index = -1;
2548 const char *addr = NULL;
2550 DBG("answer %p data %p", answer, user_data);
2555 len = answer->nlmsg_len;
2557 if (answer->nlmsg_type != RTM_NEWROUTE &&
2558 answer->nlmsg_type != RTM_DELROUTE) {
2559 connman_error("Not a route: %08x %08x %08x",
2560 answer->nlmsg_len, answer->nlmsg_type,
2561 answer->nlmsg_flags);
2565 len -= NLMSG_LENGTH(sizeof(*r));
2567 connman_error("BUG: wrong nlmsg len %d", len);
2571 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2574 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2576 if (tb[RTA_GATEWAY])
2577 addr = inet_ntop(r->rtm_family,
2578 RTA_DATA(tb[RTA_GATEWAY]),
2579 abuf, sizeof(abuf));
2581 DBG("addr %s index %d user %p", addr, index, data->user_data);
2584 if (data && data->callback)
2585 data->callback(addr, index, data->user_data);
2593 * Return the interface index that contains route to host.
2595 int __connman_inet_get_route(const char *dest_address,
2596 connman_inet_addr_cb_t callback, void *user_data)
2598 struct get_route_cb_data *data;
2599 struct addrinfo hints, *rp;
2600 struct __connman_inet_rtnl_handle *rth;
2603 DBG("dest %s", dest_address);
2608 memset(&hints, 0, sizeof(hints));
2609 hints.ai_family = AF_UNSPEC;
2610 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2612 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2616 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2622 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2623 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2624 rth->req.n.nlmsg_type = RTM_GETROUTE;
2625 rth->req.u.r.rt.rtm_family = rp->ai_family;
2626 rth->req.u.r.rt.rtm_table = 0;
2627 rth->req.u.r.rt.rtm_protocol = 0;
2628 rth->req.u.r.rt.rtm_scope = 0;
2629 rth->req.u.r.rt.rtm_type = 0;
2630 rth->req.u.r.rt.rtm_src_len = 0;
2631 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2632 rth->req.u.r.rt.rtm_tos = 0;
2634 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2635 &rp->ai_addr, rp->ai_addrlen);
2639 err = __connman_inet_rtnl_open(rth);
2643 data = g_try_malloc(sizeof(struct get_route_cb_data));
2649 data->callback = callback;
2650 data->user_data = user_data;
2652 #define GET_ROUTE_TIMEOUT 2
2653 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2654 get_route_cb, data);
2663 __connman_inet_rtnl_close(rth);
2670 int connman_inet_check_ipaddress(const char *host)
2672 struct addrinfo hints;
2673 struct addrinfo *addr;
2676 memset(&hints, 0, sizeof(struct addrinfo));
2677 hints.ai_flags = AI_NUMERICHOST;
2680 result = getaddrinfo(host, NULL, &hints, &addr);
2682 result = addr->ai_family;
2688 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2689 bool connman_inet_check_hostname(const char *ptr, size_t len)
2694 * Not empty or complete length not over 255 characters.
2696 if ((len == 0) || (len > 256))
2700 * Consists of [[:alnum:]-]+ labels separated by [.]
2701 * a [_] is against RFC but seems to be "widely used"
2703 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2705 if ((*p == '-') || (*p == '_')) {
2707 * Not allowed at begin or end of a label.
2709 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2712 } else if (*p == '.') {
2714 * Each label has to be 1-63 characters;
2715 * we allow [.] at the end ('foo.bar.')
2719 if ((d <= 0) || (d >= 64))
2722 ptr = p + 1; /* Jump to the next label */
2724 } else if (isalnum((unsigned char)*p) == 0) {
2726 * Also numbers at the begin are fine
2735 char **__connman_inet_get_running_interfaces(void)
2739 struct ifreq *ifr = NULL;
2740 int sk, i, numif, count = 0;
2742 memset(&ifc, 0, sizeof(ifc));
2744 sk = socket(AF_INET, SOCK_DGRAM, 0);
2748 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2752 * Allocate some extra bytes just in case there will
2753 * be new interfaces added between two SIOCGIFCONF
2756 ifr = g_try_malloc0(ifc.ifc_len * 2);
2762 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2765 numif = ifc.ifc_len / sizeof(struct ifreq);
2767 result = g_try_malloc0((numif + 1) * sizeof(char *));
2773 for (i = 0; i < numif; i++) {
2774 struct ifreq *r = &ifr[i];
2775 struct in6_addr *addr6;
2779 * Note that we do not return loopback interfaces here as they
2780 * are not needed for our purposes.
2782 switch (r->ifr_addr.sa_family) {
2784 addr4 = ntohl(((struct sockaddr_in *)
2785 &r->ifr_addr)->sin_addr.s_addr);
2786 if (((addr4 & 0xff000000) >> 24) == 127)
2790 addr6 = &((struct sockaddr_in6 *)
2791 &r->ifr_addr)->sin6_addr;
2792 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2797 result[count++] = g_strdup(r->ifr_name);
2804 char **prev_result = result;
2805 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2807 g_free(prev_result);
2820 bool connman_inet_is_ipv6_supported()
2824 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2832 int __connman_inet_get_interface_address(int index, int family, void *address)
2834 struct ifaddrs *ifaddr, *ifa;
2836 char name[IF_NAMESIZE];
2838 if (!if_indextoname(index, name))
2841 DBG("index %d interface %s", index, name);
2843 if (getifaddrs(&ifaddr) < 0) {
2845 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2849 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2853 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2854 ifa->ifa_addr->sa_family == family) {
2855 if (family == AF_INET) {
2856 struct sockaddr_in *in4 = (struct sockaddr_in *)
2858 if (in4->sin_addr.s_addr == INADDR_ANY)
2860 memcpy(address, &in4->sin_addr,
2861 sizeof(struct in_addr));
2862 } else if (family == AF_INET6) {
2863 struct sockaddr_in6 *in6 =
2864 (struct sockaddr_in6 *)ifa->ifa_addr;
2865 if (memcmp(&in6->sin6_addr, &in6addr_any,
2866 sizeof(struct in6_addr)) == 0)
2868 memcpy(address, &in6->sin6_addr,
2869 sizeof(struct in6_addr));
2882 freeifaddrs(ifaddr);
2886 static int iprule_modify(int cmd, int family, uint32_t table_id,
2889 struct __connman_inet_rtnl_handle rth;
2892 memset(&rth, 0, sizeof(rth));
2894 rth.req.n.nlmsg_type = cmd;
2895 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2896 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2897 rth.req.u.r.rt.rtm_family = family;
2898 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2899 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2900 rth.req.u.r.rt.rtm_table = table_id;
2901 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2902 rth.req.u.r.rt.rtm_flags = 0;
2904 if (cmd == RTM_NEWRULE) {
2905 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2906 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2909 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2910 FRA_FWMARK, fwmark);
2912 if (table_id < 256) {
2913 rth.req.u.r.rt.rtm_table = table_id;
2915 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2916 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2917 FRA_TABLE, table_id);
2920 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2921 rth.req.u.r.rt.rtm_family = AF_INET;
2923 ret = __connman_inet_rtnl_open(&rth);
2927 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2930 __connman_inet_rtnl_close(&rth);
2935 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2937 /* ip rule add fwmark 9876 table 1234 */
2939 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2942 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2944 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2947 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2948 const char *gateway)
2950 struct __connman_inet_rtnl_handle rth;
2951 unsigned char buf[sizeof(struct in6_addr)];
2953 int family = connman_inet_check_ipaddress(gateway);
2966 ret = inet_pton(family, gateway, buf);
2970 memset(&rth, 0, sizeof(rth));
2972 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2973 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
2974 rth.req.n.nlmsg_type = cmd;
2975 rth.req.u.r.rt.rtm_family = family;
2976 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
2977 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
2978 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2979 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2980 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2982 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
2984 if (table_id < 256) {
2985 rth.req.u.r.rt.rtm_table = table_id;
2987 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2988 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2989 RTA_TABLE, table_id);
2992 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2995 ret = __connman_inet_rtnl_open(&rth);
2999 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3002 __connman_inet_rtnl_close(&rth);
3007 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
3008 const char *gateway)
3010 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
3012 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
3015 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
3016 const char *gateway)
3018 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
3020 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
3023 int __connman_inet_get_interface_ll_address(int index, int family,
3026 struct ifaddrs *ifaddr, *ifa;
3028 char name[IF_NAMESIZE];
3030 if (!if_indextoname(index, name))
3033 DBG("index %d interface %s", index, name);
3035 if (getifaddrs(&ifaddr) < 0) {
3037 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
3041 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3045 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
3046 ifa->ifa_addr->sa_family == family) {
3047 if (family == AF_INET) {
3048 struct sockaddr_in *in4 = (struct sockaddr_in *)
3050 if (in4->sin_addr.s_addr == INADDR_ANY)
3052 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
3053 ((in_addr_t) 0xa9fe0000))
3055 memcpy(address, &in4->sin_addr,
3056 sizeof(struct in_addr));
3057 } else if (family == AF_INET6) {
3058 struct sockaddr_in6 *in6 =
3059 (struct sockaddr_in6 *)ifa->ifa_addr;
3060 if (memcmp(&in6->sin6_addr, &in6addr_any,
3061 sizeof(struct in6_addr)) == 0)
3063 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
3066 memcpy(address, &in6->sin6_addr,
3067 sizeof(struct in6_addr));
3079 freeifaddrs(ifaddr);
3083 int __connman_inet_get_address_netmask(int ifindex,
3084 struct sockaddr_in *address,
3085 struct sockaddr_in *netmask)
3087 int sk, ret = -EINVAL;
3090 DBG("index %d", ifindex);
3092 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3096 memset(&ifr, 0, sizeof(ifr));
3097 ifr.ifr_ifindex = ifindex;
3099 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3102 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3105 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3106 sizeof(struct sockaddr_in));
3108 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3111 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3112 sizeof(struct sockaddr_in));
3120 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3121 struct in_addr *addr)
3125 char addrstr[INET_ADDRSTRLEN];
3126 struct in_addr taddr;
3127 GError *error = NULL;
3128 char *cmdline = NULL;
3131 char **pnpent = NULL;
3136 cmdline_file = "/proc/cmdline";
3138 pnp_file = "/proc/net/pnp";
3141 addr->s_addr = INADDR_NONE;
3143 if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3144 connman_error("%s: Cannot read %s %s\n", __func__,
3145 cmdline_file, error->message);
3149 if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3150 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3151 connman_error("%s: Cannot read %s %s\n", __func__,
3152 pnp_file, error->message);
3156 connman_error("%s: File %s doesn't exist\n", __func__, pnp_file);
3160 len = strlen(cmdline);
3165 /* remove newline */
3166 if (cmdline[len - 1] == '\n')
3167 cmdline[--len] = '\0';
3169 /* split in arguments (seperated by space) */
3170 args = g_strsplit(cmdline, " ", 0);
3172 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3177 /* split in entries (by newlines) */
3178 pnpent = g_strsplit(pnp, "\n", 0);
3180 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3185 /* first find root argument */
3186 for (pp = args; *pp; pp++) {
3187 if (!strcmp(*pp, "root=/dev/nfs"))
3190 /* no rootnfs found */
3194 /* locate nfsroot argument */
3195 for (pp = args; *pp; pp++) {
3196 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3199 /* no nfsroot argument found */
3203 /* determine if nfsroot server is provided */
3204 nfsargs = strchr(*pp, '=');
3209 /* find whether serverip is present */
3210 s = strchr(nfsargs, ':');
3215 /* no serverip, use bootserver */
3216 for (pp = pnpent; *pp; pp++) {
3217 if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3220 /* no bootserver found */
3223 s = *pp + strlen("bootserver ");
3227 /* copy to addr string buffer */
3228 if (len >= sizeof(addrstr)) {
3229 connman_error("%s: Bad server\n", __func__);
3232 memcpy(addrstr, s, len);
3233 addrstr[len] = '\0';
3235 err = inet_pton(AF_INET, addrstr, addr);
3237 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3249 g_error_free(error);
3256 /* get interface out of which peer is reachable (IPv4 only) */
3257 static int get_peer_iface(struct in_addr *addr, char *ifname)
3259 struct ifaddrs *ifaddr, *ifa;
3260 struct sockaddr_in saddr, *ifsaddr;
3265 /* Obtain address(es) matching host/port */
3266 err = getifaddrs(&ifaddr);
3268 connman_error("%s: getifaddrs() failed %d (%s)\n",
3269 __func__, errno, strerror(errno));
3273 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3275 connman_error("%s: socket() failed %d (%s)\n",
3276 __func__, errno, strerror(errno));
3280 memset(&saddr, 0, sizeof(saddr));
3281 saddr.sin_family = AF_INET;
3282 saddr.sin_port = 0; /* any port */
3283 saddr.sin_addr = *addr;
3285 /* no need to bind, connect will select iface */
3286 err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3288 connman_error("%s: connect() failed: %d (%s)\n",
3289 __func__, errno, strerror(errno));
3293 socklen = sizeof(saddr);
3294 err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3296 connman_error("%s: getsockname() failed: %d (%s)\n",
3297 __func__, errno, strerror(errno));
3302 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3306 /* only IPv4 address */
3307 if (ifa->ifa_addr->sa_family != AF_INET)
3310 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3312 /* match address? */
3313 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3320 strcpy(ifname, ifa->ifa_name);
3326 freeifaddrs(ifaddr);
3331 bool __connman_inet_isrootnfs_device(const char *devname)
3333 struct in_addr addr;
3334 char ifname[IFNAMSIZ];
3336 return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3337 get_peer_iface(&addr, ifname) == 0 &&
3338 strcmp(devname, ifname) == 0;
3341 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3346 GError *error = NULL;
3348 char **pnpent = NULL;
3349 char **nameservers = NULL;
3352 pnp_file = "/proc/net/pnp";
3354 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3355 connman_error("%s: Cannot read %s %s\n", __func__,
3356 pnp_file, error->message);
3360 /* split in entries (by newlines) */
3361 pnpent = g_strsplit(pnp, "\n", 0);
3363 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3369 * Perform two passes to retreive a char ** array of
3370 * nameservers that are not 0.0.0.0
3372 * The first pass counts them, the second fills in the
3377 for (pass = 1; pass <= 2; pass++) {
3379 /* at the start of the second pass allocate */
3381 nameservers = g_new(char *, count + 1);
3384 for (pp = pnpent; *pp; pp++) {
3385 /* match 'nameserver ' at the start of each line */
3386 if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3389 /* compare it against 0.0.0.0 */
3390 s = *pp + strlen("nameserver ");
3391 if (!strcmp(s, "0.0.0.0"))
3394 /* on second pass fill in array */
3396 nameservers[count] = g_strdup(s);
3400 /* no nameservers? */
3404 /* and terminate char ** array with NULL */
3406 nameservers[count] = NULL;
3414 g_error_free(error);