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
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <linux/sockios.h>
37 #include <arpa/inet.h>
38 #include <net/route.h>
39 #include <net/ethernet.h>
41 #include <net/if_arp.h>
42 #include <netinet/icmp6.h>
44 #include <linux/if_tun.h>
48 #define NLMSG_TAIL(nmsg) \
49 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
50 NLMSG_ALIGN((nmsg)->nlmsg_len)))
52 static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
53 const void *data, size_t data_length)
58 length = RTA_LENGTH(data_length);
60 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
65 rta->rta_len = length;
66 memcpy(RTA_DATA(rta), data, data_length);
67 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
72 int __connman_inet_modify_address(int cmd, int flags,
73 int index, int family,
76 unsigned char prefixlen,
77 const char *broadcast)
79 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
80 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
81 RTA_LENGTH(sizeof(struct in6_addr)) +
82 RTA_LENGTH(sizeof(struct in6_addr))];
84 struct nlmsghdr *header;
85 struct sockaddr_nl nl_addr;
86 struct ifaddrmsg *ifaddrmsg;
87 struct in6_addr ipv6_addr;
88 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
96 if (family != AF_INET && family != AF_INET6)
99 memset(&request, 0, sizeof(request));
101 header = (struct nlmsghdr *)request;
102 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
103 header->nlmsg_type = cmd;
104 header->nlmsg_flags = NLM_F_REQUEST | flags;
105 header->nlmsg_seq = 1;
107 ifaddrmsg = NLMSG_DATA(header);
108 ifaddrmsg->ifa_family = family;
109 ifaddrmsg->ifa_prefixlen = prefixlen;
110 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
111 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
112 ifaddrmsg->ifa_index = index;
114 if (family == AF_INET) {
115 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
118 if (broadcast != NULL)
119 inet_pton(AF_INET, broadcast, &ipv4_bcast);
121 ipv4_bcast.s_addr = ipv4_addr.s_addr |
122 htonl(0xfffffffflu >> prefixlen);
125 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
128 if ((err = add_rtattr(header, sizeof(request),
130 &ipv4_dest, sizeof(ipv4_dest))) < 0)
134 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
135 &ipv4_addr, sizeof(ipv4_addr))) < 0)
138 if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
139 &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
142 } else if (family == AF_INET6) {
143 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
146 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
147 &ipv6_addr, sizeof(ipv6_addr))) < 0)
151 sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
155 memset(&nl_addr, 0, sizeof(nl_addr));
156 nl_addr.nl_family = AF_NETLINK;
158 if ((err = sendto(sk, request, header->nlmsg_len, 0,
159 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
170 int connman_inet_ifindex(const char *name)
178 sk = socket(PF_INET, SOCK_DGRAM, 0);
182 memset(&ifr, 0, sizeof(ifr));
183 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
185 err = ioctl(sk, SIOCGIFINDEX, &ifr);
192 return ifr.ifr_ifindex;
195 char *connman_inet_ifname(int index)
203 sk = socket(PF_INET, SOCK_DGRAM, 0);
207 memset(&ifr, 0, sizeof(ifr));
208 ifr.ifr_ifindex = index;
210 err = ioctl(sk, SIOCGIFNAME, &ifr);
217 return strdup(ifr.ifr_name);
220 short int connman_inet_ifflags(int index)
225 sk = socket(PF_INET, SOCK_DGRAM, 0);
229 memset(&ifr, 0, sizeof(ifr));
230 ifr.ifr_ifindex = index;
232 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
237 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
250 int connman_inet_ifup(int index)
255 sk = socket(PF_INET, SOCK_DGRAM, 0);
259 memset(&ifr, 0, sizeof(ifr));
260 ifr.ifr_ifindex = index;
262 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
267 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
272 if (ifr.ifr_flags & IFF_UP) {
277 ifr.ifr_flags |= IFF_UP;
279 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
292 int connman_inet_ifdown(int index)
297 sk = socket(PF_INET, SOCK_DGRAM, 0);
301 memset(&ifr, 0, sizeof(ifr));
302 ifr.ifr_ifindex = index;
304 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
309 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
314 if (!(ifr.ifr_flags & IFF_UP)) {
319 ifr.ifr_flags &= ~IFF_UP;
321 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
332 static char *index2addr(int index)
335 struct ether_addr eth;
342 sk = socket(PF_INET, SOCK_DGRAM, 0);
346 memset(&ifr, 0, sizeof(ifr));
347 ifr.ifr_ifindex = index;
349 err = ioctl(sk, SIOCGIFNAME, &ifr);
352 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
363 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
364 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
365 eth.ether_addr_octet[0],
366 eth.ether_addr_octet[1],
367 eth.ether_addr_octet[2],
368 eth.ether_addr_octet[3],
369 eth.ether_addr_octet[4],
370 eth.ether_addr_octet[5]);
375 static char *index2ident(int index, const char *prefix)
378 struct ether_addr eth;
385 sk = socket(PF_INET, SOCK_DGRAM, 0);
389 memset(&ifr, 0, sizeof(ifr));
390 ifr.ifr_ifindex = index;
392 err = ioctl(sk, SIOCGIFNAME, &ifr);
395 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
402 len = prefix ? strlen(prefix) + 18 : 18;
408 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
409 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
410 prefix ? prefix : "",
411 eth.ether_addr_octet[0],
412 eth.ether_addr_octet[1],
413 eth.ether_addr_octet[2],
414 eth.ether_addr_octet[3],
415 eth.ether_addr_octet[4],
416 eth.ether_addr_octet[5]);
421 connman_bool_t connman_inet_is_cfg80211(int index)
423 connman_bool_t result = FALSE;
424 char phy80211_path[PATH_MAX];
429 sk = socket(PF_INET, SOCK_DGRAM, 0);
433 memset(&ifr, 0, sizeof(ifr));
434 ifr.ifr_ifindex = index;
436 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
439 snprintf(phy80211_path, PATH_MAX,
440 "/sys/class/net/%s/phy80211", ifr.ifr_name);
442 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
451 struct connman_device *connman_inet_create_device(int index)
453 enum connman_device_type type;
454 struct connman_device *device;
455 char *devname, *ident = NULL;
456 char *addr = NULL, *name = NULL;
461 devname = connman_inet_ifname(index);
465 if (__connman_device_isfiltered(devname) == TRUE) {
466 connman_info("Ignoring interface %s (filtered)", devname);
471 type = __connman_rtnl_get_device_type(index);
474 case CONNMAN_DEVICE_TYPE_UNKNOWN:
475 connman_info("Ignoring interface %s (type unknown)", devname);
478 case CONNMAN_DEVICE_TYPE_ETHERNET:
479 case CONNMAN_DEVICE_TYPE_GADGET:
480 case CONNMAN_DEVICE_TYPE_WIFI:
481 case CONNMAN_DEVICE_TYPE_WIMAX:
482 name = index2ident(index, "");
483 addr = index2addr(index);
485 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
486 case CONNMAN_DEVICE_TYPE_CELLULAR:
487 case CONNMAN_DEVICE_TYPE_GPS:
488 case CONNMAN_DEVICE_TYPE_VENDOR:
489 name = strdup(devname);
493 device = connman_device_create(name, type);
498 case CONNMAN_DEVICE_TYPE_UNKNOWN:
499 case CONNMAN_DEVICE_TYPE_VENDOR:
500 case CONNMAN_DEVICE_TYPE_GPS:
502 case CONNMAN_DEVICE_TYPE_ETHERNET:
503 case CONNMAN_DEVICE_TYPE_GADGET:
504 ident = index2ident(index, NULL);
506 case CONNMAN_DEVICE_TYPE_WIFI:
507 case CONNMAN_DEVICE_TYPE_WIMAX:
508 ident = index2ident(index, NULL);
510 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
512 case CONNMAN_DEVICE_TYPE_CELLULAR:
513 ident = index2ident(index, NULL);
517 connman_device_set_index(device, index);
518 connman_device_set_interface(device, devname);
521 connman_device_set_ident(device, ident);
525 connman_device_set_string(device, "Address", addr);
536 struct in6_addr ifr6_addr;
537 __u32 ifr6_prefixlen;
538 unsigned int ifr6_ifindex;
541 int connman_inet_set_ipv6_address(int index,
542 struct connman_ipaddress *ipaddress)
544 unsigned char prefix_len;
547 if (ipaddress->local == NULL)
550 prefix_len = ipaddress->prefixlen;
551 address = ipaddress->local;
553 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
555 if ((__connman_inet_modify_address(RTM_NEWADDR,
556 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
557 address, NULL, prefix_len, NULL)) < 0) {
558 connman_error("Set IPv6 address error");
565 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
567 unsigned char prefix_len;
568 const char *address, *broadcast, *peer;
570 if (ipaddress->local == NULL)
573 prefix_len = ipaddress->prefixlen;
574 address = ipaddress->local;
575 broadcast = ipaddress->broadcast;
576 peer = ipaddress->peer;
578 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
580 if ((__connman_inet_modify_address(RTM_NEWADDR,
581 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
582 address, peer, prefix_len, broadcast)) < 0) {
583 DBG("address setting failed");
590 int connman_inet_clear_ipv6_address(int index, const char *address,
593 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
595 if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
596 address, NULL, prefix_len, NULL)) < 0) {
597 connman_error("Clear IPv6 address error");
604 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
606 unsigned char prefix_len;
607 const char *address, *broadcast, *peer;
609 prefix_len = ipaddress->prefixlen;
610 address = ipaddress->local;
611 broadcast = ipaddress->broadcast;
612 peer = ipaddress->peer;
614 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
616 if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
617 address, peer, prefix_len, broadcast)) < 0) {
618 DBG("address removal failed");
625 int connman_inet_add_host_route(int index, const char *host,
628 return connman_inet_add_network_route(index, host, gateway, NULL);
631 int connman_inet_del_host_route(int index, const char *host)
633 return connman_inet_del_network_route(index, host);
636 int connman_inet_add_network_route(int index, const char *host,
642 struct sockaddr_in addr;
645 sk = socket(PF_INET, SOCK_DGRAM, 0);
649 memset(&ifr, 0, sizeof(ifr));
650 ifr.ifr_ifindex = index;
652 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
657 DBG("ifname %s", ifr.ifr_name);
659 memset(&rt, 0, sizeof(rt));
660 rt.rt_flags = RTF_UP;
662 rt.rt_flags |= RTF_GATEWAY;
664 rt.rt_flags |= RTF_HOST;
666 memset(&addr, 0, sizeof(addr));
667 addr.sin_family = AF_INET;
668 addr.sin_addr.s_addr = inet_addr(host);
669 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
671 memset(&addr, 0, sizeof(addr));
672 addr.sin_family = AF_INET;
674 addr.sin_addr.s_addr = inet_addr(gateway);
676 addr.sin_addr.s_addr = INADDR_ANY;
677 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
679 memset(&addr, 0, sizeof(addr));
680 addr.sin_family = AF_INET;
681 addr.sin_addr.s_addr = INADDR_ANY;
683 addr.sin_addr.s_addr = inet_addr(netmask);
685 addr.sin_addr.s_addr = INADDR_ANY;
686 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
688 rt.rt_dev = ifr.ifr_name;
690 err = ioctl(sk, SIOCADDRT, &rt);
692 connman_error("Adding host route failed (%s)",
700 int connman_inet_del_network_route(int index, const char *host)
704 struct sockaddr_in addr;
707 sk = socket(PF_INET, SOCK_DGRAM, 0);
711 memset(&ifr, 0, sizeof(ifr));
712 ifr.ifr_ifindex = index;
714 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
719 DBG("ifname %s", ifr.ifr_name);
721 memset(&rt, 0, sizeof(rt));
722 rt.rt_flags = RTF_UP | RTF_HOST;
724 memset(&addr, 0, sizeof(addr));
725 addr.sin_family = AF_INET;
726 addr.sin_addr.s_addr = inet_addr(host);
727 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
729 rt.rt_dev = ifr.ifr_name;
731 err = ioctl(sk, SIOCDELRT, &rt);
733 connman_error("Deleting host route failed (%s)",
741 int connman_inet_del_ipv6_network_route(int index, const char *host,
742 unsigned char prefix_len)
747 DBG("index %d host %s", index, host);
752 memset(&rt, 0, sizeof(rt));
754 rt.rtmsg_dst_len = prefix_len;
756 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
760 rt.rtmsg_flags = RTF_UP | RTF_HOST;
763 rt.rtmsg_ifindex = index;
765 sk = socket(AF_INET6, SOCK_DGRAM, 0);
771 err = ioctl(sk, SIOCDELRT, &rt);
775 connman_error("Del IPv6 host route error");
780 int connman_inet_del_ipv6_host_route(int index, const char *host)
782 return connman_inet_del_ipv6_network_route(index, host, 128);
785 int connman_inet_add_ipv6_network_route(int index, const char *host,
787 unsigned char prefix_len)
792 DBG("index %d host %s gateway %s", index, host, gateway);
797 memset(&rt, 0, sizeof(rt));
799 rt.rtmsg_dst_len = prefix_len;
801 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
805 rt.rtmsg_flags = RTF_UP | RTF_HOST;
807 if (gateway != NULL) {
808 rt.rtmsg_flags |= RTF_GATEWAY;
809 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
813 rt.rtmsg_ifindex = index;
815 sk = socket(AF_INET6, SOCK_DGRAM, 0);
821 err = ioctl(sk, SIOCADDRT, &rt);
825 connman_error("Set IPv6 host route error");
830 int connman_inet_add_ipv6_host_route(int index, const char *host,
833 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
836 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
841 DBG("index %d, gateway %s", index, gateway);
846 memset(&rt, 0, sizeof(rt));
848 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
852 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
854 rt.rtmsg_dst_len = 0;
855 rt.rtmsg_ifindex = index;
857 sk = socket(AF_INET6, SOCK_DGRAM, 0);
863 err = ioctl(sk, SIOCADDRT, &rt);
867 connman_error("Set default IPv6 gateway error");
872 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
877 DBG("index %d, gateway %s", index, gateway);
882 memset(&rt, 0, sizeof(rt));
884 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
888 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
890 rt.rtmsg_dst_len = 0;
891 rt.rtmsg_ifindex = index;
893 sk = socket(AF_INET6, SOCK_DGRAM, 0);
899 err = ioctl(sk, SIOCDELRT, &rt);
903 connman_error("Clear default IPv6 gateway error");
908 int connman_inet_set_gateway_address(int index, const char *gateway)
912 struct sockaddr_in addr;
915 sk = socket(PF_INET, SOCK_DGRAM, 0);
919 memset(&ifr, 0, sizeof(ifr));
920 ifr.ifr_ifindex = index;
922 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
927 DBG("ifname %s", ifr.ifr_name);
929 memset(&rt, 0, sizeof(rt));
930 rt.rt_flags = RTF_UP | RTF_GATEWAY;
932 memset(&addr, 0, sizeof(addr));
933 addr.sin_family = AF_INET;
934 addr.sin_addr.s_addr = INADDR_ANY;
935 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
937 memset(&addr, 0, sizeof(addr));
938 addr.sin_family = AF_INET;
939 addr.sin_addr.s_addr = inet_addr(gateway);
940 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
942 memset(&addr, 0, sizeof(addr));
943 addr.sin_family = AF_INET;
944 addr.sin_addr.s_addr = INADDR_ANY;
945 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
947 err = ioctl(sk, SIOCADDRT, &rt);
949 connman_error("Setting default gateway route failed (%s)",
957 int connman_inet_set_gateway_interface(int index)
961 struct sockaddr_in addr;
966 sk = socket(PF_INET, SOCK_DGRAM, 0);
970 memset(&ifr, 0, sizeof(ifr));
971 ifr.ifr_ifindex = index;
973 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
978 DBG("ifname %s", ifr.ifr_name);
980 memset(&rt, 0, sizeof(rt));
981 rt.rt_flags = RTF_UP;
983 memset(&addr, 0, sizeof(addr));
984 addr.sin_family = AF_INET;
985 addr.sin_addr.s_addr = INADDR_ANY;
987 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
988 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
989 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
991 rt.rt_dev = ifr.ifr_name;
993 err = ioctl(sk, SIOCADDRT, &rt);
995 connman_error("Setting default interface route failed (%s)",
1002 int connman_inet_clear_gateway_address(int index, const char *gateway)
1006 struct sockaddr_in addr;
1011 sk = socket(PF_INET, SOCK_DGRAM, 0);
1015 memset(&ifr, 0, sizeof(ifr));
1016 ifr.ifr_ifindex = index;
1018 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1023 DBG("ifname %s", ifr.ifr_name);
1025 memset(&rt, 0, sizeof(rt));
1026 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1028 memset(&addr, 0, sizeof(addr));
1029 addr.sin_family = AF_INET;
1030 addr.sin_addr.s_addr = INADDR_ANY;
1031 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1033 memset(&addr, 0, sizeof(addr));
1034 addr.sin_family = AF_INET;
1035 addr.sin_addr.s_addr = inet_addr(gateway);
1036 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1038 memset(&addr, 0, sizeof(addr));
1039 addr.sin_family = AF_INET;
1040 addr.sin_addr.s_addr = INADDR_ANY;
1041 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1043 err = ioctl(sk, SIOCDELRT, &rt);
1045 connman_error("Removing default gateway route failed (%s)",
1053 int connman_inet_clear_gateway_interface(int index)
1057 struct sockaddr_in addr;
1062 sk = socket(PF_INET, SOCK_DGRAM, 0);
1066 memset(&ifr, 0, sizeof(ifr));
1067 ifr.ifr_ifindex = index;
1069 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1074 DBG("ifname %s", ifr.ifr_name);
1076 memset(&rt, 0, sizeof(rt));
1077 rt.rt_flags = RTF_UP;
1079 memset(&addr, 0, sizeof(addr));
1080 addr.sin_family = AF_INET;
1081 addr.sin_addr.s_addr = INADDR_ANY;
1083 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1084 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1085 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1087 rt.rt_dev = ifr.ifr_name;
1089 err = ioctl(sk, SIOCDELRT, &rt);
1091 connman_error("Removing default interface route failed (%s)",
1098 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1101 struct in_addr _host_addr;
1102 in_addr_t host_addr, netmask_addr, if_addr;
1103 struct sockaddr_in *netmask, *addr;
1106 DBG("host %s", host);
1111 if (inet_aton(host, &_host_addr) == 0)
1113 host_addr = _host_addr.s_addr;
1115 sk = socket(PF_INET, SOCK_DGRAM, 0);
1119 memset(&ifr, 0, sizeof(ifr));
1120 ifr.ifr_ifindex = index;
1122 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1127 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1132 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1133 netmask_addr = netmask->sin_addr.s_addr;
1135 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1139 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1140 if_addr = addr->sin_addr.s_addr;
1142 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1145 int connman_inet_remove_from_bridge(int index, const char *bridge)
1153 sk = socket(AF_INET, SOCK_STREAM, 0);
1157 memset(&ifr, 0, sizeof(ifr));
1158 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1159 ifr.ifr_ifindex = index;
1161 err = ioctl(sk, SIOCBRDELIF, &ifr);
1166 connman_error("Remove interface from bridge error %s",
1174 int connman_inet_add_to_bridge(int index, const char *bridge)
1182 sk = socket(AF_INET, SOCK_STREAM, 0);
1186 memset(&ifr, 0, sizeof(ifr));
1187 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1188 ifr.ifr_ifindex = index;
1190 err = ioctl(sk, SIOCBRADDIF, &ifr);
1195 connman_error("Add interface to bridge error %s",
1203 int connman_inet_set_mtu(int index, int mtu)
1208 sk = socket(AF_INET, SOCK_DGRAM, 0);
1212 memset(&ifr, 0, sizeof(ifr));
1213 ifr.ifr_ifindex = index;
1215 err = ioctl(sk, SIOCGIFNAME, &ifr);
1218 err = ioctl(sk, SIOCSIFMTU, &ifr);
1225 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1235 sk = socket(AF_INET, SOCK_DGRAM, 0);
1239 index = if_nametoindex(tunnel);
1241 err = connman_inet_set_mtu(index, mtu);
1247 memset(&ifr, 0, sizeof(ifr));
1248 strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1249 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1256 if ((ifr.ifr_flags ^ flags) & mask) {
1257 ifr.ifr_flags &= ~mask;
1258 ifr.ifr_flags |= mask & flags;
1259 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1261 connman_error("SIOCSIFFLAGS failed: %s",
1270 int connman_inet_create_tunnel(char **iface)
1275 fd = open("/dev/net/tun", O_RDWR);
1278 connman_error("Failed to open /dev/net/tun: %s",
1283 memset(&ifr, 0, sizeof(ifr));
1284 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1286 for (i = 0; i < 256; i++) {
1287 sprintf(ifr.ifr_name, "tun%d", i);
1289 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1294 connman_error("Failed to find available tun device");
1299 *iface = g_strdup(ifr.ifr_name);
1305 GIOChannel *channel;
1306 __connman_inet_rs_cb_t callback;
1307 struct sockaddr_in6 addr;
1312 #define CMSG_BUF_LEN 512
1313 #define IN6ADDR_ALL_NODES_MC_INIT \
1314 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1315 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1316 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1318 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1319 static const struct in6_addr in6addr_all_routers_mc =
1320 IN6ADDR_ALL_ROUTERS_MC_INIT;
1322 /* from netinet/in.h */
1323 struct in6_pktinfo {
1324 struct in6_addr ipi6_addr; /* src/dst IPv6 address */
1325 unsigned int ipi6_ifindex; /* send/recv interface index */
1328 static void rs_cleanup(struct rs_cb_data *data)
1330 g_io_channel_shutdown(data->channel, TRUE, NULL);
1331 g_io_channel_unref(data->channel);
1334 if (data->rs_timeout > 0)
1335 g_source_remove(data->rs_timeout);
1340 static gboolean rs_timeout_cb(gpointer user_data)
1342 struct rs_cb_data *data = user_data;
1344 DBG("user data %p", user_data);
1349 if (data->callback != NULL)
1350 data->callback(NULL, data->user_data);
1352 data->rs_timeout = 0;
1357 static int icmpv6_recv(int fd, gpointer user_data)
1361 unsigned char chdr[CMSG_BUF_LEN];
1362 unsigned char buf[1540];
1363 struct rs_cb_data *data = user_data;
1364 struct nd_router_advert *hdr;
1365 struct sockaddr_in6 saddr;
1370 iov.iov_len = sizeof(buf);
1373 mhdr.msg_name = (void *)&saddr;
1374 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1375 mhdr.msg_iov = &iov;
1376 mhdr.msg_iovlen = 1;
1377 mhdr.msg_control = (void *)chdr;
1378 mhdr.msg_controllen = CMSG_BUF_LEN;
1380 len = recvmsg(fd, &mhdr, 0);
1382 data->callback(NULL, data->user_data);
1386 hdr = (struct nd_router_advert *)buf;
1387 if (hdr->nd_ra_code != 0)
1390 data->callback(hdr, data->user_data);
1396 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1403 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1406 fd = g_io_channel_unix_get_fd(chan);
1407 ret = icmpv6_recv(fd, data);
1414 /* Adapted from RFC 1071 "C" Implementation Example */
1415 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1417 register unsigned long sum = 0;
1422 /* caller must make sure datalen is even */
1424 addr = (uint16_t *)phdr;
1425 for (i = 0; i < 20; i++)
1429 addr = (uint16_t *)data;
1437 sum = (sum & 0xffff) + (sum >> 16);
1439 return (uint16_t)~sum;
1442 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1445 struct in6_addr src;
1446 struct in6_addr dst;
1448 uint8_t reserved[3];
1455 struct icmp6_hdr icmp;
1456 struct nd_neighbor_solicit ns;
1457 struct nd_router_solicit rs;
1462 struct cmsghdr *cmsg;
1463 struct in6_pktinfo *pinfo;
1464 struct sockaddr_in6 dst;
1465 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1467 int fd, datalen, ret;
1471 fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
1475 memset(&frame, 0, sizeof(frame));
1476 memset(&dst, 0, sizeof(dst));
1478 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1479 dst.sin6_addr = *dest;
1481 /* Fill in the IPv6 header */
1482 frame.ip.ip6_vfc = 0x60;
1483 frame.ip.ip6_plen = htons(datalen);
1484 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1485 frame.ip.ip6_hlim = 255;
1486 frame.ip.ip6_dst = dst.sin6_addr;
1487 /* all other fields are already set to zero */
1489 /* Prepare pseudo header for csum */
1490 memset(&phdr, 0, sizeof(phdr));
1491 phdr.dst = dst.sin6_addr;
1492 phdr.plen = htonl(datalen);
1493 phdr.nxt = IPPROTO_ICMPV6;
1495 /* Fill in remaining ICMP header fields */
1496 frame.i.icmp.icmp6_type = type;
1497 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1499 iov.iov_base = &frame;
1500 iov.iov_len = sizeof(frame.ip) + datalen;
1502 dst.sin6_family = AF_INET6;
1503 msgh.msg_name = &dst;
1504 msgh.msg_namelen = sizeof(dst);
1505 msgh.msg_iov = &iov;
1506 msgh.msg_iovlen = 1;
1509 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1510 cmsg = (struct cmsghdr *)cbuf;
1511 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1512 pinfo->ipi6_ifindex = oif;
1514 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1515 cmsg->cmsg_level = IPPROTO_IPV6;
1516 cmsg->cmsg_type = IPV6_PKTINFO;
1517 msgh.msg_control = cmsg;
1518 msgh.msg_controllen = cmsg->cmsg_len;
1520 ret = sendmsg(fd, &msgh, 0);
1526 static inline void ipv6_addr_set(struct in6_addr *addr,
1527 uint32_t w1, uint32_t w2,
1528 uint32_t w3, uint32_t w4)
1530 addr->s6_addr32[0] = w1;
1531 addr->s6_addr32[1] = w2;
1532 addr->s6_addr32[2] = w3;
1533 addr->s6_addr32[3] = w4;
1536 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1537 struct in6_addr *solicited)
1539 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1540 htonl(0xFF000000) | addr->s6_addr32[3]);
1543 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1546 unsigned int val = 0;
1547 struct ipv6_mreq mreq;
1550 memset(&mreq, 0, sizeof(mreq));
1551 mreq.ipv6mr_interface = ifindex;
1552 mreq.ipv6mr_multiaddr = *mc_addr;
1554 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1560 return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1563 int __connman_inet_ipv6_send_rs(int index, int timeout,
1564 __connman_inet_rs_cb_t callback, void *user_data)
1566 struct rs_cb_data *data;
1567 struct icmp6_filter filter;
1568 struct in6_addr solicit;
1569 struct in6_addr dst = in6addr_all_routers_mc;
1577 data = g_try_malloc0(sizeof(struct rs_cb_data));
1581 data->callback = callback;
1582 data->user_data = user_data;
1583 data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1585 sk = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
1589 ICMP6_FILTER_SETBLOCKALL(&filter);
1590 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1592 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1593 sizeof(struct icmp6_filter));
1595 ipv6_addr_solict_mult(&dst, &solicit);
1596 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1597 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1599 data->channel = g_io_channel_unix_new(sk);
1600 g_io_channel_set_close_on_unref(data->channel, TRUE);
1602 g_io_channel_set_encoding(data->channel, NULL, NULL);
1603 g_io_channel_set_buffered(data->channel, FALSE);
1605 g_io_add_watch(data->channel,
1606 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1607 icmpv6_event, data);
1609 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);