5 * Copyright (C) 2007-2012 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>
51 #define NLMSG_TAIL(nmsg) \
52 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
53 NLMSG_ALIGN((nmsg)->nlmsg_len)))
55 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
56 int type, const void *data, size_t data_length)
61 length = RTA_LENGTH(data_length);
63 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
68 rta->rta_len = length;
69 memcpy(RTA_DATA(rta), data, data_length);
70 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
75 int __connman_inet_modify_address(int cmd, int flags,
76 int index, int family,
79 unsigned char prefixlen,
80 const char *broadcast)
82 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
83 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
84 RTA_LENGTH(sizeof(struct in6_addr)) +
85 RTA_LENGTH(sizeof(struct in6_addr))];
87 struct nlmsghdr *header;
88 struct sockaddr_nl nl_addr;
89 struct ifaddrmsg *ifaddrmsg;
90 struct in6_addr ipv6_addr;
91 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
94 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
95 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
96 address, peer, prefixlen, broadcast);
101 if (family != AF_INET && family != AF_INET6)
104 memset(&request, 0, sizeof(request));
106 header = (struct nlmsghdr *)request;
107 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
108 header->nlmsg_type = cmd;
109 header->nlmsg_flags = NLM_F_REQUEST | flags;
110 header->nlmsg_seq = 1;
112 ifaddrmsg = NLMSG_DATA(header);
113 ifaddrmsg->ifa_family = family;
114 ifaddrmsg->ifa_prefixlen = prefixlen;
115 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
116 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
117 ifaddrmsg->ifa_index = index;
119 if (family == AF_INET) {
120 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
123 if (broadcast != NULL)
124 inet_pton(AF_INET, broadcast, &ipv4_bcast);
126 ipv4_bcast.s_addr = ipv4_addr.s_addr |
127 htonl(0xfffffffflu >> prefixlen);
130 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
133 err = __connman_inet_rtnl_addattr_l(header,
142 err = __connman_inet_rtnl_addattr_l(header,
150 err = __connman_inet_rtnl_addattr_l(header,
158 } else if (family == AF_INET6) {
159 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
162 err = __connman_inet_rtnl_addattr_l(header,
171 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
175 memset(&nl_addr, 0, sizeof(nl_addr));
176 nl_addr.nl_family = AF_NETLINK;
178 if ((err = sendto(sk, request, header->nlmsg_len, 0,
179 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
190 int connman_inet_ifindex(const char *name)
198 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
202 memset(&ifr, 0, sizeof(ifr));
203 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
205 err = ioctl(sk, SIOCGIFINDEX, &ifr);
212 return ifr.ifr_ifindex;
215 char *connman_inet_ifname(int index)
223 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
227 memset(&ifr, 0, sizeof(ifr));
228 ifr.ifr_ifindex = index;
230 err = ioctl(sk, SIOCGIFNAME, &ifr);
237 return strdup(ifr.ifr_name);
240 short int connman_inet_ifflags(int index)
245 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
249 memset(&ifr, 0, sizeof(ifr));
250 ifr.ifr_ifindex = index;
252 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
257 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
270 int connman_inet_ifup(int index)
275 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
279 memset(&ifr, 0, sizeof(ifr));
280 ifr.ifr_ifindex = index;
282 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
287 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
292 if (ifr.ifr_flags & IFF_UP) {
297 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
299 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
312 int connman_inet_ifdown(int index)
314 struct ifreq ifr, addr_ifr;
315 struct sockaddr_in *addr;
318 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
322 memset(&ifr, 0, sizeof(ifr));
323 ifr.ifr_ifindex = index;
325 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
330 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
335 memset(&addr_ifr, 0, sizeof(addr_ifr));
336 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name));
337 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
338 addr->sin_family = AF_INET;
339 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
340 connman_warn("Could not clear IPv4 address index %d", index);
342 if (!(ifr.ifr_flags & IFF_UP)) {
347 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
349 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
360 connman_bool_t connman_inet_is_cfg80211(int index)
362 connman_bool_t result = FALSE;
363 char phy80211_path[PATH_MAX];
368 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
372 memset(&ifr, 0, sizeof(ifr));
373 ifr.ifr_ifindex = index;
375 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
378 snprintf(phy80211_path, PATH_MAX,
379 "/sys/class/net/%s/phy80211", ifr.ifr_name);
381 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
391 struct in6_addr ifr6_addr;
392 __u32 ifr6_prefixlen;
393 unsigned int ifr6_ifindex;
396 int connman_inet_set_ipv6_address(int index,
397 struct connman_ipaddress *ipaddress)
400 unsigned char prefix_len;
403 if (ipaddress->local == NULL)
406 prefix_len = ipaddress->prefixlen;
407 address = ipaddress->local;
409 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
411 err = __connman_inet_modify_address(RTM_NEWADDR,
412 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
413 address, NULL, prefix_len, NULL);
415 connman_error("%s: %s", __func__, strerror(-err));
422 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
425 unsigned char prefix_len;
426 const char *address, *broadcast, *peer;
428 if (ipaddress->local == NULL)
431 prefix_len = ipaddress->prefixlen;
432 address = ipaddress->local;
433 broadcast = ipaddress->broadcast;
434 peer = ipaddress->peer;
436 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
438 err = __connman_inet_modify_address(RTM_NEWADDR,
439 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
440 address, peer, prefix_len, broadcast);
442 connman_error("%s: %s", __func__, strerror(-err));
449 int connman_inet_clear_ipv6_address(int index, const char *address,
454 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
456 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
457 address, NULL, prefix_len, NULL);
459 connman_error("%s: %s", __func__, strerror(-err));
466 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
469 unsigned char prefix_len;
470 const char *address, *broadcast, *peer;
472 prefix_len = ipaddress->prefixlen;
473 address = ipaddress->local;
474 broadcast = ipaddress->broadcast;
475 peer = ipaddress->peer;
477 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
479 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
480 address, peer, prefix_len, broadcast);
482 connman_error("%s: %s", __func__, strerror(-err));
489 int connman_inet_add_host_route(int index, const char *host,
492 return connman_inet_add_network_route(index, host, gateway, NULL);
495 int connman_inet_del_host_route(int index, const char *host)
497 return connman_inet_del_network_route(index, host);
500 int connman_inet_add_network_route(int index, const char *host,
506 struct sockaddr_in addr;
509 DBG("index %d host %s gateway %s netmask %s", index,
510 host, gateway, netmask);
512 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
516 memset(&ifr, 0, sizeof(ifr));
517 ifr.ifr_ifindex = index;
519 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
524 DBG("ifname %s", ifr.ifr_name);
526 memset(&rt, 0, sizeof(rt));
527 rt.rt_flags = RTF_UP;
529 rt.rt_flags |= RTF_GATEWAY;
531 rt.rt_flags |= RTF_HOST;
533 memset(&addr, 0, sizeof(addr));
534 addr.sin_family = AF_INET;
535 addr.sin_addr.s_addr = inet_addr(host);
536 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
538 memset(&addr, 0, sizeof(addr));
539 addr.sin_family = AF_INET;
541 addr.sin_addr.s_addr = inet_addr(gateway);
543 addr.sin_addr.s_addr = INADDR_ANY;
544 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
546 memset(&addr, 0, sizeof(addr));
547 addr.sin_family = AF_INET;
548 addr.sin_addr.s_addr = INADDR_ANY;
550 addr.sin_addr.s_addr = inet_addr(netmask);
552 addr.sin_addr.s_addr = INADDR_ANY;
553 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
555 rt.rt_dev = ifr.ifr_name;
557 err = ioctl(sk, SIOCADDRT, &rt);
559 connman_error("Adding host route failed (%s)",
567 int connman_inet_del_network_route(int index, const char *host)
571 struct sockaddr_in addr;
574 DBG("index %d host %s", index, host);
576 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) {
588 DBG("ifname %s", ifr.ifr_name);
590 memset(&rt, 0, sizeof(rt));
591 rt.rt_flags = RTF_UP | RTF_HOST;
593 memset(&addr, 0, sizeof(addr));
594 addr.sin_family = AF_INET;
595 addr.sin_addr.s_addr = inet_addr(host);
596 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
598 rt.rt_dev = ifr.ifr_name;
600 err = ioctl(sk, SIOCDELRT, &rt);
602 connman_error("Deleting host route failed (%s)",
610 int connman_inet_del_ipv6_network_route(int index, const char *host,
611 unsigned char prefix_len)
616 DBG("index %d host %s", index, host);
621 memset(&rt, 0, sizeof(rt));
623 rt.rtmsg_dst_len = prefix_len;
625 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
629 rt.rtmsg_flags = RTF_UP | RTF_HOST;
632 rt.rtmsg_ifindex = index;
634 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
640 err = ioctl(sk, SIOCDELRT, &rt);
644 connman_error("Del IPv6 host route error (%s)",
650 int connman_inet_del_ipv6_host_route(int index, const char *host)
652 return connman_inet_del_ipv6_network_route(index, host, 128);
655 int connman_inet_add_ipv6_network_route(int index, const char *host,
657 unsigned char prefix_len)
662 DBG("index %d host %s gateway %s", index, host, gateway);
667 memset(&rt, 0, sizeof(rt));
669 rt.rtmsg_dst_len = prefix_len;
671 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
675 rt.rtmsg_flags = RTF_UP | RTF_HOST;
677 if (gateway != NULL) {
678 rt.rtmsg_flags |= RTF_GATEWAY;
679 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
683 rt.rtmsg_ifindex = index;
685 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
691 err = ioctl(sk, SIOCADDRT, &rt);
695 connman_error("Set IPv6 host route error (%s)",
701 int connman_inet_add_ipv6_host_route(int index, const char *host,
704 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
707 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
712 DBG("index %d gateway %s", index, gateway);
717 memset(&rt, 0, sizeof(rt));
719 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
723 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
725 rt.rtmsg_dst_len = 0;
726 rt.rtmsg_ifindex = index;
728 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
734 err = ioctl(sk, SIOCADDRT, &rt);
738 connman_error("Set default IPv6 gateway error (%s)",
744 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
749 DBG("index %d gateway %s", index, gateway);
754 memset(&rt, 0, sizeof(rt));
756 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
760 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
762 rt.rtmsg_dst_len = 0;
763 rt.rtmsg_ifindex = index;
765 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
771 err = ioctl(sk, SIOCDELRT, &rt);
775 connman_error("Clear default IPv6 gateway error (%s)",
781 int connman_inet_set_gateway_address(int index, const char *gateway)
785 struct sockaddr_in addr;
788 DBG("index %d gateway %s", index, gateway);
790 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
794 memset(&ifr, 0, sizeof(ifr));
795 ifr.ifr_ifindex = index;
797 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
802 DBG("ifname %s", ifr.ifr_name);
804 memset(&rt, 0, sizeof(rt));
805 rt.rt_flags = RTF_UP | RTF_GATEWAY;
807 memset(&addr, 0, sizeof(addr));
808 addr.sin_family = AF_INET;
809 addr.sin_addr.s_addr = INADDR_ANY;
810 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
812 memset(&addr, 0, sizeof(addr));
813 addr.sin_family = AF_INET;
814 addr.sin_addr.s_addr = inet_addr(gateway);
815 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
817 memset(&addr, 0, sizeof(addr));
818 addr.sin_family = AF_INET;
819 addr.sin_addr.s_addr = INADDR_ANY;
820 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
822 err = ioctl(sk, SIOCADDRT, &rt);
824 connman_error("Setting default gateway route failed (%s)",
832 int connman_inet_set_gateway_interface(int index)
836 struct sockaddr_in addr;
839 DBG("index %d", index);
841 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) {
853 DBG("ifname %s", ifr.ifr_name);
855 memset(&rt, 0, sizeof(rt));
856 rt.rt_flags = RTF_UP;
858 memset(&addr, 0, sizeof(addr));
859 addr.sin_family = AF_INET;
860 addr.sin_addr.s_addr = INADDR_ANY;
862 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
863 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
864 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
866 rt.rt_dev = ifr.ifr_name;
868 err = ioctl(sk, SIOCADDRT, &rt);
870 connman_error("Setting default interface route failed (%s)",
877 int connman_inet_set_ipv6_gateway_interface(int index)
881 struct sockaddr_in6 addr;
882 const struct in6_addr any = IN6ADDR_ANY_INIT;
885 DBG("index %d", index);
887 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
891 memset(&ifr, 0, sizeof(ifr));
892 ifr.ifr_ifindex = index;
894 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
899 DBG("ifname %s", ifr.ifr_name);
901 memset(&rt, 0, sizeof(rt));
902 rt.rt_flags = RTF_UP;
904 memset(&addr, 0, sizeof(addr));
905 addr.sin6_family = AF_INET6;
906 addr.sin6_addr = any;
908 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
909 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
910 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
912 rt.rt_dev = ifr.ifr_name;
914 err = ioctl(sk, SIOCADDRT, &rt);
916 connman_error("Setting default interface route failed (%s)",
923 int connman_inet_clear_gateway_address(int index, const char *gateway)
927 struct sockaddr_in addr;
930 DBG("index %d gateway %s", index, gateway);
932 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
936 memset(&ifr, 0, sizeof(ifr));
937 ifr.ifr_ifindex = index;
939 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
944 DBG("ifname %s", ifr.ifr_name);
946 memset(&rt, 0, sizeof(rt));
947 rt.rt_flags = RTF_UP | RTF_GATEWAY;
949 memset(&addr, 0, sizeof(addr));
950 addr.sin_family = AF_INET;
951 addr.sin_addr.s_addr = INADDR_ANY;
952 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
954 memset(&addr, 0, sizeof(addr));
955 addr.sin_family = AF_INET;
956 addr.sin_addr.s_addr = inet_addr(gateway);
957 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
959 memset(&addr, 0, sizeof(addr));
960 addr.sin_family = AF_INET;
961 addr.sin_addr.s_addr = INADDR_ANY;
962 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
964 err = ioctl(sk, SIOCDELRT, &rt);
966 connman_error("Removing default gateway route failed (%s)",
974 int connman_inet_clear_gateway_interface(int index)
978 struct sockaddr_in addr;
981 DBG("index %d", index);
983 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
987 memset(&ifr, 0, sizeof(ifr));
988 ifr.ifr_ifindex = index;
990 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
995 DBG("ifname %s", ifr.ifr_name);
997 memset(&rt, 0, sizeof(rt));
998 rt.rt_flags = RTF_UP;
1000 memset(&addr, 0, sizeof(addr));
1001 addr.sin_family = AF_INET;
1002 addr.sin_addr.s_addr = INADDR_ANY;
1004 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1005 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1006 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1008 rt.rt_dev = ifr.ifr_name;
1010 err = ioctl(sk, SIOCDELRT, &rt);
1012 connman_error("Removing default interface route failed (%s)",
1019 int connman_inet_clear_ipv6_gateway_interface(int index)
1023 struct sockaddr_in6 addr;
1024 const struct in6_addr any = IN6ADDR_ANY_INIT;
1027 DBG("index %d", index);
1029 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1033 memset(&ifr, 0, sizeof(ifr));
1034 ifr.ifr_ifindex = index;
1036 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1041 DBG("ifname %s", ifr.ifr_name);
1043 memset(&rt, 0, sizeof(rt));
1044 rt.rt_flags = RTF_UP;
1046 memset(&addr, 0, sizeof(addr));
1047 addr.sin6_family = AF_INET6;
1048 addr.sin6_addr = any;
1050 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1051 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1052 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1054 rt.rt_dev = ifr.ifr_name;
1056 err = ioctl(sk, SIOCDELRT, &rt);
1058 connman_error("Removing default interface route failed (%s)",
1065 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1068 struct in_addr _host_addr;
1069 in_addr_t host_addr, netmask_addr, if_addr;
1070 struct sockaddr_in *netmask, *addr;
1073 DBG("host %s", host);
1078 if (inet_aton(host, &_host_addr) == 0)
1080 host_addr = _host_addr.s_addr;
1082 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1086 memset(&ifr, 0, sizeof(ifr));
1087 ifr.ifr_ifindex = index;
1089 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1094 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1099 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1100 netmask_addr = netmask->sin_addr.s_addr;
1102 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1109 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1110 if_addr = addr->sin_addr.s_addr;
1112 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1115 int connman_inet_remove_from_bridge(int index, const char *bridge)
1123 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1127 memset(&ifr, 0, sizeof(ifr));
1128 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1129 ifr.ifr_ifindex = index;
1131 err = ioctl(sk, SIOCBRDELIF, &ifr);
1136 connman_error("Remove interface from bridge error %s",
1144 int connman_inet_add_to_bridge(int index, const char *bridge)
1152 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1156 memset(&ifr, 0, sizeof(ifr));
1157 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1158 ifr.ifr_ifindex = index;
1160 err = ioctl(sk, SIOCBRADDIF, &ifr);
1165 connman_error("Add interface to bridge error %s",
1173 int connman_inet_set_mtu(int index, int mtu)
1178 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1182 memset(&ifr, 0, sizeof(ifr));
1183 ifr.ifr_ifindex = index;
1185 err = ioctl(sk, SIOCGIFNAME, &ifr);
1188 err = ioctl(sk, SIOCSIFMTU, &ifr);
1195 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1205 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1209 index = if_nametoindex(tunnel);
1211 err = connman_inet_set_mtu(index, mtu);
1215 memset(&ifr, 0, sizeof(ifr));
1216 strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1217 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1224 if ((ifr.ifr_flags ^ flags) & mask) {
1225 ifr.ifr_flags &= ~mask;
1226 ifr.ifr_flags |= mask & flags;
1227 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1229 connman_error("SIOCSIFFLAGS failed: %s",
1238 int connman_inet_create_tunnel(char **iface)
1243 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1246 connman_error("Failed to open /dev/net/tun: %s",
1251 memset(&ifr, 0, sizeof(ifr));
1252 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1254 for (i = 0; i < 256; i++) {
1255 sprintf(ifr.ifr_name, "tun%d", i);
1257 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1262 connman_error("Failed to find available tun device");
1267 *iface = g_strdup(ifr.ifr_name);
1273 GIOChannel *channel;
1274 __connman_inet_rs_cb_t callback;
1275 struct sockaddr_in6 addr;
1281 #define CMSG_BUF_LEN 512
1282 #define IN6ADDR_ALL_NODES_MC_INIT \
1283 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1284 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1285 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1287 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1288 static const struct in6_addr in6addr_all_routers_mc =
1289 IN6ADDR_ALL_ROUTERS_MC_INIT;
1291 static void rs_cleanup(struct rs_cb_data *data)
1293 if (data->channel != NULL) {
1294 g_io_channel_shutdown(data->channel, TRUE, NULL);
1295 g_io_channel_unref(data->channel);
1296 data->channel = NULL;
1299 if (data->rs_timeout > 0)
1300 g_source_remove(data->rs_timeout);
1302 if (data->watch_id > 0)
1303 g_source_remove(data->watch_id);
1308 static gboolean rs_timeout_cb(gpointer user_data)
1310 struct rs_cb_data *data = user_data;
1312 DBG("user data %p", user_data);
1317 if (data->callback != NULL)
1318 data->callback(NULL, 0, data->user_data);
1320 data->rs_timeout = 0;
1325 static int icmpv6_recv(int fd, gpointer user_data)
1329 unsigned char chdr[CMSG_BUF_LEN];
1330 unsigned char buf[1540];
1331 struct rs_cb_data *data = user_data;
1332 struct nd_router_advert *hdr;
1333 struct sockaddr_in6 saddr;
1338 iov.iov_len = sizeof(buf);
1341 mhdr.msg_name = (void *)&saddr;
1342 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1343 mhdr.msg_iov = &iov;
1344 mhdr.msg_iovlen = 1;
1345 mhdr.msg_control = (void *)chdr;
1346 mhdr.msg_controllen = CMSG_BUF_LEN;
1348 len = recvmsg(fd, &mhdr, 0);
1350 data->callback(NULL, 0, data->user_data);
1355 hdr = (struct nd_router_advert *)buf;
1356 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1357 sizeof(struct nd_router_advert));
1358 if (hdr->nd_ra_code != 0)
1361 data->callback(hdr, len, data->user_data);
1367 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1374 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1377 fd = g_io_channel_unix_get_fd(chan);
1378 ret = icmpv6_recv(fd, data);
1385 /* Adapted from RFC 1071 "C" Implementation Example */
1386 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1388 register unsigned long sum = 0;
1393 /* caller must make sure datalen is even */
1395 addr = (uint16_t *)phdr;
1396 for (i = 0; i < 20; i++)
1400 addr = (uint16_t *)data;
1408 sum = (sum & 0xffff) + (sum >> 16);
1410 return (uint16_t)~sum;
1413 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1416 struct in6_addr src;
1417 struct in6_addr dst;
1419 uint8_t reserved[3];
1426 struct icmp6_hdr icmp;
1427 struct nd_neighbor_solicit ns;
1428 struct nd_router_solicit rs;
1433 struct cmsghdr *cmsg;
1434 struct in6_pktinfo *pinfo;
1435 struct sockaddr_in6 dst;
1436 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1438 int fd, datalen, ret;
1442 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1446 memset(&frame, 0, sizeof(frame));
1447 memset(&dst, 0, sizeof(dst));
1449 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1450 dst.sin6_addr = *dest;
1452 /* Fill in the IPv6 header */
1453 frame.ip.ip6_vfc = 0x60;
1454 frame.ip.ip6_plen = htons(datalen);
1455 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1456 frame.ip.ip6_hlim = 255;
1457 frame.ip.ip6_dst = dst.sin6_addr;
1458 /* all other fields are already set to zero */
1460 /* Prepare pseudo header for csum */
1461 memset(&phdr, 0, sizeof(phdr));
1462 phdr.dst = dst.sin6_addr;
1463 phdr.plen = htonl(datalen);
1464 phdr.nxt = IPPROTO_ICMPV6;
1466 /* Fill in remaining ICMP header fields */
1467 frame.i.icmp.icmp6_type = type;
1468 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1470 iov.iov_base = &frame;
1471 iov.iov_len = sizeof(frame.ip) + datalen;
1473 dst.sin6_family = AF_INET6;
1474 msgh.msg_name = &dst;
1475 msgh.msg_namelen = sizeof(dst);
1476 msgh.msg_iov = &iov;
1477 msgh.msg_iovlen = 1;
1480 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1481 cmsg = (struct cmsghdr *)cbuf;
1482 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1483 pinfo->ipi6_ifindex = oif;
1485 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1486 cmsg->cmsg_level = IPPROTO_IPV6;
1487 cmsg->cmsg_type = IPV6_PKTINFO;
1488 msgh.msg_control = cmsg;
1489 msgh.msg_controllen = cmsg->cmsg_len;
1491 ret = sendmsg(fd, &msgh, 0);
1497 static inline void ipv6_addr_set(struct in6_addr *addr,
1498 uint32_t w1, uint32_t w2,
1499 uint32_t w3, uint32_t w4)
1501 addr->s6_addr32[0] = w1;
1502 addr->s6_addr32[1] = w2;
1503 addr->s6_addr32[2] = w3;
1504 addr->s6_addr32[3] = w4;
1507 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1508 struct in6_addr *solicited)
1510 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1511 htonl(0xFF000000) | addr->s6_addr32[3]);
1514 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1517 unsigned int val = 0;
1518 struct ipv6_mreq mreq;
1521 memset(&mreq, 0, sizeof(mreq));
1522 mreq.ipv6mr_interface = ifindex;
1523 mreq.ipv6mr_multiaddr = *mc_addr;
1525 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1531 return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1534 int __connman_inet_ipv6_send_rs(int index, int timeout,
1535 __connman_inet_rs_cb_t callback, void *user_data)
1537 struct rs_cb_data *data;
1538 struct icmp6_filter filter;
1539 struct in6_addr solicit;
1540 struct in6_addr dst = in6addr_all_routers_mc;
1548 data = g_try_malloc0(sizeof(struct rs_cb_data));
1552 data->callback = callback;
1553 data->user_data = user_data;
1554 data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1556 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1560 ICMP6_FILTER_SETBLOCKALL(&filter);
1561 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1563 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1564 sizeof(struct icmp6_filter));
1566 ipv6_addr_solict_mult(&dst, &solicit);
1567 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1568 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1570 data->channel = g_io_channel_unix_new(sk);
1571 g_io_channel_set_close_on_unref(data->channel, TRUE);
1573 g_io_channel_set_encoding(data->channel, NULL, NULL);
1574 g_io_channel_set_buffered(data->channel, FALSE);
1576 data->watch_id = g_io_add_watch(data->channel,
1577 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1578 icmpv6_event, data);
1580 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
1585 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
1586 unsigned int length)
1588 GSList *prefixes = NULL;
1592 if (length <= sizeof(struct nd_router_advert))
1595 len = length - sizeof(struct nd_router_advert);
1596 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
1599 struct nd_opt_prefix_info *pinfo;
1600 char prefix_str[INET6_ADDRSTRLEN+1], *str;
1607 optlen = pos[1] << 3;
1608 if (optlen == 0 || optlen > len)
1612 case ND_OPT_PREFIX_INFORMATION:
1613 pinfo = (struct nd_opt_prefix_info *)pos;
1614 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
1615 prefix_str, INET6_ADDRSTRLEN);
1619 str = g_strdup_printf("%s/%d", prefix,
1620 pinfo->nd_opt_pi_prefix_len);
1621 prefixes = g_slist_prepend(prefixes, str);
1623 DBG("prefix %s", str);
1635 static int get_dest_addr(int family, int index, char *buf, int len)
1641 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1645 memset(&ifr, 0, sizeof(ifr));
1646 ifr.ifr_ifindex = index;
1648 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1649 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
1654 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
1655 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
1660 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
1666 DBG("index %d %s", index, ifr.ifr_name);
1668 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
1669 connman_error("Get destination address failed (%s)",
1679 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
1682 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
1689 if (inet_ntop(family, addr, buf, len) == NULL) {
1690 DBG("error %d/%s", errno, strerror(errno));
1697 int connman_inet_get_dest_addr(int index, char **dest)
1699 char addr[INET_ADDRSTRLEN];
1702 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
1706 *dest = g_strdup(addr);
1708 DBG("destination %s", *dest);
1713 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
1715 char addr[INET6_ADDRSTRLEN];
1718 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
1722 *dest = g_strdup(addr);
1724 DBG("destination %s", *dest);
1729 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
1732 int rcvbuf = 1024 * 4;
1734 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
1736 connman_error("Can not open netlink socket: %s",
1741 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
1742 sizeof(sndbuf)) < 0) {
1743 connman_error("SO_SNDBUF: %s", strerror(errno));
1747 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
1748 sizeof(rcvbuf)) < 0) {
1749 connman_error("SO_RCVBUF: %s", strerror(errno));
1753 memset(&rth->local, 0, sizeof(rth->local));
1754 rth->local.nl_family = AF_NETLINK;
1755 rth->local.nl_groups = 0;
1757 if (bind(rth->fd, (struct sockaddr *)&rth->local,
1758 sizeof(rth->local)) < 0) {
1759 connman_error("Can not bind netlink socket: %s",
1764 rth->seq = time(NULL);
1766 DBG("fd %d", rth->fd);
1771 struct inet_rtnl_cb_data {
1772 GIOChannel *channel;
1773 __connman_inet_rtnl_cb_t callback;
1776 struct __connman_inet_rtnl_handle *rtnl;
1780 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
1782 struct __connman_inet_rtnl_handle *rth = data->rtnl;
1784 if (data->channel != NULL) {
1785 g_io_channel_shutdown(data->channel, TRUE, NULL);
1786 g_io_channel_unref(data->channel);
1787 data->channel = NULL;
1790 DBG("data %p", data);
1792 if (data->rtnl_timeout > 0)
1793 g_source_remove(data->rtnl_timeout);
1795 if (data->watch_id > 0)
1796 g_source_remove(data->watch_id);
1799 __connman_inet_rtnl_close(rth);
1806 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
1808 struct inet_rtnl_cb_data *data = user_data;
1810 DBG("user data %p", user_data);
1815 if (data->callback != NULL)
1816 data->callback(NULL, data->user_data);
1818 data->rtnl_timeout = 0;
1819 inet_rtnl_cleanup(data);
1823 static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
1825 struct inet_rtnl_cb_data *rtnl_data = user_data;
1826 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
1827 struct nlmsghdr *h = NULL;
1828 struct sockaddr_nl nladdr;
1829 socklen_t addr_len = sizeof(nladdr);
1830 unsigned char buf[4096];
1835 memset(buf, 0, sizeof(buf));
1836 memset(&nladdr, 0, sizeof(nladdr));
1838 fd = g_io_channel_unix_get_fd(chan);
1840 status = recvfrom(fd, buf, sizeof(buf), 0,
1841 (struct sockaddr *) &nladdr, &addr_len);
1843 if (errno == EINTR || errno == EAGAIN)
1852 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1853 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1860 struct nlmsgerr *err;
1864 if (!NLMSG_OK(h, len)) {
1869 if (h->nlmsg_seq != rth->seq) {
1871 DBG("skip %d/%d len %d", rth->seq,
1872 h->nlmsg_seq, h->nlmsg_len);
1874 len -= h->nlmsg_len;
1875 ptr += h->nlmsg_len;
1879 switch (h->nlmsg_type) {
1885 err = (struct nlmsgerr *)NLMSG_DATA(h);
1886 connman_error("RTNETLINK answers %s (%d)",
1887 strerror(-err->error), -err->error);
1894 if (h->nlmsg_seq == rth->seq) {
1895 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
1897 rtnl_data->callback(h, rtnl_data->user_data);
1899 inet_rtnl_cleanup(rtnl_data);
1905 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
1912 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1915 ret = inet_rtnl_recv(chan, user_data);
1922 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
1923 struct nlmsghdr *n, int timeout,
1924 __connman_inet_rtnl_cb_t callback, void *user_data)
1926 struct sockaddr_nl nladdr;
1927 struct inet_rtnl_cb_data *data;
1931 memset(&nladdr, 0, sizeof(nladdr));
1932 nladdr.nl_family = AF_NETLINK;
1934 n->nlmsg_seq = seq = ++rtnl->seq;
1936 if (callback != NULL) {
1937 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
1941 data->callback = callback;
1942 data->user_data = user_data;
1944 data->rtnl_timeout = g_timeout_add_seconds(timeout,
1945 inet_rtnl_timeout_cb, data);
1947 data->channel = g_io_channel_unix_new(rtnl->fd);
1948 g_io_channel_set_close_on_unref(data->channel, TRUE);
1950 g_io_channel_set_encoding(data->channel, NULL, NULL);
1951 g_io_channel_set_buffered(data->channel, FALSE);
1953 data->watch_id = g_io_add_watch(data->channel,
1954 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1955 inet_rtnl_event, data);
1957 n->nlmsg_flags |= NLM_F_ACK;
1959 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
1960 (struct sockaddr *) &nladdr, sizeof(nladdr));
1961 DBG("handle %p len %d err %d", rtnl, rtnl->req.n.nlmsg_len, err);
1963 connman_error("Can not talk to rtnetlink");
1967 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
1968 connman_error("Sent %d bytes, msg truncated", err);
1975 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
1977 DBG("handle %p", rth);
1985 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
1988 int len = RTA_LENGTH(4);
1991 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
1992 DBG("Error! max allowed bound %zd exceeded", maxlen);
1995 rta = NLMSG_TAIL(n);
1996 rta->rta_type = type;
1998 memcpy(RTA_DATA(rta), &data, 4);
1999 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2004 static int parse_rtattr(struct rtattr *tb[], int max,
2005 struct rtattr *rta, int len)
2007 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2008 while (RTA_OK(rta, len)) {
2009 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2010 tb[rta->rta_type] = rta;
2011 rta = RTA_NEXT(rta, len);
2014 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2019 struct get_route_cb_data {
2020 connman_inet_addr_cb_t callback;
2024 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2026 struct get_route_cb_data *data = user_data;
2027 struct rtattr *tb[RTA_MAX+1];
2028 struct rtmsg *r = NLMSG_DATA(answer);
2029 int len, index = -1;
2031 const char *addr = NULL;
2033 DBG("answer %p data %p", answer, user_data);
2038 len = answer->nlmsg_len;
2040 if (answer->nlmsg_type != RTM_NEWROUTE &&
2041 answer->nlmsg_type != RTM_DELROUTE) {
2042 connman_error("Not a route: %08x %08x %08x",
2043 answer->nlmsg_len, answer->nlmsg_type,
2044 answer->nlmsg_flags);
2048 len -= NLMSG_LENGTH(sizeof(*r));
2050 connman_error("BUG: wrong nlmsg len %d", len);
2054 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2056 if (tb[RTA_OIF] != NULL)
2057 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2059 if (tb[RTA_GATEWAY] != NULL)
2060 addr = inet_ntop(r->rtm_family,
2061 RTA_DATA(tb[RTA_GATEWAY]),
2062 abuf, sizeof(abuf));
2064 DBG("addr %s index %d user %p", addr, index, data->user_data);
2067 if (data != NULL && data->callback != NULL)
2068 data->callback(addr, index, data->user_data);
2076 * Return the interface index that contains route to host.
2078 int __connman_inet_get_route(const char *dest_address,
2079 connman_inet_addr_cb_t callback, void *user_data)
2081 struct get_route_cb_data *data;
2082 struct addrinfo hints, *rp;
2083 struct __connman_inet_rtnl_handle *rth;
2086 DBG("dest %s", dest_address);
2088 if (dest_address == NULL)
2091 memset(&hints, 0, sizeof(hints));
2092 hints.ai_family = AF_UNSPEC;
2093 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2095 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2099 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2105 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2106 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2107 rth->req.n.nlmsg_type = RTM_GETROUTE;
2108 rth->req.u.r.rt.rtm_family = rp->ai_family;
2109 rth->req.u.r.rt.rtm_table = 0;
2110 rth->req.u.r.rt.rtm_protocol = 0;
2111 rth->req.u.r.rt.rtm_scope = 0;
2112 rth->req.u.r.rt.rtm_type = 0;
2113 rth->req.u.r.rt.rtm_src_len = 0;
2114 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2115 rth->req.u.r.rt.rtm_tos = 0;
2117 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2118 &rp->ai_addr, rp->ai_addrlen);
2122 err = __connman_inet_rtnl_open(rth);
2126 data = g_try_malloc(sizeof(struct get_route_cb_data));
2132 data->callback = callback;
2133 data->user_data = user_data;
2135 #define GET_ROUTE_TIMEOUT 2
2136 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2137 get_route_cb, data);
2146 __connman_inet_rtnl_close(rth);
2153 int connman_inet_check_ipaddress(const char *host)
2155 struct addrinfo hints;
2156 struct addrinfo *addr;
2159 memset(&hints, 0, sizeof(struct addrinfo));
2160 hints.ai_flags = AI_NUMERICHOST;
2163 result = getaddrinfo(host, NULL, &hints, &addr);
2165 result = addr->ai_family;
2171 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2172 connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
2177 * Not empty or complete length not over 255 characters.
2179 if ((len == 0) || (len > 256))
2183 * Consists of [[:alnum:]-]+ labels separated by [.]
2184 * a [_] is against RFC but seems to be "widely used"
2186 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2188 if ((*p == '-') || (*p == '_')) {
2190 * Not allowed at begin or end of a label.
2192 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2195 } else if (*p == '.') {
2197 * Each label has to be 1-63 characters;
2198 * we allow [.] at the end ('foo.bar.')
2202 if ((d <= 0) || (d >= 64))
2205 ptr = p + 1; /* Jump to the next label */
2207 } else if (isalnum((unsigned char)*p) == 0) {
2209 * Also numbers at the begin are fine
2218 char **__connman_inet_get_running_interfaces(void)
2222 struct ifreq *ifr = NULL;
2223 int sk, i, numif, count = 0;
2225 memset(&ifc, 0, sizeof(ifc));
2227 sk = socket(AF_INET, SOCK_DGRAM, 0);
2231 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2235 * Allocate some extra bytes just in case there will
2236 * be new interfaces added between two SIOCGIFCONF
2239 ifr = g_try_malloc0(ifc.ifc_len * 2);
2245 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2248 numif = ifc.ifc_len / sizeof(struct ifreq);
2250 result = g_try_malloc0((numif + 1) * sizeof(char *));
2256 for (i = 0; i < numif; i++) {
2257 struct ifreq *r = &ifr[i];
2258 struct in6_addr *addr6;
2262 * Note that we do not return loopback interfaces here as they
2263 * are not needed for our purposes.
2265 switch (r->ifr_addr.sa_family) {
2267 addr4 = ntohl(((struct sockaddr_in *)
2268 &r->ifr_addr)->sin_addr.s_addr);
2269 if (((addr4 & 0xff000000) >> 24) == 127)
2273 addr6 = &((struct sockaddr_in6 *)
2274 &r->ifr_addr)->sin6_addr;
2275 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2280 result[count++] = g_strdup(r->ifr_name);
2286 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2296 connman_bool_t connman_inet_is_ipv6_supported()
2300 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);