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>
52 #define NLMSG_TAIL(nmsg) \
53 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
54 NLMSG_ALIGN((nmsg)->nlmsg_len)))
56 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
57 int type, const void *data, size_t data_length)
62 length = RTA_LENGTH(data_length);
64 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
69 rta->rta_len = length;
70 memcpy(RTA_DATA(rta), data, data_length);
71 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
76 int __connman_inet_modify_address(int cmd, int flags,
77 int index, int family,
80 unsigned char prefixlen,
81 const char *broadcast)
83 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
84 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
85 RTA_LENGTH(sizeof(struct in6_addr)) +
86 RTA_LENGTH(sizeof(struct in6_addr))];
88 struct nlmsghdr *header;
89 struct sockaddr_nl nl_addr;
90 struct ifaddrmsg *ifaddrmsg;
91 struct in6_addr ipv6_addr;
92 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
95 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
96 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
97 address, peer, prefixlen, broadcast);
102 if (family != AF_INET && family != AF_INET6)
105 memset(&request, 0, sizeof(request));
107 header = (struct nlmsghdr *)request;
108 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
109 header->nlmsg_type = cmd;
110 header->nlmsg_flags = NLM_F_REQUEST | flags;
111 header->nlmsg_seq = 1;
113 ifaddrmsg = NLMSG_DATA(header);
114 ifaddrmsg->ifa_family = family;
115 ifaddrmsg->ifa_prefixlen = prefixlen;
116 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
117 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
118 ifaddrmsg->ifa_index = index;
120 if (family == AF_INET) {
121 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
124 if (broadcast != NULL)
125 inet_pton(AF_INET, broadcast, &ipv4_bcast);
127 ipv4_bcast.s_addr = ipv4_addr.s_addr |
128 htonl(0xfffffffflu >> prefixlen);
131 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
134 err = __connman_inet_rtnl_addattr_l(header,
143 err = __connman_inet_rtnl_addattr_l(header,
151 err = __connman_inet_rtnl_addattr_l(header,
159 } else if (family == AF_INET6) {
160 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
163 err = __connman_inet_rtnl_addattr_l(header,
172 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
176 memset(&nl_addr, 0, sizeof(nl_addr));
177 nl_addr.nl_family = AF_NETLINK;
179 if ((err = sendto(sk, request, header->nlmsg_len, 0,
180 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
191 int connman_inet_ifindex(const char *name)
199 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
203 memset(&ifr, 0, sizeof(ifr));
204 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
206 err = ioctl(sk, SIOCGIFINDEX, &ifr);
213 return ifr.ifr_ifindex;
216 char *connman_inet_ifname(int index)
224 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
228 memset(&ifr, 0, sizeof(ifr));
229 ifr.ifr_ifindex = index;
231 err = ioctl(sk, SIOCGIFNAME, &ifr);
238 return g_strdup(ifr.ifr_name);
241 short int connman_inet_ifflags(int index)
246 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
250 memset(&ifr, 0, sizeof(ifr));
251 ifr.ifr_ifindex = index;
253 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
258 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
271 int connman_inet_ifup(int index)
276 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
280 memset(&ifr, 0, sizeof(ifr));
281 ifr.ifr_ifindex = index;
283 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
288 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
293 if (ifr.ifr_flags & IFF_UP) {
298 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
300 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
313 int connman_inet_ifdown(int index)
315 struct ifreq ifr, addr_ifr;
316 struct sockaddr_in *addr;
319 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
323 memset(&ifr, 0, sizeof(ifr));
324 ifr.ifr_ifindex = index;
326 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
331 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
336 memset(&addr_ifr, 0, sizeof(addr_ifr));
337 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name));
338 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
339 addr->sin_family = AF_INET;
340 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
341 connman_warn("Could not clear IPv4 address index %d", index);
343 if (!(ifr.ifr_flags & IFF_UP)) {
348 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
350 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
361 connman_bool_t connman_inet_is_cfg80211(int index)
363 connman_bool_t result = FALSE;
364 char phy80211_path[PATH_MAX];
369 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
373 memset(&ifr, 0, sizeof(ifr));
374 ifr.ifr_ifindex = index;
376 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
379 snprintf(phy80211_path, PATH_MAX,
380 "/sys/class/net/%s/phy80211", ifr.ifr_name);
382 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
392 struct in6_addr ifr6_addr;
393 __u32 ifr6_prefixlen;
394 unsigned int ifr6_ifindex;
397 int connman_inet_set_ipv6_address(int index,
398 struct connman_ipaddress *ipaddress)
401 unsigned char prefix_len;
404 if (ipaddress->local == NULL)
407 prefix_len = ipaddress->prefixlen;
408 address = ipaddress->local;
410 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
412 err = __connman_inet_modify_address(RTM_NEWADDR,
413 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
414 address, NULL, prefix_len, NULL);
416 connman_error("%s: %s", __func__, strerror(-err));
423 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
426 unsigned char prefix_len;
427 const char *address, *broadcast, *peer;
429 if (ipaddress->local == NULL)
432 prefix_len = ipaddress->prefixlen;
433 address = ipaddress->local;
434 broadcast = ipaddress->broadcast;
435 peer = ipaddress->peer;
437 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
439 err = __connman_inet_modify_address(RTM_NEWADDR,
440 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
441 address, peer, prefix_len, broadcast);
443 connman_error("%s: %s", __func__, strerror(-err));
450 int connman_inet_clear_ipv6_address(int index, const char *address,
455 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
457 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
458 address, NULL, prefix_len, NULL);
460 connman_error("%s: %s", __func__, strerror(-err));
467 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
470 unsigned char prefix_len;
471 const char *address, *broadcast, *peer;
473 prefix_len = ipaddress->prefixlen;
474 address = ipaddress->local;
475 broadcast = ipaddress->broadcast;
476 peer = ipaddress->peer;
478 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
480 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
481 address, peer, prefix_len, broadcast);
483 connman_error("%s: %s", __func__, strerror(-err));
490 int connman_inet_add_host_route(int index, const char *host,
493 return connman_inet_add_network_route(index, host, gateway, NULL);
496 int connman_inet_del_host_route(int index, const char *host)
498 return connman_inet_del_network_route(index, host);
501 int connman_inet_add_network_route(int index, const char *host,
507 struct sockaddr_in addr;
510 DBG("index %d host %s gateway %s netmask %s", index,
511 host, gateway, netmask);
513 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
519 memset(&ifr, 0, sizeof(ifr));
520 ifr.ifr_ifindex = index;
522 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
528 DBG("ifname %s", ifr.ifr_name);
530 memset(&rt, 0, sizeof(rt));
531 rt.rt_flags = RTF_UP;
533 rt.rt_flags |= RTF_GATEWAY;
535 rt.rt_flags |= RTF_HOST;
537 memset(&addr, 0, sizeof(addr));
538 addr.sin_family = AF_INET;
539 addr.sin_addr.s_addr = inet_addr(host);
540 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
542 memset(&addr, 0, sizeof(addr));
543 addr.sin_family = AF_INET;
545 addr.sin_addr.s_addr = inet_addr(gateway);
547 addr.sin_addr.s_addr = INADDR_ANY;
548 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
550 memset(&addr, 0, sizeof(addr));
551 addr.sin_family = AF_INET;
552 addr.sin_addr.s_addr = INADDR_ANY;
554 addr.sin_addr.s_addr = inet_addr(netmask);
556 addr.sin_addr.s_addr = INADDR_ANY;
557 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
559 rt.rt_dev = ifr.ifr_name;
561 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
568 connman_error("Adding host route failed (%s)",
574 int connman_inet_del_network_route(int index, const char *host)
578 struct sockaddr_in addr;
581 DBG("index %d host %s", index, host);
583 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
589 memset(&ifr, 0, sizeof(ifr));
590 ifr.ifr_ifindex = index;
592 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
598 DBG("ifname %s", ifr.ifr_name);
600 memset(&rt, 0, sizeof(rt));
601 rt.rt_flags = RTF_UP | RTF_HOST;
603 memset(&addr, 0, sizeof(addr));
604 addr.sin_family = AF_INET;
605 addr.sin_addr.s_addr = inet_addr(host);
606 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
608 rt.rt_dev = ifr.ifr_name;
610 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
617 connman_error("Deleting host route failed (%s)",
623 int connman_inet_del_ipv6_network_route(int index, const char *host,
624 unsigned char prefix_len)
629 DBG("index %d host %s", index, host);
634 memset(&rt, 0, sizeof(rt));
636 rt.rtmsg_dst_len = prefix_len;
638 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
643 rt.rtmsg_flags = RTF_UP | RTF_HOST;
646 rt.rtmsg_ifindex = index;
648 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
654 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
661 connman_error("Del IPv6 host route error (%s)",
667 int connman_inet_del_ipv6_host_route(int index, const char *host)
669 return connman_inet_del_ipv6_network_route(index, host, 128);
672 int connman_inet_add_ipv6_network_route(int index, const char *host,
674 unsigned char prefix_len)
679 DBG("index %d host %s gateway %s", index, host, gateway);
684 memset(&rt, 0, sizeof(rt));
686 rt.rtmsg_dst_len = prefix_len;
688 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
693 rt.rtmsg_flags = RTF_UP | RTF_HOST;
695 if (gateway != NULL) {
696 rt.rtmsg_flags |= RTF_GATEWAY;
697 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
701 rt.rtmsg_ifindex = index;
703 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
709 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
716 connman_error("Set IPv6 host route error (%s)",
722 int connman_inet_add_ipv6_host_route(int index, const char *host,
725 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
728 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
733 DBG("index %d gateway %s", index, gateway);
738 memset(&rt, 0, sizeof(rt));
740 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
745 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
747 rt.rtmsg_dst_len = 0;
748 rt.rtmsg_ifindex = index;
750 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
756 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
763 connman_error("Set default IPv6 gateway error (%s)",
769 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
774 DBG("index %d gateway %s", index, gateway);
779 memset(&rt, 0, sizeof(rt));
781 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
786 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
788 rt.rtmsg_dst_len = 0;
789 rt.rtmsg_ifindex = index;
791 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
797 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
804 connman_error("Clear default IPv6 gateway error (%s)",
810 int connman_inet_set_gateway_address(int index, const char *gateway)
814 struct sockaddr_in addr;
817 DBG("index %d gateway %s", index, gateway);
819 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
825 memset(&ifr, 0, sizeof(ifr));
826 ifr.ifr_ifindex = index;
828 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
834 DBG("ifname %s", ifr.ifr_name);
836 memset(&rt, 0, sizeof(rt));
837 rt.rt_flags = RTF_UP | RTF_GATEWAY;
839 memset(&addr, 0, sizeof(addr));
840 addr.sin_family = AF_INET;
841 addr.sin_addr.s_addr = INADDR_ANY;
842 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
844 memset(&addr, 0, sizeof(addr));
845 addr.sin_family = AF_INET;
846 addr.sin_addr.s_addr = inet_addr(gateway);
847 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
849 memset(&addr, 0, sizeof(addr));
850 addr.sin_family = AF_INET;
851 addr.sin_addr.s_addr = INADDR_ANY;
852 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
854 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
861 connman_error("Setting default gateway route failed (%s)",
867 int connman_inet_set_gateway_interface(int index)
871 struct sockaddr_in addr;
874 DBG("index %d", index);
876 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
882 memset(&ifr, 0, sizeof(ifr));
883 ifr.ifr_ifindex = index;
885 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
891 DBG("ifname %s", ifr.ifr_name);
893 memset(&rt, 0, sizeof(rt));
894 rt.rt_flags = RTF_UP;
896 memset(&addr, 0, sizeof(addr));
897 addr.sin_family = AF_INET;
898 addr.sin_addr.s_addr = INADDR_ANY;
900 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
901 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
902 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
904 rt.rt_dev = ifr.ifr_name;
906 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
913 connman_error("Setting default interface route failed (%s)",
919 int connman_inet_set_ipv6_gateway_interface(int index)
923 struct sockaddr_in6 addr;
924 const struct in6_addr any = IN6ADDR_ANY_INIT;
927 DBG("index %d", index);
929 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
935 memset(&ifr, 0, sizeof(ifr));
936 ifr.ifr_ifindex = index;
938 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;
949 memset(&addr, 0, sizeof(addr));
950 addr.sin6_family = AF_INET6;
951 addr.sin6_addr = any;
953 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
954 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
955 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
957 rt.rt_dev = ifr.ifr_name;
959 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
966 connman_error("Setting default interface route failed (%s)",
972 int connman_inet_clear_gateway_address(int index, const char *gateway)
976 struct sockaddr_in addr;
979 DBG("index %d gateway %s", index, gateway);
981 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) {
996 DBG("ifname %s", ifr.ifr_name);
998 memset(&rt, 0, sizeof(rt));
999 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1001 memset(&addr, 0, sizeof(addr));
1002 addr.sin_family = AF_INET;
1003 addr.sin_addr.s_addr = INADDR_ANY;
1004 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1006 memset(&addr, 0, sizeof(addr));
1007 addr.sin_family = AF_INET;
1008 addr.sin_addr.s_addr = inet_addr(gateway);
1009 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1011 memset(&addr, 0, sizeof(addr));
1012 addr.sin_family = AF_INET;
1013 addr.sin_addr.s_addr = INADDR_ANY;
1014 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1016 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1023 connman_error("Removing default gateway route failed (%s)",
1029 int connman_inet_clear_gateway_interface(int index)
1033 struct sockaddr_in addr;
1036 DBG("index %d", index);
1038 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1044 memset(&ifr, 0, sizeof(ifr));
1045 ifr.ifr_ifindex = index;
1047 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1053 DBG("ifname %s", ifr.ifr_name);
1055 memset(&rt, 0, sizeof(rt));
1056 rt.rt_flags = RTF_UP;
1058 memset(&addr, 0, sizeof(addr));
1059 addr.sin_family = AF_INET;
1060 addr.sin_addr.s_addr = INADDR_ANY;
1062 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1063 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1064 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1066 rt.rt_dev = ifr.ifr_name;
1068 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1075 connman_error("Removing default interface route failed (%s)",
1081 int connman_inet_clear_ipv6_gateway_interface(int index)
1085 struct sockaddr_in6 addr;
1086 const struct in6_addr any = IN6ADDR_ANY_INIT;
1089 DBG("index %d", index);
1091 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1097 memset(&ifr, 0, sizeof(ifr));
1098 ifr.ifr_ifindex = index;
1100 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1106 DBG("ifname %s", ifr.ifr_name);
1108 memset(&rt, 0, sizeof(rt));
1109 rt.rt_flags = RTF_UP;
1111 memset(&addr, 0, sizeof(addr));
1112 addr.sin6_family = AF_INET6;
1113 addr.sin6_addr = any;
1115 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1116 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1117 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1119 rt.rt_dev = ifr.ifr_name;
1121 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1128 connman_error("Removing default interface route failed (%s)",
1134 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1137 struct in_addr _host_addr;
1138 in_addr_t host_addr, netmask_addr, if_addr;
1139 struct sockaddr_in *netmask, *addr;
1142 DBG("host %s", host);
1147 if (inet_aton(host, &_host_addr) == 0)
1149 host_addr = _host_addr.s_addr;
1151 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1155 memset(&ifr, 0, sizeof(ifr));
1156 ifr.ifr_ifindex = index;
1158 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1163 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1168 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1169 netmask_addr = netmask->sin_addr.s_addr;
1171 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1178 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1179 if_addr = addr->sin_addr.s_addr;
1181 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1184 int connman_inet_remove_from_bridge(int index, const char *bridge)
1192 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1198 memset(&ifr, 0, sizeof(ifr));
1199 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1200 ifr.ifr_ifindex = index;
1202 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1209 connman_error("Remove interface from bridge error %s",
1215 int connman_inet_add_to_bridge(int index, const char *bridge)
1223 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1229 memset(&ifr, 0, sizeof(ifr));
1230 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1231 ifr.ifr_ifindex = index;
1233 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1240 connman_error("Add interface to bridge error %s",
1246 int connman_inet_set_mtu(int index, int mtu)
1251 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1255 memset(&ifr, 0, sizeof(ifr));
1256 ifr.ifr_ifindex = index;
1258 err = ioctl(sk, SIOCGIFNAME, &ifr);
1261 err = ioctl(sk, SIOCSIFMTU, &ifr);
1268 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1278 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1282 index = if_nametoindex(tunnel);
1284 err = connman_inet_set_mtu(index, mtu);
1288 memset(&ifr, 0, sizeof(ifr));
1289 strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1290 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1297 if ((ifr.ifr_flags ^ flags) & mask) {
1298 ifr.ifr_flags &= ~mask;
1299 ifr.ifr_flags |= mask & flags;
1300 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1302 connman_error("SIOCSIFFLAGS failed: %s",
1311 int connman_inet_create_tunnel(char **iface)
1316 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1319 connman_error("Failed to open /dev/net/tun: %s",
1324 memset(&ifr, 0, sizeof(ifr));
1325 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1327 for (i = 0; i < 256; i++) {
1328 sprintf(ifr.ifr_name, "tun%d", i);
1330 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1335 connman_error("Failed to find available tun device");
1340 *iface = g_strdup(ifr.ifr_name);
1346 GIOChannel *channel;
1347 __connman_inet_rs_cb_t callback;
1348 struct sockaddr_in6 addr;
1354 #define CMSG_BUF_LEN 512
1355 #define IN6ADDR_ALL_NODES_MC_INIT \
1356 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1357 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1358 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1360 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1361 static const struct in6_addr in6addr_all_routers_mc =
1362 IN6ADDR_ALL_ROUTERS_MC_INIT;
1364 static void rs_cleanup(struct rs_cb_data *data)
1366 if (data->channel != NULL) {
1367 g_io_channel_shutdown(data->channel, TRUE, NULL);
1368 g_io_channel_unref(data->channel);
1369 data->channel = NULL;
1372 if (data->rs_timeout > 0)
1373 g_source_remove(data->rs_timeout);
1375 if (data->watch_id > 0)
1376 g_source_remove(data->watch_id);
1381 static gboolean rs_timeout_cb(gpointer user_data)
1383 struct rs_cb_data *data = user_data;
1385 DBG("user data %p", user_data);
1390 if (data->callback != NULL)
1391 data->callback(NULL, 0, data->user_data);
1393 data->rs_timeout = 0;
1398 static int icmpv6_recv(int fd, gpointer user_data)
1402 unsigned char chdr[CMSG_BUF_LEN];
1403 unsigned char buf[1540];
1404 struct rs_cb_data *data = user_data;
1405 struct nd_router_advert *hdr;
1406 struct sockaddr_in6 saddr;
1411 iov.iov_len = sizeof(buf);
1414 mhdr.msg_name = (void *)&saddr;
1415 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1416 mhdr.msg_iov = &iov;
1417 mhdr.msg_iovlen = 1;
1418 mhdr.msg_control = (void *)chdr;
1419 mhdr.msg_controllen = CMSG_BUF_LEN;
1421 len = recvmsg(fd, &mhdr, 0);
1423 data->callback(NULL, 0, data->user_data);
1428 hdr = (struct nd_router_advert *)buf;
1429 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1430 sizeof(struct nd_router_advert));
1431 if (hdr->nd_ra_code != 0)
1434 data->callback(hdr, len, data->user_data);
1440 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1447 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1450 fd = g_io_channel_unix_get_fd(chan);
1451 ret = icmpv6_recv(fd, data);
1458 /* Adapted from RFC 1071 "C" Implementation Example */
1459 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1461 register unsigned long sum = 0;
1466 /* caller must make sure datalen is even */
1468 addr = (uint16_t *)phdr;
1469 for (i = 0; i < 20; i++)
1473 addr = (uint16_t *)data;
1481 sum = (sum & 0xffff) + (sum >> 16);
1483 return (uint16_t)~sum;
1486 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1489 struct in6_addr src;
1490 struct in6_addr dst;
1492 uint8_t reserved[3];
1499 struct icmp6_hdr icmp;
1500 struct nd_neighbor_solicit ns;
1501 struct nd_router_solicit rs;
1506 struct cmsghdr *cmsg;
1507 struct in6_pktinfo *pinfo;
1508 struct sockaddr_in6 dst;
1509 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1511 int fd, datalen, ret;
1515 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1519 memset(&frame, 0, sizeof(frame));
1520 memset(&dst, 0, sizeof(dst));
1522 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1523 dst.sin6_addr = *dest;
1525 /* Fill in the IPv6 header */
1526 frame.ip.ip6_vfc = 0x60;
1527 frame.ip.ip6_plen = htons(datalen);
1528 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1529 frame.ip.ip6_hlim = 255;
1530 frame.ip.ip6_dst = dst.sin6_addr;
1531 /* all other fields are already set to zero */
1533 /* Prepare pseudo header for csum */
1534 memset(&phdr, 0, sizeof(phdr));
1535 phdr.dst = dst.sin6_addr;
1536 phdr.plen = htonl(datalen);
1537 phdr.nxt = IPPROTO_ICMPV6;
1539 /* Fill in remaining ICMP header fields */
1540 frame.i.icmp.icmp6_type = type;
1541 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1543 iov.iov_base = &frame;
1544 iov.iov_len = sizeof(frame.ip) + datalen;
1546 dst.sin6_family = AF_INET6;
1547 msgh.msg_name = &dst;
1548 msgh.msg_namelen = sizeof(dst);
1549 msgh.msg_iov = &iov;
1550 msgh.msg_iovlen = 1;
1553 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1554 cmsg = (struct cmsghdr *)cbuf;
1555 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1556 pinfo->ipi6_ifindex = oif;
1558 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1559 cmsg->cmsg_level = IPPROTO_IPV6;
1560 cmsg->cmsg_type = IPV6_PKTINFO;
1561 msgh.msg_control = cmsg;
1562 msgh.msg_controllen = cmsg->cmsg_len;
1564 ret = sendmsg(fd, &msgh, 0);
1570 static inline void ipv6_addr_set(struct in6_addr *addr,
1571 uint32_t w1, uint32_t w2,
1572 uint32_t w3, uint32_t w4)
1574 addr->s6_addr32[0] = w1;
1575 addr->s6_addr32[1] = w2;
1576 addr->s6_addr32[2] = w3;
1577 addr->s6_addr32[3] = w4;
1580 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1581 struct in6_addr *solicited)
1583 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1584 htonl(0xFF000000) | addr->s6_addr32[3]);
1587 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1590 unsigned int val = 0;
1591 struct ipv6_mreq mreq;
1594 memset(&mreq, 0, sizeof(mreq));
1595 mreq.ipv6mr_interface = ifindex;
1596 mreq.ipv6mr_multiaddr = *mc_addr;
1598 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1604 return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1607 int __connman_inet_ipv6_send_rs(int index, int timeout,
1608 __connman_inet_rs_cb_t callback, void *user_data)
1610 struct rs_cb_data *data;
1611 struct icmp6_filter filter;
1612 struct in6_addr solicit;
1613 struct in6_addr dst = in6addr_all_routers_mc;
1621 data = g_try_malloc0(sizeof(struct rs_cb_data));
1625 data->callback = callback;
1626 data->user_data = user_data;
1627 data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1629 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1633 ICMP6_FILTER_SETBLOCKALL(&filter);
1634 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1636 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1637 sizeof(struct icmp6_filter));
1639 ipv6_addr_solict_mult(&dst, &solicit);
1640 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1641 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1643 data->channel = g_io_channel_unix_new(sk);
1644 g_io_channel_set_close_on_unref(data->channel, TRUE);
1646 g_io_channel_set_encoding(data->channel, NULL, NULL);
1647 g_io_channel_set_buffered(data->channel, FALSE);
1649 data->watch_id = g_io_add_watch(data->channel,
1650 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1651 icmpv6_event, data);
1653 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
1658 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
1659 unsigned int length)
1661 GSList *prefixes = NULL;
1665 if (length <= sizeof(struct nd_router_advert))
1668 len = length - sizeof(struct nd_router_advert);
1669 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
1672 struct nd_opt_prefix_info *pinfo;
1673 char prefix_str[INET6_ADDRSTRLEN+1], *str;
1680 optlen = pos[1] << 3;
1681 if (optlen == 0 || optlen > len)
1685 case ND_OPT_PREFIX_INFORMATION:
1686 pinfo = (struct nd_opt_prefix_info *)pos;
1687 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
1688 prefix_str, INET6_ADDRSTRLEN);
1692 str = g_strdup_printf("%s/%d", prefix,
1693 pinfo->nd_opt_pi_prefix_len);
1694 prefixes = g_slist_prepend(prefixes, str);
1696 DBG("prefix %s", str);
1708 static int get_dest_addr(int family, int index, char *buf, int len)
1714 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1718 memset(&ifr, 0, sizeof(ifr));
1719 ifr.ifr_ifindex = index;
1721 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1722 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
1727 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
1728 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
1733 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
1739 DBG("index %d %s", index, ifr.ifr_name);
1741 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
1742 connman_error("Get destination address failed (%s)",
1752 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
1755 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
1762 if (inet_ntop(family, addr, buf, len) == NULL) {
1763 DBG("error %d/%s", errno, strerror(errno));
1770 int connman_inet_get_dest_addr(int index, char **dest)
1772 char addr[INET_ADDRSTRLEN];
1775 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
1779 *dest = g_strdup(addr);
1781 DBG("destination %s", *dest);
1786 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
1788 char addr[INET6_ADDRSTRLEN];
1791 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
1795 *dest = g_strdup(addr);
1797 DBG("destination %s", *dest);
1802 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
1805 int rcvbuf = 1024 * 4;
1807 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
1809 connman_error("Can not open netlink socket: %s",
1814 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
1815 sizeof(sndbuf)) < 0) {
1816 connman_error("SO_SNDBUF: %s", strerror(errno));
1820 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
1821 sizeof(rcvbuf)) < 0) {
1822 connman_error("SO_RCVBUF: %s", strerror(errno));
1826 memset(&rth->local, 0, sizeof(rth->local));
1827 rth->local.nl_family = AF_NETLINK;
1828 rth->local.nl_groups = 0;
1830 if (bind(rth->fd, (struct sockaddr *)&rth->local,
1831 sizeof(rth->local)) < 0) {
1832 connman_error("Can not bind netlink socket: %s",
1837 rth->seq = time(NULL);
1839 DBG("fd %d", rth->fd);
1844 struct inet_rtnl_cb_data {
1845 GIOChannel *channel;
1846 __connman_inet_rtnl_cb_t callback;
1849 struct __connman_inet_rtnl_handle *rtnl;
1853 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
1855 struct __connman_inet_rtnl_handle *rth = data->rtnl;
1857 if (data->channel != NULL) {
1858 g_io_channel_shutdown(data->channel, TRUE, NULL);
1859 g_io_channel_unref(data->channel);
1860 data->channel = NULL;
1863 DBG("data %p", data);
1865 if (data->rtnl_timeout > 0)
1866 g_source_remove(data->rtnl_timeout);
1868 if (data->watch_id > 0)
1869 g_source_remove(data->watch_id);
1872 __connman_inet_rtnl_close(rth);
1879 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
1881 struct inet_rtnl_cb_data *data = user_data;
1883 DBG("user data %p", user_data);
1888 if (data->callback != NULL)
1889 data->callback(NULL, data->user_data);
1891 data->rtnl_timeout = 0;
1892 inet_rtnl_cleanup(data);
1896 static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
1898 struct inet_rtnl_cb_data *rtnl_data = user_data;
1899 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
1900 struct nlmsghdr *h = NULL;
1901 struct sockaddr_nl nladdr;
1902 socklen_t addr_len = sizeof(nladdr);
1903 unsigned char buf[4096];
1908 memset(buf, 0, sizeof(buf));
1909 memset(&nladdr, 0, sizeof(nladdr));
1911 fd = g_io_channel_unix_get_fd(chan);
1913 status = recvfrom(fd, buf, sizeof(buf), 0,
1914 (struct sockaddr *) &nladdr, &addr_len);
1916 if (errno == EINTR || errno == EAGAIN)
1925 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1926 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1933 struct nlmsgerr *err;
1937 if (!NLMSG_OK(h, len)) {
1942 if (h->nlmsg_seq != rth->seq) {
1944 DBG("skip %d/%d len %d", rth->seq,
1945 h->nlmsg_seq, h->nlmsg_len);
1947 len -= h->nlmsg_len;
1948 ptr += h->nlmsg_len;
1952 switch (h->nlmsg_type) {
1958 err = (struct nlmsgerr *)NLMSG_DATA(h);
1959 connman_error("RTNETLINK answers %s (%d)",
1960 strerror(-err->error), -err->error);
1967 if (h->nlmsg_seq == rth->seq) {
1968 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
1970 rtnl_data->callback(h, rtnl_data->user_data);
1972 inet_rtnl_cleanup(rtnl_data);
1978 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
1985 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1988 ret = inet_rtnl_recv(chan, user_data);
1995 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
1996 struct nlmsghdr *n, int timeout,
1997 __connman_inet_rtnl_cb_t callback, void *user_data)
1999 struct sockaddr_nl nladdr;
2000 struct inet_rtnl_cb_data *data;
2004 memset(&nladdr, 0, sizeof(nladdr));
2005 nladdr.nl_family = AF_NETLINK;
2007 n->nlmsg_seq = seq = ++rtnl->seq;
2009 if (callback != NULL) {
2010 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2014 data->callback = callback;
2015 data->user_data = user_data;
2017 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2018 inet_rtnl_timeout_cb, data);
2020 data->channel = g_io_channel_unix_new(rtnl->fd);
2021 g_io_channel_set_close_on_unref(data->channel, TRUE);
2023 g_io_channel_set_encoding(data->channel, NULL, NULL);
2024 g_io_channel_set_buffered(data->channel, FALSE);
2026 data->watch_id = g_io_add_watch(data->channel,
2027 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2028 inet_rtnl_event, data);
2030 n->nlmsg_flags |= NLM_F_ACK;
2032 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2033 (struct sockaddr *) &nladdr, sizeof(nladdr));
2034 DBG("handle %p len %d err %d", rtnl, rtnl->req.n.nlmsg_len, err);
2036 connman_error("Can not talk to rtnetlink");
2040 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2041 connman_error("Sent %d bytes, msg truncated", err);
2048 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2050 DBG("handle %p", rth);
2058 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2061 int len = RTA_LENGTH(4);
2064 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2065 DBG("Error! max allowed bound %zd exceeded", maxlen);
2068 rta = NLMSG_TAIL(n);
2069 rta->rta_type = type;
2071 memcpy(RTA_DATA(rta), &data, 4);
2072 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2077 static int parse_rtattr(struct rtattr *tb[], int max,
2078 struct rtattr *rta, int len)
2080 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2081 while (RTA_OK(rta, len)) {
2082 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2083 tb[rta->rta_type] = rta;
2084 rta = RTA_NEXT(rta, len);
2087 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2092 struct get_route_cb_data {
2093 connman_inet_addr_cb_t callback;
2097 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2099 struct get_route_cb_data *data = user_data;
2100 struct rtattr *tb[RTA_MAX+1];
2101 struct rtmsg *r = NLMSG_DATA(answer);
2102 int len, index = -1;
2104 const char *addr = NULL;
2106 DBG("answer %p data %p", answer, user_data);
2111 len = answer->nlmsg_len;
2113 if (answer->nlmsg_type != RTM_NEWROUTE &&
2114 answer->nlmsg_type != RTM_DELROUTE) {
2115 connman_error("Not a route: %08x %08x %08x",
2116 answer->nlmsg_len, answer->nlmsg_type,
2117 answer->nlmsg_flags);
2121 len -= NLMSG_LENGTH(sizeof(*r));
2123 connman_error("BUG: wrong nlmsg len %d", len);
2127 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2129 if (tb[RTA_OIF] != NULL)
2130 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2132 if (tb[RTA_GATEWAY] != NULL)
2133 addr = inet_ntop(r->rtm_family,
2134 RTA_DATA(tb[RTA_GATEWAY]),
2135 abuf, sizeof(abuf));
2137 DBG("addr %s index %d user %p", addr, index, data->user_data);
2140 if (data != NULL && data->callback != NULL)
2141 data->callback(addr, index, data->user_data);
2149 * Return the interface index that contains route to host.
2151 int __connman_inet_get_route(const char *dest_address,
2152 connman_inet_addr_cb_t callback, void *user_data)
2154 struct get_route_cb_data *data;
2155 struct addrinfo hints, *rp;
2156 struct __connman_inet_rtnl_handle *rth;
2159 DBG("dest %s", dest_address);
2161 if (dest_address == NULL)
2164 memset(&hints, 0, sizeof(hints));
2165 hints.ai_family = AF_UNSPEC;
2166 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2168 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2172 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2178 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2179 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2180 rth->req.n.nlmsg_type = RTM_GETROUTE;
2181 rth->req.u.r.rt.rtm_family = rp->ai_family;
2182 rth->req.u.r.rt.rtm_table = 0;
2183 rth->req.u.r.rt.rtm_protocol = 0;
2184 rth->req.u.r.rt.rtm_scope = 0;
2185 rth->req.u.r.rt.rtm_type = 0;
2186 rth->req.u.r.rt.rtm_src_len = 0;
2187 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2188 rth->req.u.r.rt.rtm_tos = 0;
2190 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2191 &rp->ai_addr, rp->ai_addrlen);
2195 err = __connman_inet_rtnl_open(rth);
2199 data = g_try_malloc(sizeof(struct get_route_cb_data));
2205 data->callback = callback;
2206 data->user_data = user_data;
2208 #define GET_ROUTE_TIMEOUT 2
2209 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2210 get_route_cb, data);
2219 __connman_inet_rtnl_close(rth);
2226 int connman_inet_check_ipaddress(const char *host)
2228 struct addrinfo hints;
2229 struct addrinfo *addr;
2232 memset(&hints, 0, sizeof(struct addrinfo));
2233 hints.ai_flags = AI_NUMERICHOST;
2236 result = getaddrinfo(host, NULL, &hints, &addr);
2238 result = addr->ai_family;
2244 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2245 connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
2250 * Not empty or complete length not over 255 characters.
2252 if ((len == 0) || (len > 256))
2256 * Consists of [[:alnum:]-]+ labels separated by [.]
2257 * a [_] is against RFC but seems to be "widely used"
2259 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2261 if ((*p == '-') || (*p == '_')) {
2263 * Not allowed at begin or end of a label.
2265 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2268 } else if (*p == '.') {
2270 * Each label has to be 1-63 characters;
2271 * we allow [.] at the end ('foo.bar.')
2275 if ((d <= 0) || (d >= 64))
2278 ptr = p + 1; /* Jump to the next label */
2280 } else if (isalnum((unsigned char)*p) == 0) {
2282 * Also numbers at the begin are fine
2291 char **__connman_inet_get_running_interfaces(void)
2295 struct ifreq *ifr = NULL;
2296 int sk, i, numif, count = 0;
2298 memset(&ifc, 0, sizeof(ifc));
2300 sk = socket(AF_INET, SOCK_DGRAM, 0);
2304 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2308 * Allocate some extra bytes just in case there will
2309 * be new interfaces added between two SIOCGIFCONF
2312 ifr = g_try_malloc0(ifc.ifc_len * 2);
2318 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2321 numif = ifc.ifc_len / sizeof(struct ifreq);
2323 result = g_try_malloc0((numif + 1) * sizeof(char *));
2329 for (i = 0; i < numif; i++) {
2330 struct ifreq *r = &ifr[i];
2331 struct in6_addr *addr6;
2335 * Note that we do not return loopback interfaces here as they
2336 * are not needed for our purposes.
2338 switch (r->ifr_addr.sa_family) {
2340 addr4 = ntohl(((struct sockaddr_in *)
2341 &r->ifr_addr)->sin_addr.s_addr);
2342 if (((addr4 & 0xff000000) >> 24) == 127)
2346 addr6 = &((struct sockaddr_in6 *)
2347 &r->ifr_addr)->sin6_addr;
2348 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2353 result[count++] = g_strdup(r->ifr_name);
2359 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2369 connman_bool_t connman_inet_is_ipv6_supported()
2373 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2381 int __connman_inet_get_interface_address(int index, int family, void *address)
2383 struct ifaddrs *ifaddr, *ifa;
2385 char name[IF_NAMESIZE];
2387 if (if_indextoname(index, name) == NULL)
2390 DBG("index %d interface %s", index, name);
2392 if (getifaddrs(&ifaddr) < 0) {
2394 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2398 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
2399 if (ifa->ifa_addr == NULL)
2402 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2403 ifa->ifa_addr->sa_family == family) {
2404 if (family == AF_INET) {
2405 struct sockaddr_in *in4 = (struct sockaddr_in *)
2407 if (in4->sin_addr.s_addr == INADDR_ANY)
2409 memcpy(address, &in4->sin_addr,
2410 sizeof(struct in_addr));
2411 } else if (family == AF_INET6) {
2412 struct sockaddr_in6 *in6 =
2413 (struct sockaddr_in6 *)ifa->ifa_addr;
2414 if (memcmp(&in6->sin6_addr, &in6addr_any,
2415 sizeof(struct in6_addr)) == 0)
2417 memcpy(address, &in6->sin6_addr,
2418 sizeof(struct in6_addr));
2431 freeifaddrs(ifaddr);