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 int connman_inet_ifindex(const char *name)
201 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
205 memset(&ifr, 0, sizeof(ifr));
206 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
208 err = ioctl(sk, SIOCGIFINDEX, &ifr);
215 return ifr.ifr_ifindex;
218 char *connman_inet_ifname(int index)
226 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
230 memset(&ifr, 0, sizeof(ifr));
231 ifr.ifr_ifindex = index;
233 err = ioctl(sk, SIOCGIFNAME, &ifr);
240 return g_strdup(ifr.ifr_name);
243 int connman_inet_ifup(int index)
248 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
252 memset(&ifr, 0, sizeof(ifr));
253 ifr.ifr_ifindex = index;
255 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
260 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
265 if (ifr.ifr_flags & IFF_UP) {
270 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
272 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
285 int connman_inet_ifdown(int index)
287 struct ifreq ifr, addr_ifr;
288 struct sockaddr_in *addr;
291 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
295 memset(&ifr, 0, sizeof(ifr));
296 ifr.ifr_ifindex = index;
298 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
303 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
308 memset(&addr_ifr, 0, sizeof(addr_ifr));
309 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
310 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
311 addr->sin_family = AF_INET;
312 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
313 connman_warn("Could not clear IPv4 address index %d", index);
315 if (!(ifr.ifr_flags & IFF_UP)) {
320 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
322 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
334 struct in6_addr ifr6_addr;
335 __u32 ifr6_prefixlen;
336 unsigned int ifr6_ifindex;
339 int connman_inet_set_ipv6_address(int index,
340 struct connman_ipaddress *ipaddress)
343 unsigned char prefix_len;
346 if (!ipaddress->local)
349 prefix_len = ipaddress->prefixlen;
350 address = ipaddress->local;
352 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
354 err = __connman_inet_modify_address(RTM_NEWADDR,
355 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
356 address, NULL, prefix_len, NULL);
358 connman_error("%s: %s", __func__, strerror(-err));
365 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
368 unsigned char prefix_len;
369 const char *address, *broadcast, *peer;
371 if (!ipaddress->local)
374 prefix_len = ipaddress->prefixlen;
375 address = ipaddress->local;
376 broadcast = ipaddress->broadcast;
377 peer = ipaddress->peer;
379 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
381 err = __connman_inet_modify_address(RTM_NEWADDR,
382 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
383 address, peer, prefix_len, broadcast);
385 connman_error("%s: %s", __func__, strerror(-err));
392 int connman_inet_clear_ipv6_address(int index, const char *address,
397 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
402 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
403 address, NULL, prefix_len, NULL);
405 connman_error("%s: %s", __func__, strerror(-err));
412 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
415 unsigned char prefix_len;
416 const char *address, *broadcast, *peer;
418 prefix_len = ipaddress->prefixlen;
419 address = ipaddress->local;
420 broadcast = ipaddress->broadcast;
421 peer = ipaddress->peer;
423 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
424 address, prefix_len, peer, broadcast);
429 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
430 address, peer, prefix_len, broadcast);
432 connman_error("%s: %s", __func__, strerror(-err));
439 int connman_inet_add_host_route(int index, const char *host,
442 return connman_inet_add_network_route(index, host, gateway, NULL);
445 int connman_inet_del_host_route(int index, const char *host)
447 return connman_inet_del_network_route(index, host);
450 int connman_inet_add_network_route(int index, const char *host,
456 struct sockaddr_in addr;
459 DBG("index %d host %s gateway %s netmask %s", index,
460 host, gateway, netmask);
462 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
468 memset(&ifr, 0, sizeof(ifr));
469 ifr.ifr_ifindex = index;
471 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
477 DBG("ifname %s", ifr.ifr_name);
479 memset(&rt, 0, sizeof(rt));
480 rt.rt_flags = RTF_UP;
482 rt.rt_flags |= RTF_GATEWAY;
484 rt.rt_flags |= RTF_HOST;
486 memset(&addr, 0, sizeof(addr));
487 addr.sin_family = AF_INET;
488 addr.sin_addr.s_addr = inet_addr(host);
489 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
491 memset(&addr, 0, sizeof(addr));
492 addr.sin_family = AF_INET;
494 addr.sin_addr.s_addr = inet_addr(gateway);
496 addr.sin_addr.s_addr = INADDR_ANY;
497 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
499 memset(&addr, 0, sizeof(addr));
500 addr.sin_family = AF_INET;
501 addr.sin_addr.s_addr = INADDR_ANY;
503 addr.sin_addr.s_addr = inet_addr(netmask);
505 addr.sin_addr.s_addr = INADDR_ANY;
506 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
508 rt.rt_dev = ifr.ifr_name;
510 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
517 connman_error("Adding host route failed (%s)",
523 int connman_inet_del_network_route(int index, const char *host)
527 struct sockaddr_in addr;
530 DBG("index %d host %s", index, host);
532 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
538 memset(&ifr, 0, sizeof(ifr));
539 ifr.ifr_ifindex = index;
541 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
547 DBG("ifname %s", ifr.ifr_name);
549 memset(&rt, 0, sizeof(rt));
550 rt.rt_flags = RTF_UP | RTF_HOST;
552 memset(&addr, 0, sizeof(addr));
553 addr.sin_family = AF_INET;
554 addr.sin_addr.s_addr = inet_addr(host);
555 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
557 rt.rt_dev = ifr.ifr_name;
559 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
566 connman_error("Deleting host route failed (%s)",
572 int connman_inet_del_ipv6_network_route(int index, const char *host,
573 unsigned char prefix_len)
578 DBG("index %d host %s", index, host);
583 memset(&rt, 0, sizeof(rt));
585 rt.rtmsg_dst_len = prefix_len;
587 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
592 rt.rtmsg_flags = RTF_UP | RTF_HOST;
595 rt.rtmsg_ifindex = index;
597 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
603 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
610 connman_error("Del IPv6 host route error (%s)",
616 int connman_inet_del_ipv6_host_route(int index, const char *host)
618 return connman_inet_del_ipv6_network_route(index, host, 128);
621 int connman_inet_add_ipv6_network_route(int index, const char *host,
623 unsigned char prefix_len)
628 DBG("index %d host %s gateway %s", index, host, gateway);
633 memset(&rt, 0, sizeof(rt));
635 rt.rtmsg_dst_len = prefix_len;
637 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
642 rt.rtmsg_flags = RTF_UP | RTF_HOST;
645 rt.rtmsg_flags |= RTF_GATEWAY;
646 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
650 rt.rtmsg_ifindex = index;
652 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
658 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
665 connman_error("Set IPv6 host route error (%s)",
671 int connman_inet_add_ipv6_host_route(int index, const char *host,
674 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
677 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
682 DBG("index %d gateway %s", index, gateway);
687 memset(&rt, 0, sizeof(rt));
689 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
694 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
696 rt.rtmsg_dst_len = 0;
697 rt.rtmsg_ifindex = index;
699 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
705 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
712 connman_error("Clear default IPv6 gateway error (%s)",
718 int connman_inet_set_gateway_interface(int index)
722 struct sockaddr_in addr;
725 DBG("index %d", index);
727 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
733 memset(&ifr, 0, sizeof(ifr));
734 ifr.ifr_ifindex = index;
736 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
742 DBG("ifname %s", ifr.ifr_name);
744 memset(&rt, 0, sizeof(rt));
745 rt.rt_flags = RTF_UP;
747 memset(&addr, 0, sizeof(addr));
748 addr.sin_family = AF_INET;
749 addr.sin_addr.s_addr = INADDR_ANY;
751 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
752 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
753 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
755 rt.rt_dev = ifr.ifr_name;
757 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
764 connman_error("Setting default interface route failed (%s)",
770 int connman_inet_set_ipv6_gateway_interface(int index)
774 struct sockaddr_in6 addr;
775 const struct in6_addr any = IN6ADDR_ANY_INIT;
778 DBG("index %d", index);
780 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
786 memset(&ifr, 0, sizeof(ifr));
787 ifr.ifr_ifindex = index;
789 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
795 DBG("ifname %s", ifr.ifr_name);
797 memset(&rt, 0, sizeof(rt));
798 rt.rt_flags = RTF_UP;
800 memset(&addr, 0, sizeof(addr));
801 addr.sin6_family = AF_INET6;
802 addr.sin6_addr = any;
804 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
805 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
806 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
808 rt.rt_dev = ifr.ifr_name;
810 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
817 connman_error("Setting default interface route failed (%s)",
823 int connman_inet_clear_gateway_address(int index, const char *gateway)
827 struct sockaddr_in addr;
830 DBG("index %d gateway %s", index, gateway);
832 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
838 memset(&ifr, 0, sizeof(ifr));
839 ifr.ifr_ifindex = index;
841 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
847 DBG("ifname %s", ifr.ifr_name);
849 memset(&rt, 0, sizeof(rt));
850 rt.rt_flags = RTF_UP | RTF_GATEWAY;
852 memset(&addr, 0, sizeof(addr));
853 addr.sin_family = AF_INET;
854 addr.sin_addr.s_addr = INADDR_ANY;
855 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
857 memset(&addr, 0, sizeof(addr));
858 addr.sin_family = AF_INET;
859 addr.sin_addr.s_addr = inet_addr(gateway);
860 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
862 memset(&addr, 0, sizeof(addr));
863 addr.sin_family = AF_INET;
864 addr.sin_addr.s_addr = INADDR_ANY;
865 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
867 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
874 connman_error("Removing default gateway route failed (%s)",
880 int connman_inet_clear_gateway_interface(int index)
884 struct sockaddr_in addr;
887 DBG("index %d", index);
889 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
895 memset(&ifr, 0, sizeof(ifr));
896 ifr.ifr_ifindex = index;
898 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
904 DBG("ifname %s", ifr.ifr_name);
906 memset(&rt, 0, sizeof(rt));
907 rt.rt_flags = RTF_UP;
909 memset(&addr, 0, sizeof(addr));
910 addr.sin_family = AF_INET;
911 addr.sin_addr.s_addr = INADDR_ANY;
913 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
914 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
915 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
917 rt.rt_dev = ifr.ifr_name;
919 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
926 connman_error("Removing default interface route failed (%s)",
932 int connman_inet_clear_ipv6_gateway_interface(int index)
936 struct sockaddr_in6 addr;
937 const struct in6_addr any = IN6ADDR_ANY_INIT;
940 DBG("index %d", index);
942 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
948 memset(&ifr, 0, sizeof(ifr));
949 ifr.ifr_ifindex = index;
951 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
957 DBG("ifname %s", ifr.ifr_name);
959 memset(&rt, 0, sizeof(rt));
960 rt.rt_flags = RTF_UP;
962 memset(&addr, 0, sizeof(addr));
963 addr.sin6_family = AF_INET6;
964 addr.sin6_addr = any;
966 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
967 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
968 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
970 rt.rt_dev = ifr.ifr_name;
972 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
979 connman_error("Removing default interface route failed (%s)",
985 bool connman_inet_compare_subnet(int index, const char *host)
988 struct in_addr _host_addr;
989 in_addr_t host_addr, netmask_addr, if_addr;
990 struct sockaddr_in *netmask, *addr;
993 DBG("host %s", host);
998 if (inet_aton(host, &_host_addr) == 0)
1000 host_addr = _host_addr.s_addr;
1002 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1006 memset(&ifr, 0, sizeof(ifr));
1007 ifr.ifr_ifindex = index;
1009 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1014 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1019 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1020 netmask_addr = netmask->sin_addr.s_addr;
1022 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1029 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1030 if_addr = addr->sin_addr.s_addr;
1032 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1035 int connman_inet_remove_from_bridge(int index, const char *bridge)
1043 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1049 memset(&ifr, 0, sizeof(ifr));
1050 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1051 ifr.ifr_ifindex = index;
1053 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1060 connman_error("Remove interface from bridge error %s",
1066 int connman_inet_add_to_bridge(int index, const char *bridge)
1074 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1080 memset(&ifr, 0, sizeof(ifr));
1081 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1082 ifr.ifr_ifindex = index;
1084 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1091 connman_error("Add interface to bridge error %s",
1097 int connman_inet_set_mtu(int index, int mtu)
1102 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1106 memset(&ifr, 0, sizeof(ifr));
1107 ifr.ifr_ifindex = index;
1109 err = ioctl(sk, SIOCGIFNAME, &ifr);
1112 err = ioctl(sk, SIOCSIFMTU, &ifr);
1119 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1129 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1133 index = if_nametoindex(tunnel);
1135 err = connman_inet_set_mtu(index, mtu);
1139 memset(&ifr, 0, sizeof(ifr));
1140 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1141 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1148 if ((ifr.ifr_flags ^ flags) & mask) {
1149 ifr.ifr_flags &= ~mask;
1150 ifr.ifr_flags |= mask & flags;
1151 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1153 connman_error("SIOCSIFFLAGS failed: %s",
1162 int connman_inet_create_tunnel(char **iface)
1167 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1170 connman_error("Failed to open /dev/net/tun: %s",
1175 memset(&ifr, 0, sizeof(ifr));
1176 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1178 for (i = 0; i < 256; i++) {
1179 sprintf(ifr.ifr_name, "tun%d", i);
1181 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1186 connman_error("Failed to find available tun device");
1191 *iface = g_strdup(ifr.ifr_name);
1197 * This callback struct is used when sending router and neighbor
1198 * solicitation and advertisement messages.
1201 GIOChannel *channel;
1203 struct sockaddr_in6 addr;
1209 #define CMSG_BUF_LEN 512
1210 #define IN6ADDR_ALL_NODES_MC_INIT \
1211 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1212 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1213 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1215 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1216 static const struct in6_addr in6addr_all_routers_mc =
1217 IN6ADDR_ALL_ROUTERS_MC_INIT;
1219 static void xs_cleanup(struct xs_cb_data *data)
1221 if (data->channel) {
1222 g_io_channel_shutdown(data->channel, TRUE, NULL);
1223 g_io_channel_unref(data->channel);
1224 data->channel = NULL;
1227 if (data->timeout > 0)
1228 g_source_remove(data->timeout);
1230 if (data->watch_id > 0)
1231 g_source_remove(data->watch_id);
1236 static gboolean rs_timeout_cb(gpointer user_data)
1238 struct xs_cb_data *data = user_data;
1240 DBG("user data %p", user_data);
1245 if (data->callback) {
1246 __connman_inet_rs_cb_t cb = data->callback;
1247 cb(NULL, 0, data->user_data);
1255 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1259 unsigned char chdr[CMSG_BUF_LEN];
1260 unsigned char buf[1540];
1261 struct nd_router_advert *hdr;
1262 struct sockaddr_in6 saddr;
1264 __connman_inet_rs_cb_t cb = data->callback;
1268 iov.iov_len = sizeof(buf);
1271 mhdr.msg_name = (void *)&saddr;
1272 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1274 mhdr.msg_iov = &iov;
1275 mhdr.msg_iovlen = 1;
1276 mhdr.msg_control = (void *)chdr;
1277 mhdr.msg_controllen = CMSG_BUF_LEN;
1279 len = recvmsg(fd, &mhdr, 0);
1281 cb(NULL, 0, data->user_data);
1285 hdr = (struct nd_router_advert *)buf;
1286 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1287 sizeof(struct nd_router_advert));
1288 if (hdr->nd_ra_code != 0)
1291 cb(hdr, len, data->user_data);
1296 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1299 struct xs_cb_data *xs_data = data;
1303 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1306 fd = g_io_channel_unix_get_fd(chan);
1307 ret = icmpv6_recv(fd, xs_data);
1312 xs_cleanup(xs_data);
1316 /* Adapted from RFC 1071 "C" Implementation Example */
1317 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1318 const void *extra_data, socklen_t extra_datalen)
1320 register unsigned long sum = 0;
1325 /* caller must make sure datalen is even */
1327 addr = (uint16_t *)phdr;
1328 for (i = 0; i < 20; i++)
1332 addr = (uint16_t *)data;
1340 count = extra_datalen;
1341 addr = (uint16_t *)extra_data;
1350 sum = (sum & 0xffff) + (sum >> 16);
1352 return (uint16_t)~sum;
1355 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1356 const struct in6_addr *source,
1357 unsigned char *buf, size_t len, uint16_t lifetime)
1360 struct in6_addr src;
1361 struct in6_addr dst;
1363 uint8_t reserved[3];
1370 struct icmp6_hdr icmp;
1371 struct nd_neighbor_solicit ns;
1372 struct nd_router_solicit rs;
1373 struct nd_router_advert ra;
1378 struct cmsghdr *cmsg;
1379 struct in6_pktinfo *pinfo;
1380 struct sockaddr_in6 dst, src;
1381 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1382 struct iovec iov[2];
1383 int fd, datalen, ret, iovlen = 1;
1387 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1391 memset(&frame, 0, sizeof(frame));
1392 memset(&dst, 0, sizeof(dst));
1394 if (type == ND_ROUTER_SOLICIT)
1395 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1396 else if (type == ND_ROUTER_ADVERT) {
1397 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1398 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1399 } else if (type == ND_NEIGHBOR_SOLICIT) {
1400 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1401 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1407 dst.sin6_addr = *dest;
1410 src.sin6_addr = *source;
1412 src.sin6_addr = in6addr_any;
1414 /* Fill in the IPv6 header */
1415 frame.ip.ip6_vfc = 0x60;
1416 frame.ip.ip6_plen = htons(datalen + len);
1417 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1418 frame.ip.ip6_hlim = 255;
1419 frame.ip.ip6_dst = dst.sin6_addr;
1420 frame.ip.ip6_src = src.sin6_addr;
1421 /* all other fields are already set to zero */
1423 /* Prepare pseudo header for csum */
1424 memset(&phdr, 0, sizeof(phdr));
1425 phdr.dst = dst.sin6_addr;
1426 phdr.src = src.sin6_addr;
1427 phdr.plen = htonl(datalen + len);
1428 phdr.nxt = IPPROTO_ICMPV6;
1430 /* Fill in remaining ICMP header fields */
1431 frame.i.icmp.icmp6_type = type;
1432 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1434 iov[0].iov_base = &frame;
1435 iov[0].iov_len = sizeof(frame.ip) + datalen;
1438 iov[1].iov_base = buf;
1439 iov[1].iov_len = len;
1443 dst.sin6_family = AF_INET6;
1444 msgh.msg_name = &dst;
1445 msgh.msg_namelen = sizeof(dst);
1447 msgh.msg_iovlen = iovlen;
1450 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1451 cmsg = (struct cmsghdr *)cbuf;
1452 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1453 pinfo->ipi6_ifindex = oif;
1455 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1456 cmsg->cmsg_level = IPPROTO_IPV6;
1457 cmsg->cmsg_type = IPV6_PKTINFO;
1458 msgh.msg_control = cmsg;
1459 msgh.msg_controllen = cmsg->cmsg_len;
1461 ret = sendmsg(fd, &msgh, 0);
1467 static inline void ipv6_addr_set(struct in6_addr *addr,
1468 uint32_t w1, uint32_t w2,
1469 uint32_t w3, uint32_t w4)
1471 addr->s6_addr32[0] = w1;
1472 addr->s6_addr32[1] = w2;
1473 addr->s6_addr32[2] = w3;
1474 addr->s6_addr32[3] = w4;
1477 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1478 struct in6_addr *solicited)
1480 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1481 htonl(0xFF000000) | addr->s6_addr32[3]);
1484 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1487 unsigned int val = 0;
1488 struct ipv6_mreq mreq;
1491 memset(&mreq, 0, sizeof(mreq));
1492 mreq.ipv6mr_interface = ifindex;
1493 mreq.ipv6mr_multiaddr = *mc_addr;
1495 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1499 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1504 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1507 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1514 int __connman_inet_ipv6_send_rs(int index, int timeout,
1515 __connman_inet_rs_cb_t callback, void *user_data)
1517 struct xs_cb_data *data;
1518 struct icmp6_filter filter;
1519 struct in6_addr solicit;
1520 struct in6_addr dst = in6addr_all_routers_mc;
1526 data = g_try_malloc0(sizeof(struct xs_cb_data));
1530 data->callback = callback;
1531 data->user_data = user_data;
1532 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1534 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1540 ICMP6_FILTER_SETBLOCKALL(&filter);
1541 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1543 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1544 sizeof(struct icmp6_filter));
1546 ipv6_addr_solict_mult(&dst, &solicit);
1547 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1548 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1550 data->channel = g_io_channel_unix_new(sk);
1551 g_io_channel_set_close_on_unref(data->channel, TRUE);
1553 g_io_channel_set_encoding(data->channel, NULL, NULL);
1554 g_io_channel_set_buffered(data->channel, FALSE);
1556 data->watch_id = g_io_add_watch(data->channel,
1557 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1558 icmpv6_event, data);
1560 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1565 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1566 struct in6_addr *advert)
1568 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1569 htonl(0xFF000000) | addr->s6_addr32[3]);
1572 #define MSG_SIZE_SEND 1452
1574 static int inc_len(int len, int inc)
1576 if (len > MSG_SIZE_SEND)
1583 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1584 GSList *prefixes, int router_lifetime)
1587 struct in6_addr src, *source;
1588 struct in6_addr dst = in6addr_all_nodes_mc;
1589 GDHCPIAPrefix *prefix;
1590 unsigned char buf[MSG_SIZE_SEND];
1591 char addr_str[INET6_ADDRSTRLEN];
1598 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1603 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1608 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1609 prefixes, inet_ntop(AF_INET6, source, addr_str,
1613 memset(buf, 0, MSG_SIZE_SEND);
1616 for (list = prefixes; list; list = list->next) {
1617 struct nd_opt_prefix_info *pinfo;
1619 prefix = list->data;
1620 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1622 len = inc_len(len, sizeof(*pinfo));
1628 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1629 pinfo->nd_opt_pi_len = 4;
1630 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1631 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1632 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1633 if (router_lifetime > 0) {
1634 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1635 pinfo->nd_opt_pi_preferred_time =
1636 htonl(prefix->preferred);
1638 pinfo->nd_opt_pi_reserved2 = 0;
1640 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1641 sizeof(struct in6_addr));
1643 DBG("[%d] index %d prefix %s/%d", count, index,
1644 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1645 INET6_ADDRSTRLEN), prefix->prefixlen);
1651 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1652 buf, len, router_lifetime);
1654 DBG("cannot send RA %d/%s", err, strerror(-err));
1662 void __connman_inet_ipv6_stop_recv_rs(void *context)
1667 xs_cleanup(context);
1670 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1674 unsigned char chdr[CMSG_BUF_LEN];
1675 unsigned char buf[1540];
1676 struct nd_router_solicit *hdr;
1677 struct sockaddr_in6 saddr;
1679 __connman_inet_recv_rs_cb_t cb = data->callback;
1683 iov.iov_len = sizeof(buf);
1686 mhdr.msg_name = (void *)&saddr;
1687 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1689 mhdr.msg_iov = &iov;
1690 mhdr.msg_iovlen = 1;
1691 mhdr.msg_control = (void *)chdr;
1692 mhdr.msg_controllen = CMSG_BUF_LEN;
1694 len = recvmsg(fd, &mhdr, 0);
1696 cb(NULL, 0, data->user_data);
1700 hdr = (struct nd_router_solicit *)buf;
1701 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1702 sizeof(struct nd_router_solicit));
1703 if (hdr->nd_rs_code != 0)
1706 cb(hdr, len, data->user_data);
1710 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1714 struct xs_cb_data *xs_data = data;
1718 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1721 fd = g_io_channel_unix_get_fd(chan);
1722 ret = icmpv6_rs_recv(fd, xs_data);
1727 xs_data->watch_id = 0;
1731 int __connman_inet_ipv6_start_recv_rs(int index,
1732 __connman_inet_recv_rs_cb_t callback,
1736 struct xs_cb_data *data;
1737 struct icmp6_filter filter;
1738 char addr_str[INET6_ADDRSTRLEN];
1741 data = g_try_malloc0(sizeof(struct xs_cb_data));
1745 data->callback = callback;
1746 data->user_data = user_data;
1748 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1756 ICMP6_FILTER_SETBLOCKALL(&filter);
1757 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1759 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1760 sizeof(struct icmp6_filter));
1762 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1764 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1765 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1766 err, strerror(-err));
1768 data->channel = g_io_channel_unix_new(sk);
1769 g_io_channel_set_close_on_unref(data->channel, TRUE);
1771 g_io_channel_set_encoding(data->channel, NULL, NULL);
1772 g_io_channel_set_buffered(data->channel, FALSE);
1774 data->watch_id = g_io_add_watch(data->channel,
1775 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1776 icmpv6_rs_event, data);
1783 static gboolean ns_timeout_cb(gpointer user_data)
1785 struct xs_cb_data *data = user_data;
1787 DBG("user data %p", user_data);
1792 if (data->callback) {
1793 __connman_inet_ns_cb_t cb = data->callback;
1794 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1802 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
1806 unsigned char chdr[CMSG_BUF_LEN];
1807 unsigned char buf[1540];
1808 struct nd_neighbor_advert *hdr;
1809 struct sockaddr_in6 saddr;
1811 __connman_inet_ns_cb_t cb = data->callback;
1815 iov.iov_len = sizeof(buf);
1818 mhdr.msg_name = (void *)&saddr;
1819 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1821 mhdr.msg_iov = &iov;
1822 mhdr.msg_iovlen = 1;
1823 mhdr.msg_control = (void *)chdr;
1824 mhdr.msg_controllen = CMSG_BUF_LEN;
1826 len = recvmsg(fd, &mhdr, 0);
1828 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1832 hdr = (struct nd_neighbor_advert *)buf;
1833 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1834 sizeof(struct nd_neighbor_advert));
1835 if (hdr->nd_na_code != 0)
1839 * We can receive any neighbor advertisement so we need to check if the
1840 * packet was meant for us and ignore the packet otherwise.
1842 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1843 sizeof(struct in6_addr)))
1846 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1851 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
1855 struct xs_cb_data *xs_data = data;
1859 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1862 fd = g_io_channel_unix_get_fd(chan);
1863 ret = icmpv6_nd_recv(fd, xs_data);
1868 xs_cleanup(xs_data);
1872 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
1873 struct in6_addr *addr,
1874 __connman_inet_ns_cb_t callback,
1877 struct xs_cb_data *data;
1878 struct icmp6_filter filter;
1879 struct in6_addr solicit;
1880 int sk, err, val = 1;
1882 if (timeout_ms <= 0)
1885 data = g_try_malloc0(sizeof(struct xs_cb_data));
1889 data->callback = callback;
1890 data->user_data = user_data;
1891 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
1896 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
1898 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1904 ICMP6_FILTER_SETBLOCKALL(&filter);
1905 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
1907 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1908 sizeof(struct icmp6_filter));
1910 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
1911 &val, sizeof(val)) < 0) {
1913 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
1919 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
1920 &val, sizeof(val)) < 0) {
1922 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
1929 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
1931 ipv6_addr_solict_mult(addr, &solicit);
1932 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1933 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1935 data->channel = g_io_channel_unix_new(sk);
1936 g_io_channel_set_close_on_unref(data->channel, TRUE);
1938 g_io_channel_set_encoding(data->channel, NULL, NULL);
1939 g_io_channel_set_buffered(data->channel, FALSE);
1941 data->watch_id = g_io_add_watch(data->channel,
1942 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1943 icmpv6_nd_event, data);
1945 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
1946 (unsigned char *)addr, 0, 0);
1948 DBG("Cannot send NS %d/%s", err, strerror(-err));
1955 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
1956 unsigned int length)
1958 GSList *prefixes = NULL;
1962 if (length <= sizeof(struct nd_router_advert))
1965 len = length - sizeof(struct nd_router_advert);
1966 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
1969 struct nd_opt_prefix_info *pinfo;
1970 char prefix_str[INET6_ADDRSTRLEN+1], *str;
1977 optlen = pos[1] << 3;
1978 if (optlen == 0 || optlen > len)
1982 case ND_OPT_PREFIX_INFORMATION:
1983 pinfo = (struct nd_opt_prefix_info *)pos;
1984 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
1985 prefix_str, INET6_ADDRSTRLEN);
1989 str = g_strdup_printf("%s/%d", prefix,
1990 pinfo->nd_opt_pi_prefix_len);
1991 prefixes = g_slist_prepend(prefixes, str);
1993 DBG("prefix %s", str);
2005 static int get_dest_addr(int family, int index, char *buf, int len)
2011 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2015 memset(&ifr, 0, sizeof(ifr));
2016 ifr.ifr_ifindex = index;
2018 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2019 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2024 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2025 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2030 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2036 DBG("index %d %s", index, ifr.ifr_name);
2038 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2039 connman_error("Get destination address failed (%s)",
2049 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2052 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2059 if (!inet_ntop(family, addr, buf, len)) {
2060 DBG("error %d/%s", errno, strerror(errno));
2067 int connman_inet_get_dest_addr(int index, char **dest)
2069 char addr[INET_ADDRSTRLEN];
2072 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2076 *dest = g_strdup(addr);
2078 DBG("destination %s", *dest);
2083 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2085 char addr[INET6_ADDRSTRLEN];
2088 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2092 *dest = g_strdup(addr);
2094 DBG("destination %s", *dest);
2099 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2102 int rcvbuf = 1024 * 4;
2104 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2106 connman_error("Can not open netlink socket: %s",
2111 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2112 sizeof(sndbuf)) < 0) {
2113 connman_error("SO_SNDBUF: %s", strerror(errno));
2117 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2118 sizeof(rcvbuf)) < 0) {
2119 connman_error("SO_RCVBUF: %s", strerror(errno));
2123 memset(&rth->local, 0, sizeof(rth->local));
2124 rth->local.nl_family = AF_NETLINK;
2125 rth->local.nl_groups = 0;
2127 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2128 sizeof(rth->local)) < 0) {
2129 connman_error("Can not bind netlink socket: %s",
2134 rth->seq = time(NULL);
2136 DBG("fd %d", rth->fd);
2141 struct inet_rtnl_cb_data {
2142 GIOChannel *channel;
2143 __connman_inet_rtnl_cb_t callback;
2146 struct __connman_inet_rtnl_handle *rtnl;
2150 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2152 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2154 if (data->channel) {
2155 g_io_channel_shutdown(data->channel, TRUE, NULL);
2156 g_io_channel_unref(data->channel);
2157 data->channel = NULL;
2160 DBG("data %p", data);
2162 if (data->rtnl_timeout > 0)
2163 g_source_remove(data->rtnl_timeout);
2165 if (data->watch_id > 0)
2166 g_source_remove(data->watch_id);
2169 __connman_inet_rtnl_close(rth);
2176 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2178 struct inet_rtnl_cb_data *data = user_data;
2180 DBG("user data %p", user_data);
2186 data->callback(NULL, data->user_data);
2188 data->rtnl_timeout = 0;
2189 inet_rtnl_cleanup(data);
2193 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2195 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2196 struct nlmsghdr *h = NULL;
2197 struct sockaddr_nl nladdr;
2198 socklen_t addr_len = sizeof(nladdr);
2199 unsigned char buf[4096];
2204 memset(buf, 0, sizeof(buf));
2205 memset(&nladdr, 0, sizeof(nladdr));
2207 fd = g_io_channel_unix_get_fd(chan);
2209 status = recvfrom(fd, buf, sizeof(buf), 0,
2210 (struct sockaddr *) &nladdr, &addr_len);
2212 if (errno == EINTR || errno == EAGAIN)
2221 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2222 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2229 struct nlmsgerr *err;
2233 if (!NLMSG_OK(h, len))
2236 if (h->nlmsg_seq != rth->seq) {
2238 DBG("skip %d/%d len %d", rth->seq,
2239 h->nlmsg_seq, h->nlmsg_len);
2241 len -= h->nlmsg_len;
2242 ptr += h->nlmsg_len;
2246 switch (h->nlmsg_type) {
2252 err = (struct nlmsgerr *)NLMSG_DATA(h);
2253 connman_error("RTNETLINK answers %s (%d)",
2254 strerror(-err->error), -err->error);
2261 if (h->nlmsg_seq == rth->seq) {
2262 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2264 rtnl_data->callback(h, rtnl_data->user_data);
2266 inet_rtnl_cleanup(rtnl_data);
2272 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2276 struct inet_rtnl_cb_data *rtnl_data = user_data;
2280 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2283 ret = inet_rtnl_recv(chan, rtnl_data);
2288 inet_rtnl_cleanup(rtnl_data);
2292 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2293 struct nlmsghdr *n, int timeout,
2294 __connman_inet_rtnl_cb_t callback, void *user_data)
2296 struct sockaddr_nl nladdr;
2297 struct inet_rtnl_cb_data *data;
2300 memset(&nladdr, 0, sizeof(nladdr));
2301 nladdr.nl_family = AF_NETLINK;
2303 n->nlmsg_seq = ++rtnl->seq;
2306 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2310 data->callback = callback;
2311 data->user_data = user_data;
2313 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2314 inet_rtnl_timeout_cb, data);
2316 data->channel = g_io_channel_unix_new(rtnl->fd);
2318 g_io_channel_set_encoding(data->channel, NULL, NULL);
2319 g_io_channel_set_buffered(data->channel, FALSE);
2321 data->watch_id = g_io_add_watch(data->channel,
2322 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2323 inet_rtnl_event, data);
2325 n->nlmsg_flags |= NLM_F_ACK;
2327 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2328 (struct sockaddr *) &nladdr, sizeof(nladdr));
2329 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2331 connman_error("Can not talk to rtnetlink err %d %s",
2332 -errno, strerror(errno));
2336 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2337 connman_error("Sent %d bytes, msg truncated", err);
2344 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2346 DBG("handle %p", rth);
2354 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2357 int len = RTA_LENGTH(4);
2360 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2361 DBG("Error! max allowed bound %zd exceeded", maxlen);
2364 rta = NLMSG_TAIL(n);
2365 rta->rta_type = type;
2367 memcpy(RTA_DATA(rta), &data, 4);
2368 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2373 static int parse_rtattr(struct rtattr *tb[], int max,
2374 struct rtattr *rta, int len)
2376 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2377 while (RTA_OK(rta, len)) {
2378 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2379 tb[rta->rta_type] = rta;
2380 rta = RTA_NEXT(rta, len);
2383 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2388 struct get_route_cb_data {
2389 connman_inet_addr_cb_t callback;
2393 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2395 struct get_route_cb_data *data = user_data;
2396 struct rtattr *tb[RTA_MAX+1];
2397 struct rtmsg *r = NLMSG_DATA(answer);
2398 int len, index = -1;
2400 const char *addr = NULL;
2402 DBG("answer %p data %p", answer, user_data);
2407 len = answer->nlmsg_len;
2409 if (answer->nlmsg_type != RTM_NEWROUTE &&
2410 answer->nlmsg_type != RTM_DELROUTE) {
2411 connman_error("Not a route: %08x %08x %08x",
2412 answer->nlmsg_len, answer->nlmsg_type,
2413 answer->nlmsg_flags);
2417 len -= NLMSG_LENGTH(sizeof(*r));
2419 connman_error("BUG: wrong nlmsg len %d", len);
2423 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2426 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2428 if (tb[RTA_GATEWAY])
2429 addr = inet_ntop(r->rtm_family,
2430 RTA_DATA(tb[RTA_GATEWAY]),
2431 abuf, sizeof(abuf));
2433 DBG("addr %s index %d user %p", addr, index, data->user_data);
2436 if (data && data->callback)
2437 data->callback(addr, index, data->user_data);
2445 * Return the interface index that contains route to host.
2447 int __connman_inet_get_route(const char *dest_address,
2448 connman_inet_addr_cb_t callback, void *user_data)
2450 struct get_route_cb_data *data;
2451 struct addrinfo hints, *rp;
2452 struct __connman_inet_rtnl_handle *rth;
2455 DBG("dest %s", dest_address);
2460 memset(&hints, 0, sizeof(hints));
2461 hints.ai_family = AF_UNSPEC;
2462 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2464 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2468 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2474 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2475 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2476 rth->req.n.nlmsg_type = RTM_GETROUTE;
2477 rth->req.u.r.rt.rtm_family = rp->ai_family;
2478 rth->req.u.r.rt.rtm_table = 0;
2479 rth->req.u.r.rt.rtm_protocol = 0;
2480 rth->req.u.r.rt.rtm_scope = 0;
2481 rth->req.u.r.rt.rtm_type = 0;
2482 rth->req.u.r.rt.rtm_src_len = 0;
2483 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2484 rth->req.u.r.rt.rtm_tos = 0;
2486 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2487 &rp->ai_addr, rp->ai_addrlen);
2491 err = __connman_inet_rtnl_open(rth);
2495 data = g_try_malloc(sizeof(struct get_route_cb_data));
2501 data->callback = callback;
2502 data->user_data = user_data;
2504 #define GET_ROUTE_TIMEOUT 2
2505 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2506 get_route_cb, data);
2515 __connman_inet_rtnl_close(rth);
2522 int connman_inet_check_ipaddress(const char *host)
2524 struct addrinfo hints;
2525 struct addrinfo *addr;
2528 memset(&hints, 0, sizeof(struct addrinfo));
2529 hints.ai_flags = AI_NUMERICHOST;
2532 result = getaddrinfo(host, NULL, &hints, &addr);
2534 result = addr->ai_family;
2540 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2541 bool connman_inet_check_hostname(const char *ptr, size_t len)
2546 * Not empty or complete length not over 255 characters.
2548 if ((len == 0) || (len > 256))
2552 * Consists of [[:alnum:]-]+ labels separated by [.]
2553 * a [_] is against RFC but seems to be "widely used"
2555 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2557 if ((*p == '-') || (*p == '_')) {
2559 * Not allowed at begin or end of a label.
2561 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2564 } else if (*p == '.') {
2566 * Each label has to be 1-63 characters;
2567 * we allow [.] at the end ('foo.bar.')
2571 if ((d <= 0) || (d >= 64))
2574 ptr = p + 1; /* Jump to the next label */
2576 } else if (isalnum((unsigned char)*p) == 0) {
2578 * Also numbers at the begin are fine
2587 char **__connman_inet_get_running_interfaces(void)
2591 struct ifreq *ifr = NULL;
2592 int sk, i, numif, count = 0;
2594 memset(&ifc, 0, sizeof(ifc));
2596 sk = socket(AF_INET, SOCK_DGRAM, 0);
2600 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2604 * Allocate some extra bytes just in case there will
2605 * be new interfaces added between two SIOCGIFCONF
2608 ifr = g_try_malloc0(ifc.ifc_len * 2);
2614 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2617 numif = ifc.ifc_len / sizeof(struct ifreq);
2619 result = g_try_malloc0((numif + 1) * sizeof(char *));
2625 for (i = 0; i < numif; i++) {
2626 struct ifreq *r = &ifr[i];
2627 struct in6_addr *addr6;
2631 * Note that we do not return loopback interfaces here as they
2632 * are not needed for our purposes.
2634 switch (r->ifr_addr.sa_family) {
2636 addr4 = ntohl(((struct sockaddr_in *)
2637 &r->ifr_addr)->sin_addr.s_addr);
2638 if (((addr4 & 0xff000000) >> 24) == 127)
2642 addr6 = &((struct sockaddr_in6 *)
2643 &r->ifr_addr)->sin6_addr;
2644 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2649 result[count++] = g_strdup(r->ifr_name);
2654 if (count < numif) {
2655 char **prev_result = result;
2656 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2658 g_free(prev_result);
2671 bool connman_inet_is_ipv6_supported()
2675 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2683 int __connman_inet_get_interface_address(int index, int family, void *address)
2685 struct ifaddrs *ifaddr, *ifa;
2687 char name[IF_NAMESIZE];
2689 if (!if_indextoname(index, name))
2692 DBG("index %d interface %s", index, name);
2694 if (getifaddrs(&ifaddr) < 0) {
2696 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2700 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2704 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2705 ifa->ifa_addr->sa_family == family) {
2706 if (family == AF_INET) {
2707 struct sockaddr_in *in4 = (struct sockaddr_in *)
2709 if (in4->sin_addr.s_addr == INADDR_ANY)
2711 memcpy(address, &in4->sin_addr,
2712 sizeof(struct in_addr));
2713 } else if (family == AF_INET6) {
2714 struct sockaddr_in6 *in6 =
2715 (struct sockaddr_in6 *)ifa->ifa_addr;
2716 if (memcmp(&in6->sin6_addr, &in6addr_any,
2717 sizeof(struct in6_addr)) == 0)
2719 memcpy(address, &in6->sin6_addr,
2720 sizeof(struct in6_addr));
2733 freeifaddrs(ifaddr);
2737 static int iprule_modify(int cmd, int family, uint32_t table_id,
2740 struct __connman_inet_rtnl_handle rth;
2743 memset(&rth, 0, sizeof(rth));
2745 rth.req.n.nlmsg_type = cmd;
2746 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2747 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2748 rth.req.u.r.rt.rtm_family = family;
2749 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2750 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2751 rth.req.u.r.rt.rtm_table = table_id;
2752 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2753 rth.req.u.r.rt.rtm_flags = 0;
2755 if (cmd == RTM_NEWRULE) {
2756 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2757 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2760 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2761 FRA_FWMARK, fwmark);
2763 if (table_id < 256) {
2764 rth.req.u.r.rt.rtm_table = table_id;
2766 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2767 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2768 FRA_TABLE, table_id);
2771 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2772 rth.req.u.r.rt.rtm_family = AF_INET;
2774 ret = __connman_inet_rtnl_open(&rth);
2778 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2781 __connman_inet_rtnl_close(&rth);
2786 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2788 /* ip rule add fwmark 9876 table 1234 */
2790 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2793 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2795 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2798 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2799 const char *gateway)
2801 struct __connman_inet_rtnl_handle rth;
2802 unsigned char buf[sizeof(struct in6_addr)];
2804 int family = connman_inet_check_ipaddress(gateway);
2817 ret = inet_pton(family, gateway, buf);
2821 memset(&rth, 0, sizeof(rth));
2823 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2824 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
2825 rth.req.n.nlmsg_type = cmd;
2826 rth.req.u.r.rt.rtm_family = family;
2827 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
2828 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
2829 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2830 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2831 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2833 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
2835 if (table_id < 256) {
2836 rth.req.u.r.rt.rtm_table = table_id;
2838 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2839 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2840 RTA_TABLE, table_id);
2843 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2846 ret = __connman_inet_rtnl_open(&rth);
2850 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2853 __connman_inet_rtnl_close(&rth);
2858 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
2859 const char *gateway)
2861 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
2863 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
2866 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
2867 const char *gateway)
2869 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
2871 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
2874 int __connman_inet_get_interface_ll_address(int index, int family,
2877 struct ifaddrs *ifaddr, *ifa;
2879 char name[IF_NAMESIZE];
2881 if (!if_indextoname(index, name))
2884 DBG("index %d interface %s", index, name);
2886 if (getifaddrs(&ifaddr) < 0) {
2888 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2892 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2896 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2897 ifa->ifa_addr->sa_family == family) {
2898 if (family == AF_INET) {
2899 struct sockaddr_in *in4 = (struct sockaddr_in *)
2901 if (in4->sin_addr.s_addr == INADDR_ANY)
2903 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
2904 ((in_addr_t) 0xa9fe0000))
2906 memcpy(address, &in4->sin_addr,
2907 sizeof(struct in_addr));
2908 } else if (family == AF_INET6) {
2909 struct sockaddr_in6 *in6 =
2910 (struct sockaddr_in6 *)ifa->ifa_addr;
2911 if (memcmp(&in6->sin6_addr, &in6addr_any,
2912 sizeof(struct in6_addr)) == 0)
2914 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
2917 memcpy(address, &in6->sin6_addr,
2918 sizeof(struct in6_addr));
2930 freeifaddrs(ifaddr);
2934 int __connman_inet_get_address_netmask(int ifindex,
2935 struct sockaddr_in *address,
2936 struct sockaddr_in *netmask)
2938 int sk, ret = -EINVAL;
2941 DBG("index %d", ifindex);
2943 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2947 memset(&ifr, 0, sizeof(ifr));
2948 ifr.ifr_ifindex = ifindex;
2950 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
2953 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
2956 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
2957 sizeof(struct sockaddr_in));
2959 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
2962 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
2963 sizeof(struct sockaddr_in));
2971 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
2972 struct in_addr *addr)
2976 char addrstr[INET_ADDRSTRLEN];
2977 struct in_addr taddr;
2978 GError *error = NULL;
2979 char *cmdline = NULL;
2982 char **pnpent = NULL;
2987 cmdline_file = "/proc/cmdline";
2989 pnp_file = "/proc/net/pnp";
2992 addr->s_addr = INADDR_NONE;
2994 if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
2995 connman_error("%s: Cannot read %s %s\n", __func__,
2996 cmdline_file, error->message);
3000 if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3001 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3002 connman_error("%s: Cannot read %s %s\n", __func__,
3003 pnp_file, error->message);
3007 connman_error("%s: File %s doesn't exist\n", __func__, pnp_file);
3011 len = strlen(cmdline);
3016 /* remove newline */
3017 if (cmdline[len - 1] == '\n')
3018 cmdline[--len] = '\0';
3020 /* split in arguments (seperated by space) */
3021 args = g_strsplit(cmdline, " ", 0);
3023 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3028 /* split in entries (by newlines) */
3029 pnpent = g_strsplit(pnp, "\n", 0);
3031 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3036 /* first find root argument */
3037 for (pp = args; *pp; pp++) {
3038 if (!strcmp(*pp, "root=/dev/nfs"))
3041 /* no rootnfs found */
3045 /* locate nfsroot argument */
3046 for (pp = args; *pp; pp++) {
3047 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3050 /* no nfsroot argument found */
3054 /* determine if nfsroot server is provided */
3055 nfsargs = strchr(*pp, '=');
3060 /* find whether serverip is present */
3061 s = strchr(nfsargs, ':');
3066 /* no serverip, use bootserver */
3067 for (pp = pnpent; *pp; pp++) {
3068 if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3071 /* no bootserver found */
3074 s = *pp + strlen("bootserver ");
3078 /* copy to addr string buffer */
3079 if (len >= sizeof(addrstr)) {
3080 connman_error("%s: Bad server\n", __func__);
3083 memcpy(addrstr, s, len);
3084 addrstr[len] = '\0';
3086 err = inet_pton(AF_INET, addrstr, addr);
3088 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3100 g_error_free(error);
3107 /* get interface out of which peer is reachable (IPv4 only) */
3108 static int get_peer_iface(struct in_addr *addr, char *ifname)
3110 struct ifaddrs *ifaddr, *ifa;
3111 struct sockaddr_in saddr, *ifsaddr;
3116 /* Obtain address(es) matching host/port */
3117 err = getifaddrs(&ifaddr);
3119 connman_error("%s: getifaddrs() failed %d (%s)\n",
3120 __func__, errno, strerror(errno));
3124 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3126 connman_error("%s: socket() failed %d (%s)\n",
3127 __func__, errno, strerror(errno));
3131 memset(&saddr, 0, sizeof(saddr));
3132 saddr.sin_family = AF_INET;
3133 saddr.sin_port = 0; /* any port */
3134 saddr.sin_addr = *addr;
3136 /* no need to bind, connect will select iface */
3137 err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3139 connman_error("%s: connect() failed: %d (%s)\n",
3140 __func__, errno, strerror(errno));
3144 socklen = sizeof(saddr);
3145 err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3147 connman_error("%s: getsockname() failed: %d (%s)\n",
3148 __func__, errno, strerror(errno));
3153 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3157 /* only IPv4 address */
3158 if (ifa->ifa_addr->sa_family != AF_INET)
3161 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3163 /* match address? */
3164 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3171 strcpy(ifname, ifa->ifa_name);
3177 freeifaddrs(ifaddr);
3182 bool __connman_inet_isrootnfs_device(const char *devname)
3184 struct in_addr addr;
3185 char ifname[IFNAMSIZ];
3187 return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3188 get_peer_iface(&addr, ifname) == 0 &&
3189 strcmp(devname, ifname) == 0;
3192 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3197 GError *error = NULL;
3199 char **pnpent = NULL;
3200 char **nameservers = NULL;
3203 pnp_file = "/proc/net/pnp";
3205 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3206 connman_error("%s: Cannot read %s %s\n", __func__,
3207 pnp_file, error->message);
3211 /* split in entries (by newlines) */
3212 pnpent = g_strsplit(pnp, "\n", 0);
3214 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3220 * Perform two passes to retreive a char ** array of
3221 * nameservers that are not 0.0.0.0
3223 * The first pass counts them, the second fills in the
3228 for (pass = 1; pass <= 2; pass++) {
3230 /* at the start of the second pass allocate */
3232 nameservers = g_new(char *, count + 1);
3235 for (pp = pnpent; *pp; pp++) {
3236 /* match 'nameserver ' at the start of each line */
3237 if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3240 /* compare it against 0.0.0.0 */
3241 s = *pp + strlen("nameserver ");
3242 if (!strcmp(s, "0.0.0.0"))
3245 /* on second pass fill in array */
3247 nameservers[count] = g_strdup(s);
3251 /* no nameservers? */
3255 /* and terminate char ** array with NULL */
3257 nameservers[count] = NULL;
3265 g_error_free(error);