5 * Copyright (C) 2007-2010 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>
38 #include <arpa/inet.h>
39 #include <net/route.h>
40 #include <net/ethernet.h>
42 #include <net/if_arp.h>
43 #include <netinet/icmp6.h>
45 #include <linux/if_tun.h>
49 #define NLMSG_TAIL(nmsg) \
50 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
51 NLMSG_ALIGN((nmsg)->nlmsg_len)))
53 static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
54 const void *data, size_t data_length)
59 length = RTA_LENGTH(data_length);
61 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
66 rta->rta_len = length;
67 memcpy(RTA_DATA(rta), data, data_length);
68 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
73 int __connman_inet_modify_address(int cmd, int flags,
74 int index, int family,
77 unsigned char prefixlen,
78 const char *broadcast)
80 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
81 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
82 RTA_LENGTH(sizeof(struct in6_addr)) +
83 RTA_LENGTH(sizeof(struct in6_addr))];
85 struct nlmsghdr *header;
86 struct sockaddr_nl nl_addr;
87 struct ifaddrmsg *ifaddrmsg;
88 struct in6_addr ipv6_addr;
89 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
92 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
93 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
94 address, peer, prefixlen, broadcast);
99 if (family != AF_INET && family != AF_INET6)
102 memset(&request, 0, sizeof(request));
104 header = (struct nlmsghdr *)request;
105 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
106 header->nlmsg_type = cmd;
107 header->nlmsg_flags = NLM_F_REQUEST | flags;
108 header->nlmsg_seq = 1;
110 ifaddrmsg = NLMSG_DATA(header);
111 ifaddrmsg->ifa_family = family;
112 ifaddrmsg->ifa_prefixlen = prefixlen;
113 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
114 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
115 ifaddrmsg->ifa_index = index;
117 if (family == AF_INET) {
118 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
121 if (broadcast != NULL)
122 inet_pton(AF_INET, broadcast, &ipv4_bcast);
124 ipv4_bcast.s_addr = ipv4_addr.s_addr |
125 htonl(0xfffffffflu >> prefixlen);
128 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
131 if ((err = add_rtattr(header, sizeof(request),
133 &ipv4_dest, sizeof(ipv4_dest))) < 0)
137 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
138 &ipv4_addr, sizeof(ipv4_addr))) < 0)
141 if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
142 &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
145 } else if (family == AF_INET6) {
146 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
149 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
150 &ipv6_addr, sizeof(ipv6_addr))) < 0)
154 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
158 memset(&nl_addr, 0, sizeof(nl_addr));
159 nl_addr.nl_family = AF_NETLINK;
161 if ((err = sendto(sk, request, header->nlmsg_len, 0,
162 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
173 int connman_inet_ifindex(const char *name)
181 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
185 memset(&ifr, 0, sizeof(ifr));
186 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
188 err = ioctl(sk, SIOCGIFINDEX, &ifr);
195 return ifr.ifr_ifindex;
198 char *connman_inet_ifname(int index)
206 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
210 memset(&ifr, 0, sizeof(ifr));
211 ifr.ifr_ifindex = index;
213 err = ioctl(sk, SIOCGIFNAME, &ifr);
220 return strdup(ifr.ifr_name);
223 short int connman_inet_ifflags(int index)
228 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
232 memset(&ifr, 0, sizeof(ifr));
233 ifr.ifr_ifindex = index;
235 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
240 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
253 int connman_inet_ifup(int index)
258 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
262 memset(&ifr, 0, sizeof(ifr));
263 ifr.ifr_ifindex = index;
265 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
270 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
275 if (ifr.ifr_flags & IFF_UP) {
280 ifr.ifr_flags |= IFF_UP;
282 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
295 int connman_inet_ifdown(int index)
300 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
304 memset(&ifr, 0, sizeof(ifr));
305 ifr.ifr_ifindex = index;
307 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
312 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
317 if (!(ifr.ifr_flags & IFF_UP)) {
322 ifr.ifr_flags &= ~IFF_UP;
324 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
335 static char *index2addr(int index)
338 struct ether_addr eth;
345 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
349 memset(&ifr, 0, sizeof(ifr));
350 ifr.ifr_ifindex = index;
352 err = ioctl(sk, SIOCGIFNAME, &ifr);
355 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
366 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
367 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
368 eth.ether_addr_octet[0],
369 eth.ether_addr_octet[1],
370 eth.ether_addr_octet[2],
371 eth.ether_addr_octet[3],
372 eth.ether_addr_octet[4],
373 eth.ether_addr_octet[5]);
378 static char *index2ident(int index, const char *prefix)
381 struct ether_addr eth;
388 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
392 memset(&ifr, 0, sizeof(ifr));
393 ifr.ifr_ifindex = index;
395 err = ioctl(sk, SIOCGIFNAME, &ifr);
398 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
405 len = prefix ? strlen(prefix) + 18 : 18;
411 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
412 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
413 prefix ? prefix : "",
414 eth.ether_addr_octet[0],
415 eth.ether_addr_octet[1],
416 eth.ether_addr_octet[2],
417 eth.ether_addr_octet[3],
418 eth.ether_addr_octet[4],
419 eth.ether_addr_octet[5]);
424 connman_bool_t connman_inet_is_cfg80211(int index)
426 connman_bool_t result = FALSE;
427 char phy80211_path[PATH_MAX];
432 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
436 memset(&ifr, 0, sizeof(ifr));
437 ifr.ifr_ifindex = index;
439 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
442 snprintf(phy80211_path, PATH_MAX,
443 "/sys/class/net/%s/phy80211", ifr.ifr_name);
445 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
454 struct connman_device *connman_inet_create_device(int index)
456 enum connman_device_type type;
457 struct connman_device *device;
458 char *devname, *ident = NULL;
459 char *addr = NULL, *name = NULL;
464 devname = connman_inet_ifname(index);
468 if (__connman_device_isfiltered(devname) == TRUE) {
469 connman_info("Ignoring interface %s (filtered)", devname);
474 type = __connman_rtnl_get_device_type(index);
477 case CONNMAN_DEVICE_TYPE_UNKNOWN:
478 connman_info("Ignoring interface %s (type unknown)", devname);
481 case CONNMAN_DEVICE_TYPE_ETHERNET:
482 case CONNMAN_DEVICE_TYPE_GADGET:
483 case CONNMAN_DEVICE_TYPE_WIFI:
484 case CONNMAN_DEVICE_TYPE_WIMAX:
485 name = index2ident(index, "");
486 addr = index2addr(index);
488 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
489 case CONNMAN_DEVICE_TYPE_CELLULAR:
490 case CONNMAN_DEVICE_TYPE_GPS:
491 case CONNMAN_DEVICE_TYPE_VENDOR:
492 name = strdup(devname);
496 device = connman_device_create(name, type);
501 case CONNMAN_DEVICE_TYPE_UNKNOWN:
502 case CONNMAN_DEVICE_TYPE_VENDOR:
503 case CONNMAN_DEVICE_TYPE_GPS:
505 case CONNMAN_DEVICE_TYPE_ETHERNET:
506 case CONNMAN_DEVICE_TYPE_GADGET:
507 ident = index2ident(index, NULL);
509 case CONNMAN_DEVICE_TYPE_WIFI:
510 case CONNMAN_DEVICE_TYPE_WIMAX:
511 ident = index2ident(index, NULL);
513 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
515 case CONNMAN_DEVICE_TYPE_CELLULAR:
516 ident = index2ident(index, NULL);
520 connman_device_set_index(device, index);
521 connman_device_set_interface(device, devname);
524 connman_device_set_ident(device, ident);
528 connman_device_set_string(device, "Address", addr);
539 struct in6_addr ifr6_addr;
540 __u32 ifr6_prefixlen;
541 unsigned int ifr6_ifindex;
544 int connman_inet_set_ipv6_address(int index,
545 struct connman_ipaddress *ipaddress)
548 unsigned char prefix_len;
551 if (ipaddress->local == NULL)
554 prefix_len = ipaddress->prefixlen;
555 address = ipaddress->local;
557 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
559 err = __connman_inet_modify_address(RTM_NEWADDR,
560 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
561 address, NULL, prefix_len, NULL);
563 connman_error("%s: %s", __func__, strerror(-err));
570 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
573 unsigned char prefix_len;
574 const char *address, *broadcast, *peer;
576 if (ipaddress->local == NULL)
579 prefix_len = ipaddress->prefixlen;
580 address = ipaddress->local;
581 broadcast = ipaddress->broadcast;
582 peer = ipaddress->peer;
584 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
586 err = __connman_inet_modify_address(RTM_NEWADDR,
587 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
588 address, peer, prefix_len, broadcast);
590 connman_error("%s: %s", __func__, strerror(-err));
597 int connman_inet_clear_ipv6_address(int index, const char *address,
602 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
604 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
605 address, NULL, prefix_len, NULL);
607 connman_error("%s: %s", __func__, strerror(-err));
614 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
617 unsigned char prefix_len;
618 const char *address, *broadcast, *peer;
620 prefix_len = ipaddress->prefixlen;
621 address = ipaddress->local;
622 broadcast = ipaddress->broadcast;
623 peer = ipaddress->peer;
625 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
627 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
628 address, peer, prefix_len, broadcast);
630 connman_error("%s: %s", __func__, strerror(-err));
637 int connman_inet_add_host_route(int index, const char *host,
640 return connman_inet_add_network_route(index, host, gateway, NULL);
643 int connman_inet_del_host_route(int index, const char *host)
645 return connman_inet_del_network_route(index, host);
648 int connman_inet_add_network_route(int index, const char *host,
654 struct sockaddr_in addr;
657 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
661 memset(&ifr, 0, sizeof(ifr));
662 ifr.ifr_ifindex = index;
664 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
669 DBG("ifname %s", ifr.ifr_name);
671 memset(&rt, 0, sizeof(rt));
672 rt.rt_flags = RTF_UP;
674 rt.rt_flags |= RTF_GATEWAY;
676 rt.rt_flags |= RTF_HOST;
678 memset(&addr, 0, sizeof(addr));
679 addr.sin_family = AF_INET;
680 addr.sin_addr.s_addr = inet_addr(host);
681 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
683 memset(&addr, 0, sizeof(addr));
684 addr.sin_family = AF_INET;
686 addr.sin_addr.s_addr = inet_addr(gateway);
688 addr.sin_addr.s_addr = INADDR_ANY;
689 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
691 memset(&addr, 0, sizeof(addr));
692 addr.sin_family = AF_INET;
693 addr.sin_addr.s_addr = INADDR_ANY;
695 addr.sin_addr.s_addr = inet_addr(netmask);
697 addr.sin_addr.s_addr = INADDR_ANY;
698 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
700 rt.rt_dev = ifr.ifr_name;
702 err = ioctl(sk, SIOCADDRT, &rt);
704 connman_error("Adding host route failed (%s)",
712 int connman_inet_del_network_route(int index, const char *host)
716 struct sockaddr_in addr;
719 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
723 memset(&ifr, 0, sizeof(ifr));
724 ifr.ifr_ifindex = index;
726 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
731 DBG("ifname %s", ifr.ifr_name);
733 memset(&rt, 0, sizeof(rt));
734 rt.rt_flags = RTF_UP | RTF_HOST;
736 memset(&addr, 0, sizeof(addr));
737 addr.sin_family = AF_INET;
738 addr.sin_addr.s_addr = inet_addr(host);
739 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
741 rt.rt_dev = ifr.ifr_name;
743 err = ioctl(sk, SIOCDELRT, &rt);
745 connman_error("Deleting host route failed (%s)",
753 int connman_inet_del_ipv6_network_route(int index, const char *host,
754 unsigned char prefix_len)
759 DBG("index %d host %s", index, host);
764 memset(&rt, 0, sizeof(rt));
766 rt.rtmsg_dst_len = prefix_len;
768 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
772 rt.rtmsg_flags = RTF_UP | RTF_HOST;
775 rt.rtmsg_ifindex = index;
777 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
783 err = ioctl(sk, SIOCDELRT, &rt);
787 connman_error("Del IPv6 host route error (%s)",
793 int connman_inet_del_ipv6_host_route(int index, const char *host)
795 return connman_inet_del_ipv6_network_route(index, host, 128);
798 int connman_inet_add_ipv6_network_route(int index, const char *host,
800 unsigned char prefix_len)
805 DBG("index %d host %s gateway %s", index, host, gateway);
810 memset(&rt, 0, sizeof(rt));
812 rt.rtmsg_dst_len = prefix_len;
814 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
818 rt.rtmsg_flags = RTF_UP | RTF_HOST;
820 if (gateway != NULL) {
821 rt.rtmsg_flags |= RTF_GATEWAY;
822 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
826 rt.rtmsg_ifindex = index;
828 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
834 err = ioctl(sk, SIOCADDRT, &rt);
838 connman_error("Set IPv6 host route error (%s)",
844 int connman_inet_add_ipv6_host_route(int index, const char *host,
847 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
850 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
855 DBG("index %d, gateway %s", index, gateway);
860 memset(&rt, 0, sizeof(rt));
862 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
866 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
868 rt.rtmsg_dst_len = 0;
869 rt.rtmsg_ifindex = index;
871 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
877 err = ioctl(sk, SIOCADDRT, &rt);
881 connman_error("Set default IPv6 gateway error (%s)",
887 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
892 DBG("index %d, gateway %s", index, gateway);
897 memset(&rt, 0, sizeof(rt));
899 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
903 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
905 rt.rtmsg_dst_len = 0;
906 rt.rtmsg_ifindex = index;
908 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
914 err = ioctl(sk, SIOCDELRT, &rt);
918 connman_error("Clear default IPv6 gateway error (%s)",
924 int connman_inet_set_gateway_address(int index, const char *gateway)
928 struct sockaddr_in addr;
931 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
935 memset(&ifr, 0, sizeof(ifr));
936 ifr.ifr_ifindex = index;
938 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
943 DBG("ifname %s", ifr.ifr_name);
945 memset(&rt, 0, sizeof(rt));
946 rt.rt_flags = RTF_UP | RTF_GATEWAY;
948 memset(&addr, 0, sizeof(addr));
949 addr.sin_family = AF_INET;
950 addr.sin_addr.s_addr = INADDR_ANY;
951 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
953 memset(&addr, 0, sizeof(addr));
954 addr.sin_family = AF_INET;
955 addr.sin_addr.s_addr = inet_addr(gateway);
956 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
958 memset(&addr, 0, sizeof(addr));
959 addr.sin_family = AF_INET;
960 addr.sin_addr.s_addr = INADDR_ANY;
961 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
963 err = ioctl(sk, SIOCADDRT, &rt);
965 connman_error("Setting default gateway route failed (%s)",
973 int connman_inet_set_gateway_interface(int index)
977 struct sockaddr_in addr;
982 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
986 memset(&ifr, 0, sizeof(ifr));
987 ifr.ifr_ifindex = index;
989 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
994 DBG("ifname %s", ifr.ifr_name);
996 memset(&rt, 0, sizeof(rt));
997 rt.rt_flags = RTF_UP;
999 memset(&addr, 0, sizeof(addr));
1000 addr.sin_family = AF_INET;
1001 addr.sin_addr.s_addr = INADDR_ANY;
1003 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1004 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1005 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1007 rt.rt_dev = ifr.ifr_name;
1009 err = ioctl(sk, SIOCADDRT, &rt);
1011 connman_error("Setting default interface route failed (%s)",
1018 int connman_inet_set_ipv6_gateway_interface(int index)
1022 struct sockaddr_in6 addr;
1023 const struct in6_addr any = IN6ADDR_ANY_INIT;
1028 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1032 memset(&ifr, 0, sizeof(ifr));
1033 ifr.ifr_ifindex = index;
1035 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1040 DBG("ifname %s", ifr.ifr_name);
1042 memset(&rt, 0, sizeof(rt));
1043 rt.rt_flags = RTF_UP;
1045 memset(&addr, 0, sizeof(addr));
1046 addr.sin6_family = AF_INET6;
1047 addr.sin6_addr = any;
1049 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1050 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1051 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1053 rt.rt_dev = ifr.ifr_name;
1055 err = ioctl(sk, SIOCADDRT, &rt);
1057 connman_error("Setting default interface route failed (%s)",
1064 int connman_inet_clear_gateway_address(int index, const char *gateway)
1068 struct sockaddr_in addr;
1073 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1077 memset(&ifr, 0, sizeof(ifr));
1078 ifr.ifr_ifindex = index;
1080 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1085 DBG("ifname %s", ifr.ifr_name);
1087 memset(&rt, 0, sizeof(rt));
1088 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1090 memset(&addr, 0, sizeof(addr));
1091 addr.sin_family = AF_INET;
1092 addr.sin_addr.s_addr = INADDR_ANY;
1093 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1095 memset(&addr, 0, sizeof(addr));
1096 addr.sin_family = AF_INET;
1097 addr.sin_addr.s_addr = inet_addr(gateway);
1098 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1100 memset(&addr, 0, sizeof(addr));
1101 addr.sin_family = AF_INET;
1102 addr.sin_addr.s_addr = INADDR_ANY;
1103 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1105 err = ioctl(sk, SIOCDELRT, &rt);
1107 connman_error("Removing default gateway route failed (%s)",
1115 int connman_inet_clear_gateway_interface(int index)
1119 struct sockaddr_in addr;
1124 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1128 memset(&ifr, 0, sizeof(ifr));
1129 ifr.ifr_ifindex = index;
1131 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1136 DBG("ifname %s", ifr.ifr_name);
1138 memset(&rt, 0, sizeof(rt));
1139 rt.rt_flags = RTF_UP;
1141 memset(&addr, 0, sizeof(addr));
1142 addr.sin_family = AF_INET;
1143 addr.sin_addr.s_addr = INADDR_ANY;
1145 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1146 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1147 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1149 rt.rt_dev = ifr.ifr_name;
1151 err = ioctl(sk, SIOCDELRT, &rt);
1153 connman_error("Removing default interface route failed (%s)",
1160 int connman_inet_clear_ipv6_gateway_interface(int index)
1164 struct sockaddr_in6 addr;
1165 const struct in6_addr any = IN6ADDR_ANY_INIT;
1170 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1174 memset(&ifr, 0, sizeof(ifr));
1175 ifr.ifr_ifindex = index;
1177 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1182 DBG("ifname %s", ifr.ifr_name);
1184 memset(&rt, 0, sizeof(rt));
1185 rt.rt_flags = RTF_UP;
1187 memset(&addr, 0, sizeof(addr));
1188 addr.sin6_family = AF_INET6;
1189 addr.sin6_addr = any;
1191 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1192 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1193 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1195 rt.rt_dev = ifr.ifr_name;
1197 err = ioctl(sk, SIOCDELRT, &rt);
1199 connman_error("Removing default interface route failed (%s)",
1206 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1209 struct in_addr _host_addr;
1210 in_addr_t host_addr, netmask_addr, if_addr;
1211 struct sockaddr_in *netmask, *addr;
1214 DBG("host %s", host);
1219 if (inet_aton(host, &_host_addr) == 0)
1221 host_addr = _host_addr.s_addr;
1223 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1227 memset(&ifr, 0, sizeof(ifr));
1228 ifr.ifr_ifindex = index;
1230 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1235 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1240 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1241 netmask_addr = netmask->sin_addr.s_addr;
1243 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1247 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1248 if_addr = addr->sin_addr.s_addr;
1250 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1253 int connman_inet_remove_from_bridge(int index, const char *bridge)
1261 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1265 memset(&ifr, 0, sizeof(ifr));
1266 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1267 ifr.ifr_ifindex = index;
1269 err = ioctl(sk, SIOCBRDELIF, &ifr);
1274 connman_error("Remove interface from bridge error %s",
1282 int connman_inet_add_to_bridge(int index, const char *bridge)
1290 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1294 memset(&ifr, 0, sizeof(ifr));
1295 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1296 ifr.ifr_ifindex = index;
1298 err = ioctl(sk, SIOCBRADDIF, &ifr);
1303 connman_error("Add interface to bridge error %s",
1311 int connman_inet_set_mtu(int index, int mtu)
1316 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1320 memset(&ifr, 0, sizeof(ifr));
1321 ifr.ifr_ifindex = index;
1323 err = ioctl(sk, SIOCGIFNAME, &ifr);
1326 err = ioctl(sk, SIOCSIFMTU, &ifr);
1333 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1343 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1347 index = if_nametoindex(tunnel);
1349 err = connman_inet_set_mtu(index, mtu);
1355 memset(&ifr, 0, sizeof(ifr));
1356 strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1357 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1364 if ((ifr.ifr_flags ^ flags) & mask) {
1365 ifr.ifr_flags &= ~mask;
1366 ifr.ifr_flags |= mask & flags;
1367 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1369 connman_error("SIOCSIFFLAGS failed: %s",
1378 int connman_inet_create_tunnel(char **iface)
1383 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1386 connman_error("Failed to open /dev/net/tun: %s",
1391 memset(&ifr, 0, sizeof(ifr));
1392 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1394 for (i = 0; i < 256; i++) {
1395 sprintf(ifr.ifr_name, "tun%d", i);
1397 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1402 connman_error("Failed to find available tun device");
1407 *iface = g_strdup(ifr.ifr_name);
1413 GIOChannel *channel;
1414 __connman_inet_rs_cb_t callback;
1415 struct sockaddr_in6 addr;
1420 #define CMSG_BUF_LEN 512
1421 #define IN6ADDR_ALL_NODES_MC_INIT \
1422 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1423 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1424 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1426 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1427 static const struct in6_addr in6addr_all_routers_mc =
1428 IN6ADDR_ALL_ROUTERS_MC_INIT;
1430 static void rs_cleanup(struct rs_cb_data *data)
1432 g_io_channel_shutdown(data->channel, TRUE, NULL);
1433 g_io_channel_unref(data->channel);
1436 if (data->rs_timeout > 0)
1437 g_source_remove(data->rs_timeout);
1442 static gboolean rs_timeout_cb(gpointer user_data)
1444 struct rs_cb_data *data = user_data;
1446 DBG("user data %p", user_data);
1451 if (data->callback != NULL)
1452 data->callback(NULL, data->user_data);
1454 data->rs_timeout = 0;
1459 static int icmpv6_recv(int fd, gpointer user_data)
1463 unsigned char chdr[CMSG_BUF_LEN];
1464 unsigned char buf[1540];
1465 struct rs_cb_data *data = user_data;
1466 struct nd_router_advert *hdr;
1467 struct sockaddr_in6 saddr;
1472 iov.iov_len = sizeof(buf);
1475 mhdr.msg_name = (void *)&saddr;
1476 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1477 mhdr.msg_iov = &iov;
1478 mhdr.msg_iovlen = 1;
1479 mhdr.msg_control = (void *)chdr;
1480 mhdr.msg_controllen = CMSG_BUF_LEN;
1482 len = recvmsg(fd, &mhdr, 0);
1484 data->callback(NULL, data->user_data);
1489 hdr = (struct nd_router_advert *)buf;
1490 if (hdr->nd_ra_code != 0)
1493 data->callback(hdr, data->user_data);
1499 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1506 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1509 fd = g_io_channel_unix_get_fd(chan);
1510 ret = icmpv6_recv(fd, data);
1517 /* Adapted from RFC 1071 "C" Implementation Example */
1518 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1520 register unsigned long sum = 0;
1525 /* caller must make sure datalen is even */
1527 addr = (uint16_t *)phdr;
1528 for (i = 0; i < 20; i++)
1532 addr = (uint16_t *)data;
1540 sum = (sum & 0xffff) + (sum >> 16);
1542 return (uint16_t)~sum;
1545 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1548 struct in6_addr src;
1549 struct in6_addr dst;
1551 uint8_t reserved[3];
1558 struct icmp6_hdr icmp;
1559 struct nd_neighbor_solicit ns;
1560 struct nd_router_solicit rs;
1565 struct cmsghdr *cmsg;
1566 struct in6_pktinfo *pinfo;
1567 struct sockaddr_in6 dst;
1568 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1570 int fd, datalen, ret;
1574 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1578 memset(&frame, 0, sizeof(frame));
1579 memset(&dst, 0, sizeof(dst));
1581 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1582 dst.sin6_addr = *dest;
1584 /* Fill in the IPv6 header */
1585 frame.ip.ip6_vfc = 0x60;
1586 frame.ip.ip6_plen = htons(datalen);
1587 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1588 frame.ip.ip6_hlim = 255;
1589 frame.ip.ip6_dst = dst.sin6_addr;
1590 /* all other fields are already set to zero */
1592 /* Prepare pseudo header for csum */
1593 memset(&phdr, 0, sizeof(phdr));
1594 phdr.dst = dst.sin6_addr;
1595 phdr.plen = htonl(datalen);
1596 phdr.nxt = IPPROTO_ICMPV6;
1598 /* Fill in remaining ICMP header fields */
1599 frame.i.icmp.icmp6_type = type;
1600 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1602 iov.iov_base = &frame;
1603 iov.iov_len = sizeof(frame.ip) + datalen;
1605 dst.sin6_family = AF_INET6;
1606 msgh.msg_name = &dst;
1607 msgh.msg_namelen = sizeof(dst);
1608 msgh.msg_iov = &iov;
1609 msgh.msg_iovlen = 1;
1612 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1613 cmsg = (struct cmsghdr *)cbuf;
1614 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1615 pinfo->ipi6_ifindex = oif;
1617 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1618 cmsg->cmsg_level = IPPROTO_IPV6;
1619 cmsg->cmsg_type = IPV6_PKTINFO;
1620 msgh.msg_control = cmsg;
1621 msgh.msg_controllen = cmsg->cmsg_len;
1623 ret = sendmsg(fd, &msgh, 0);
1629 static inline void ipv6_addr_set(struct in6_addr *addr,
1630 uint32_t w1, uint32_t w2,
1631 uint32_t w3, uint32_t w4)
1633 addr->s6_addr32[0] = w1;
1634 addr->s6_addr32[1] = w2;
1635 addr->s6_addr32[2] = w3;
1636 addr->s6_addr32[3] = w4;
1639 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1640 struct in6_addr *solicited)
1642 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1643 htonl(0xFF000000) | addr->s6_addr32[3]);
1646 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1649 unsigned int val = 0;
1650 struct ipv6_mreq mreq;
1653 memset(&mreq, 0, sizeof(mreq));
1654 mreq.ipv6mr_interface = ifindex;
1655 mreq.ipv6mr_multiaddr = *mc_addr;
1657 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1663 return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1666 int __connman_inet_ipv6_send_rs(int index, int timeout,
1667 __connman_inet_rs_cb_t callback, void *user_data)
1669 struct rs_cb_data *data;
1670 struct icmp6_filter filter;
1671 struct in6_addr solicit;
1672 struct in6_addr dst = in6addr_all_routers_mc;
1680 data = g_try_malloc0(sizeof(struct rs_cb_data));
1684 data->callback = callback;
1685 data->user_data = user_data;
1686 data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1688 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1692 ICMP6_FILTER_SETBLOCKALL(&filter);
1693 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1695 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1696 sizeof(struct icmp6_filter));
1698 ipv6_addr_solict_mult(&dst, &solicit);
1699 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1700 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1702 data->channel = g_io_channel_unix_new(sk);
1703 g_io_channel_set_close_on_unref(data->channel, TRUE);
1705 g_io_channel_set_encoding(data->channel, NULL, NULL);
1706 g_io_channel_set_buffered(data->channel, FALSE);
1708 g_io_add_watch(data->channel,
1709 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1710 icmpv6_event, data);
1712 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);