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>
46 #define NLMSG_TAIL(nmsg) \
47 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
48 NLMSG_ALIGN((nmsg)->nlmsg_len)))
50 static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
51 const void *data, size_t data_length)
56 length = RTA_LENGTH(data_length);
58 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
63 rta->rta_len = length;
64 memcpy(RTA_DATA(rta), data, data_length);
65 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
70 int __connman_inet_modify_address(int cmd, int flags,
71 int index, int family,
74 unsigned char prefixlen,
75 const char *broadcast)
77 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
78 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
79 RTA_LENGTH(sizeof(struct in6_addr)) +
80 RTA_LENGTH(sizeof(struct in6_addr))];
82 struct nlmsghdr *header;
83 struct sockaddr_nl nl_addr;
84 struct ifaddrmsg *ifaddrmsg;
85 struct in6_addr ipv6_addr;
86 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
94 if (family != AF_INET && family != AF_INET6)
97 memset(&request, 0, sizeof(request));
99 header = (struct nlmsghdr *)request;
100 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
101 header->nlmsg_type = cmd;
102 header->nlmsg_flags = NLM_F_REQUEST | flags;
103 header->nlmsg_seq = 1;
105 ifaddrmsg = NLMSG_DATA(header);
106 ifaddrmsg->ifa_family = family;
107 ifaddrmsg->ifa_prefixlen = prefixlen;
108 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
109 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
110 ifaddrmsg->ifa_index = index;
112 if (family == AF_INET) {
113 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
116 if (broadcast != NULL)
117 inet_pton(AF_INET, broadcast, &ipv4_bcast);
119 ipv4_bcast.s_addr = ipv4_addr.s_addr |
120 htonl(0xfffffffflu >> prefixlen);
123 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
126 if ((err = add_rtattr(header, sizeof(request),
128 &ipv4_dest, sizeof(ipv4_dest))) < 0)
132 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
133 &ipv4_addr, sizeof(ipv4_addr))) < 0)
136 if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
137 &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
140 } else if (family == AF_INET6) {
141 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
144 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
145 &ipv6_addr, sizeof(ipv6_addr))) < 0)
149 sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
153 memset(&nl_addr, 0, sizeof(nl_addr));
154 nl_addr.nl_family = AF_NETLINK;
156 if ((err = sendto(sk, request, header->nlmsg_len, 0,
157 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
168 int connman_inet_ifindex(const char *name)
176 sk = socket(PF_INET, SOCK_DGRAM, 0);
180 memset(&ifr, 0, sizeof(ifr));
181 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
183 err = ioctl(sk, SIOCGIFINDEX, &ifr);
190 return ifr.ifr_ifindex;
193 char *connman_inet_ifname(int index)
201 sk = socket(PF_INET, SOCK_DGRAM, 0);
205 memset(&ifr, 0, sizeof(ifr));
206 ifr.ifr_ifindex = index;
208 err = ioctl(sk, SIOCGIFNAME, &ifr);
215 return strdup(ifr.ifr_name);
218 short int connman_inet_ifflags(int index)
223 sk = socket(PF_INET, SOCK_DGRAM, 0);
227 memset(&ifr, 0, sizeof(ifr));
228 ifr.ifr_ifindex = index;
230 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
235 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
248 int connman_inet_ifup(int index)
253 sk = socket(PF_INET, SOCK_DGRAM, 0);
257 memset(&ifr, 0, sizeof(ifr));
258 ifr.ifr_ifindex = index;
260 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
265 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
270 if (ifr.ifr_flags & IFF_UP) {
275 ifr.ifr_flags |= IFF_UP;
277 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
290 int connman_inet_ifdown(int index)
295 sk = socket(PF_INET, SOCK_DGRAM, 0);
299 memset(&ifr, 0, sizeof(ifr));
300 ifr.ifr_ifindex = index;
302 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
307 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
312 if (!(ifr.ifr_flags & IFF_UP)) {
317 ifr.ifr_flags &= ~IFF_UP;
319 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
330 static char *index2addr(int index)
333 struct ether_addr eth;
340 sk = socket(PF_INET, SOCK_DGRAM, 0);
344 memset(&ifr, 0, sizeof(ifr));
345 ifr.ifr_ifindex = index;
347 err = ioctl(sk, SIOCGIFNAME, &ifr);
350 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
361 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
362 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
363 eth.ether_addr_octet[0],
364 eth.ether_addr_octet[1],
365 eth.ether_addr_octet[2],
366 eth.ether_addr_octet[3],
367 eth.ether_addr_octet[4],
368 eth.ether_addr_octet[5]);
373 static char *index2ident(int index, const char *prefix)
376 struct ether_addr eth;
383 sk = socket(PF_INET, SOCK_DGRAM, 0);
387 memset(&ifr, 0, sizeof(ifr));
388 ifr.ifr_ifindex = index;
390 err = ioctl(sk, SIOCGIFNAME, &ifr);
393 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
400 len = prefix ? strlen(prefix) + 18 : 18;
406 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
407 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
408 prefix ? prefix : "",
409 eth.ether_addr_octet[0],
410 eth.ether_addr_octet[1],
411 eth.ether_addr_octet[2],
412 eth.ether_addr_octet[3],
413 eth.ether_addr_octet[4],
414 eth.ether_addr_octet[5]);
419 connman_bool_t connman_inet_is_cfg80211(int index)
421 connman_bool_t result = FALSE;
422 char phy80211_path[PATH_MAX];
427 sk = socket(PF_INET, SOCK_DGRAM, 0);
431 memset(&ifr, 0, sizeof(ifr));
432 ifr.ifr_ifindex = index;
434 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
437 snprintf(phy80211_path, PATH_MAX,
438 "/sys/class/net/%s/phy80211", ifr.ifr_name);
440 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
449 struct connman_device *connman_inet_create_device(int index)
451 enum connman_device_type type;
452 struct connman_device *device;
453 char *devname, *ident = NULL;
454 char *addr = NULL, *name = NULL;
459 devname = connman_inet_ifname(index);
463 if (__connman_element_device_isfiltered(devname) == TRUE) {
464 connman_info("Ignoring interface %s (filtered)", devname);
469 type = __connman_rtnl_get_device_type(index);
472 case CONNMAN_DEVICE_TYPE_UNKNOWN:
473 connman_info("Ignoring interface %s (type unknown)", devname);
476 case CONNMAN_DEVICE_TYPE_ETHERNET:
477 case CONNMAN_DEVICE_TYPE_GADGET:
478 case CONNMAN_DEVICE_TYPE_WIFI:
479 case CONNMAN_DEVICE_TYPE_WIMAX:
480 name = index2ident(index, "");
481 addr = index2addr(index);
483 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
484 case CONNMAN_DEVICE_TYPE_CELLULAR:
485 case CONNMAN_DEVICE_TYPE_GPS:
486 case CONNMAN_DEVICE_TYPE_VENDOR:
487 name = strdup(devname);
491 device = connman_device_create(name, type);
496 case CONNMAN_DEVICE_TYPE_UNKNOWN:
497 case CONNMAN_DEVICE_TYPE_VENDOR:
498 case CONNMAN_DEVICE_TYPE_GPS:
500 case CONNMAN_DEVICE_TYPE_ETHERNET:
501 case CONNMAN_DEVICE_TYPE_GADGET:
502 ident = index2ident(index, NULL);
504 case CONNMAN_DEVICE_TYPE_WIFI:
505 case CONNMAN_DEVICE_TYPE_WIMAX:
506 ident = index2ident(index, NULL);
508 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
510 case CONNMAN_DEVICE_TYPE_CELLULAR:
511 ident = index2ident(index, NULL);
515 connman_device_set_index(device, index);
516 connman_device_set_interface(device, devname);
519 connman_device_set_ident(device, ident);
523 connman_device_set_string(device, "Address", addr);
534 struct in6_addr ifr6_addr;
535 __u32 ifr6_prefixlen;
536 unsigned int ifr6_ifindex;
539 int connman_inet_set_ipv6_address(int index,
540 struct connman_ipaddress *ipaddress)
542 unsigned char prefix_len;
545 if (ipaddress->local == NULL)
548 prefix_len = ipaddress->prefixlen;
549 address = ipaddress->local;
551 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
553 if ((__connman_inet_modify_address(RTM_NEWADDR,
554 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
555 address, NULL, prefix_len, NULL)) < 0) {
556 connman_error("Set IPv6 address error");
563 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
565 unsigned char prefix_len;
566 const char *address, *broadcast, *peer;
568 if (ipaddress->local == NULL)
571 prefix_len = ipaddress->prefixlen;
572 address = ipaddress->local;
573 broadcast = ipaddress->broadcast;
574 peer = ipaddress->peer;
576 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
578 if ((__connman_inet_modify_address(RTM_NEWADDR,
579 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
580 address, peer, prefix_len, broadcast)) < 0) {
581 DBG("address setting failed");
588 int connman_inet_clear_ipv6_address(int index, const char *address,
591 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
593 if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
594 address, NULL, prefix_len, NULL)) < 0) {
595 connman_error("Clear IPv6 address error");
602 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
604 unsigned char prefix_len;
605 const char *address, *broadcast, *peer;
607 prefix_len = ipaddress->prefixlen;
608 address = ipaddress->local;
609 broadcast = ipaddress->broadcast;
610 peer = ipaddress->peer;
612 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
614 if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
615 address, peer, prefix_len, broadcast)) < 0) {
616 DBG("address removal failed");
623 int connman_inet_add_host_route(int index, const char *host,
626 return connman_inet_add_network_route(index, host, gateway, NULL);
629 int connman_inet_del_host_route(int index, const char *host)
631 return connman_inet_del_network_route(index, host);
634 int connman_inet_add_network_route(int index, const char *host,
640 struct sockaddr_in addr;
643 sk = socket(PF_INET, SOCK_DGRAM, 0);
647 memset(&ifr, 0, sizeof(ifr));
648 ifr.ifr_ifindex = index;
650 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
655 DBG("ifname %s", ifr.ifr_name);
657 memset(&rt, 0, sizeof(rt));
658 rt.rt_flags = RTF_UP;
660 rt.rt_flags |= RTF_GATEWAY;
662 rt.rt_flags |= RTF_HOST;
664 memset(&addr, 0, sizeof(addr));
665 addr.sin_family = AF_INET;
666 addr.sin_addr.s_addr = inet_addr(host);
667 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
669 memset(&addr, 0, sizeof(addr));
670 addr.sin_family = AF_INET;
672 addr.sin_addr.s_addr = inet_addr(gateway);
674 addr.sin_addr.s_addr = INADDR_ANY;
675 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
677 memset(&addr, 0, sizeof(addr));
678 addr.sin_family = AF_INET;
679 addr.sin_addr.s_addr = INADDR_ANY;
681 addr.sin_addr.s_addr = inet_addr(netmask);
683 addr.sin_addr.s_addr = INADDR_ANY;
684 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
686 rt.rt_dev = ifr.ifr_name;
688 err = ioctl(sk, SIOCADDRT, &rt);
690 connman_error("Adding host route failed (%s)",
698 int connman_inet_del_network_route(int index, const char *host)
702 struct sockaddr_in addr;
705 sk = socket(PF_INET, SOCK_DGRAM, 0);
709 memset(&ifr, 0, sizeof(ifr));
710 ifr.ifr_ifindex = index;
712 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
717 DBG("ifname %s", ifr.ifr_name);
719 memset(&rt, 0, sizeof(rt));
720 rt.rt_flags = RTF_UP | RTF_HOST;
722 memset(&addr, 0, sizeof(addr));
723 addr.sin_family = AF_INET;
724 addr.sin_addr.s_addr = inet_addr(host);
725 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
727 rt.rt_dev = ifr.ifr_name;
729 err = ioctl(sk, SIOCDELRT, &rt);
731 connman_error("Deleting host route failed (%s)",
739 int connman_inet_del_ipv6_network_route(int index, const char *host,
740 unsigned char prefix_len)
745 DBG("index %d host %s", index, host);
750 memset(&rt, 0, sizeof(rt));
752 rt.rtmsg_dst_len = prefix_len;
754 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
758 rt.rtmsg_flags = RTF_UP | RTF_HOST;
761 rt.rtmsg_ifindex = index;
763 sk = socket(AF_INET6, SOCK_DGRAM, 0);
769 err = ioctl(sk, SIOCDELRT, &rt);
773 connman_error("Del IPv6 host route error");
778 int connman_inet_del_ipv6_host_route(int index, const char *host)
780 return connman_inet_del_ipv6_network_route(index, host, 128);
783 int connman_inet_add_ipv6_network_route(int index, const char *host,
785 unsigned char prefix_len)
790 DBG("index %d host %s gateway %s", index, host, gateway);
795 memset(&rt, 0, sizeof(rt));
797 rt.rtmsg_dst_len = prefix_len;
799 err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
803 rt.rtmsg_flags = RTF_UP | RTF_HOST;
805 if (gateway != NULL) {
806 rt.rtmsg_flags |= RTF_GATEWAY;
807 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
811 rt.rtmsg_ifindex = index;
813 sk = socket(AF_INET6, SOCK_DGRAM, 0);
819 err = ioctl(sk, SIOCADDRT, &rt);
823 connman_error("Set IPv6 host route error");
828 int connman_inet_add_ipv6_host_route(int index, const char *host,
831 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
834 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
839 DBG("index %d, gateway %s", index, gateway);
844 memset(&rt, 0, sizeof(rt));
846 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
850 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
852 rt.rtmsg_dst_len = 0;
853 rt.rtmsg_ifindex = index;
855 sk = socket(AF_INET6, SOCK_DGRAM, 0);
861 err = ioctl(sk, SIOCADDRT, &rt);
865 connman_error("Set default IPv6 gateway error");
870 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
875 DBG("index %d, gateway %s", index, gateway);
880 memset(&rt, 0, sizeof(rt));
882 err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
886 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
888 rt.rtmsg_dst_len = 0;
889 rt.rtmsg_ifindex = index;
891 sk = socket(AF_INET6, SOCK_DGRAM, 0);
897 err = ioctl(sk, SIOCDELRT, &rt);
901 connman_error("Clear default IPv6 gateway error");
906 int connman_inet_set_gateway_address(int index, const char *gateway)
910 struct sockaddr_in addr;
913 sk = socket(PF_INET, SOCK_DGRAM, 0);
917 memset(&ifr, 0, sizeof(ifr));
918 ifr.ifr_ifindex = index;
920 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
925 DBG("ifname %s", ifr.ifr_name);
927 memset(&rt, 0, sizeof(rt));
928 rt.rt_flags = RTF_UP | RTF_GATEWAY;
930 memset(&addr, 0, sizeof(addr));
931 addr.sin_family = AF_INET;
932 addr.sin_addr.s_addr = INADDR_ANY;
933 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
935 memset(&addr, 0, sizeof(addr));
936 addr.sin_family = AF_INET;
937 addr.sin_addr.s_addr = inet_addr(gateway);
938 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
940 memset(&addr, 0, sizeof(addr));
941 addr.sin_family = AF_INET;
942 addr.sin_addr.s_addr = INADDR_ANY;
943 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
945 err = ioctl(sk, SIOCADDRT, &rt);
947 connman_error("Setting default gateway route failed (%s)",
955 int connman_inet_set_gateway_interface(int index)
959 struct sockaddr_in addr;
964 sk = socket(PF_INET, SOCK_DGRAM, 0);
968 memset(&ifr, 0, sizeof(ifr));
969 ifr.ifr_ifindex = index;
971 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
976 DBG("ifname %s", ifr.ifr_name);
978 memset(&rt, 0, sizeof(rt));
979 rt.rt_flags = RTF_UP;
981 memset(&addr, 0, sizeof(addr));
982 addr.sin_family = AF_INET;
983 addr.sin_addr.s_addr = INADDR_ANY;
985 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
986 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
987 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
989 rt.rt_dev = ifr.ifr_name;
991 err = ioctl(sk, SIOCADDRT, &rt);
993 connman_error("Setting default interface route failed (%s)",
1000 int connman_inet_clear_gateway_address(int index, const char *gateway)
1004 struct sockaddr_in addr;
1009 sk = socket(PF_INET, SOCK_DGRAM, 0);
1013 memset(&ifr, 0, sizeof(ifr));
1014 ifr.ifr_ifindex = index;
1016 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1021 DBG("ifname %s", ifr.ifr_name);
1023 memset(&rt, 0, sizeof(rt));
1024 rt.rt_flags = RTF_UP | RTF_GATEWAY;
1026 memset(&addr, 0, sizeof(addr));
1027 addr.sin_family = AF_INET;
1028 addr.sin_addr.s_addr = INADDR_ANY;
1029 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1031 memset(&addr, 0, sizeof(addr));
1032 addr.sin_family = AF_INET;
1033 addr.sin_addr.s_addr = inet_addr(gateway);
1034 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1036 memset(&addr, 0, sizeof(addr));
1037 addr.sin_family = AF_INET;
1038 addr.sin_addr.s_addr = INADDR_ANY;
1039 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1041 err = ioctl(sk, SIOCDELRT, &rt);
1043 connman_error("Removing default gateway route failed (%s)",
1051 int connman_inet_clear_gateway_interface(int index)
1055 struct sockaddr_in addr;
1060 sk = socket(PF_INET, SOCK_DGRAM, 0);
1064 memset(&ifr, 0, sizeof(ifr));
1065 ifr.ifr_ifindex = index;
1067 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1072 DBG("ifname %s", ifr.ifr_name);
1074 memset(&rt, 0, sizeof(rt));
1075 rt.rt_flags = RTF_UP;
1077 memset(&addr, 0, sizeof(addr));
1078 addr.sin_family = AF_INET;
1079 addr.sin_addr.s_addr = INADDR_ANY;
1081 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1082 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1083 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1085 rt.rt_dev = ifr.ifr_name;
1087 err = ioctl(sk, SIOCDELRT, &rt);
1089 connman_error("Removing default interface route failed (%s)",
1096 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1099 struct in_addr _host_addr;
1100 in_addr_t host_addr, netmask_addr, if_addr;
1101 struct sockaddr_in *netmask, *addr;
1104 DBG("host %s", host);
1109 if (inet_aton(host, &_host_addr) == 0)
1111 host_addr = _host_addr.s_addr;
1113 sk = socket(PF_INET, SOCK_DGRAM, 0);
1117 memset(&ifr, 0, sizeof(ifr));
1118 ifr.ifr_ifindex = index;
1120 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1125 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1130 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1131 netmask_addr = netmask->sin_addr.s_addr;
1133 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1137 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1138 if_addr = addr->sin_addr.s_addr;
1140 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1143 int connman_inet_remove_from_bridge(int index, const char *bridge)
1151 sk = socket(AF_INET, SOCK_STREAM, 0);
1155 memset(&ifr, 0, sizeof(ifr));
1156 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1157 ifr.ifr_ifindex = index;
1159 err = ioctl(sk, SIOCBRDELIF, &ifr);
1164 connman_error("Remove interface from bridge error %s",
1172 int connman_inet_add_to_bridge(int index, const char *bridge)
1180 sk = socket(AF_INET, SOCK_STREAM, 0);
1184 memset(&ifr, 0, sizeof(ifr));
1185 strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1186 ifr.ifr_ifindex = index;
1188 err = ioctl(sk, SIOCBRADDIF, &ifr);
1193 connman_error("Add interface to bridge error %s",
1201 int connman_inet_set_mtu(int index, int mtu)
1206 sk = socket(AF_INET, SOCK_DGRAM, 0);
1210 memset(&ifr, 0, sizeof(ifr));
1211 ifr.ifr_ifindex = index;
1213 err = ioctl(sk, SIOCGIFNAME, &ifr);
1216 err = ioctl(sk, SIOCSIFMTU, &ifr);
1223 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1233 sk = socket(AF_INET, SOCK_DGRAM, 0);
1237 index = if_nametoindex(tunnel);
1239 err = connman_inet_set_mtu(index, mtu);
1245 memset(&ifr, 0, sizeof(ifr));
1246 strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1247 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1254 if ((ifr.ifr_flags ^ flags) & mask) {
1255 ifr.ifr_flags &= ~mask;
1256 ifr.ifr_flags |= mask & flags;
1257 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1259 connman_error("SIOCSIFFLAGS failed: %s",
1269 GIOChannel *channel;
1270 __connman_inet_rs_cb_t callback;
1271 struct sockaddr_in6 addr;
1276 #define CMSG_BUF_LEN 512
1277 #define IN6ADDR_ALL_NODES_MC_INIT \
1278 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1279 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1280 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1282 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1283 static const struct in6_addr in6addr_all_routers_mc =
1284 IN6ADDR_ALL_ROUTERS_MC_INIT;
1286 /* from netinet/in.h */
1287 struct in6_pktinfo {
1288 struct in6_addr ipi6_addr; /* src/dst IPv6 address */
1289 unsigned int ipi6_ifindex; /* send/recv interface index */
1292 static void rs_cleanup(struct rs_cb_data *data)
1294 g_io_channel_shutdown(data->channel, TRUE, NULL);
1295 g_io_channel_unref(data->channel);
1298 if (data->rs_timeout > 0)
1299 g_source_remove(data->rs_timeout);
1304 static gboolean rs_timeout_cb(gpointer user_data)
1306 struct rs_cb_data *data = user_data;
1308 DBG("user data %p", user_data);
1313 if (data->callback != NULL)
1314 data->callback(NULL, data->user_data);
1316 data->rs_timeout = 0;
1321 static int icmpv6_recv(int fd, gpointer user_data)
1325 unsigned char chdr[CMSG_BUF_LEN];
1326 unsigned char buf[1540];
1327 struct rs_cb_data *data = user_data;
1328 struct nd_router_advert *hdr;
1329 struct sockaddr_in6 saddr;
1334 iov.iov_len = sizeof(buf);
1337 mhdr.msg_name = (void *)&saddr;
1338 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1339 mhdr.msg_iov = &iov;
1340 mhdr.msg_iovlen = 1;
1341 mhdr.msg_control = (void *)chdr;
1342 mhdr.msg_controllen = CMSG_BUF_LEN;
1344 len = recvmsg(fd, &mhdr, 0);
1346 data->callback(NULL, data->user_data);
1350 hdr = (struct nd_router_advert *)buf;
1351 if (hdr->nd_ra_code != 0)
1354 data->callback(hdr, data->user_data);
1360 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1367 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1370 fd = g_io_channel_unix_get_fd(chan);
1371 ret = icmpv6_recv(fd, data);
1378 /* Adapted from RFC 1071 "C" Implementation Example */
1379 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1381 register unsigned long sum = 0;
1386 /* caller must make sure datalen is even */
1388 addr = (uint16_t *)phdr;
1389 for (i = 0; i < 20; i++)
1393 addr = (uint16_t *)data;
1401 sum = (sum & 0xffff) + (sum >> 16);
1403 return (uint16_t)~sum;
1406 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1409 struct in6_addr src;
1410 struct in6_addr dst;
1412 uint8_t reserved[3];
1419 struct icmp6_hdr icmp;
1420 struct nd_neighbor_solicit ns;
1421 struct nd_router_solicit rs;
1426 struct cmsghdr *cmsg;
1427 struct in6_pktinfo *pinfo;
1428 struct sockaddr_in6 dst;
1429 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1431 int fd, datalen, ret;
1435 fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
1439 memset(&frame, 0, sizeof(frame));
1440 memset(&dst, 0, sizeof(dst));
1442 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1443 dst.sin6_addr = *dest;
1445 /* Fill in the IPv6 header */
1446 frame.ip.ip6_vfc = 0x60;
1447 frame.ip.ip6_plen = htons(datalen);
1448 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1449 frame.ip.ip6_hlim = 255;
1450 frame.ip.ip6_dst = dst.sin6_addr;
1451 /* all other fields are already set to zero */
1453 /* Prepare pseudo header for csum */
1454 memset(&phdr, 0, sizeof(phdr));
1455 phdr.dst = dst.sin6_addr;
1456 phdr.plen = htonl(datalen);
1457 phdr.nxt = IPPROTO_ICMPV6;
1459 /* Fill in remaining ICMP header fields */
1460 frame.i.icmp.icmp6_type = type;
1461 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1463 iov.iov_base = &frame;
1464 iov.iov_len = sizeof(frame.ip) + datalen;
1466 dst.sin6_family = AF_INET6;
1467 msgh.msg_name = &dst;
1468 msgh.msg_namelen = sizeof(dst);
1469 msgh.msg_iov = &iov;
1470 msgh.msg_iovlen = 1;
1473 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1474 cmsg = (struct cmsghdr *)cbuf;
1475 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1476 pinfo->ipi6_ifindex = oif;
1478 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1479 cmsg->cmsg_level = IPPROTO_IPV6;
1480 cmsg->cmsg_type = IPV6_PKTINFO;
1481 msgh.msg_control = cmsg;
1482 msgh.msg_controllen = cmsg->cmsg_len;
1484 ret = sendmsg(fd, &msgh, 0);
1490 static inline void ipv6_addr_set(struct in6_addr *addr,
1491 uint32_t w1, uint32_t w2,
1492 uint32_t w3, uint32_t w4)
1494 addr->s6_addr32[0] = w1;
1495 addr->s6_addr32[1] = w2;
1496 addr->s6_addr32[2] = w3;
1497 addr->s6_addr32[3] = w4;
1500 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1501 struct in6_addr *solicited)
1503 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1504 htonl(0xFF000000) | addr->s6_addr32[3]);
1507 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1510 unsigned int val = 0;
1511 struct ipv6_mreq mreq;
1514 memset(&mreq, 0, sizeof(mreq));
1515 mreq.ipv6mr_interface = ifindex;
1516 mreq.ipv6mr_multiaddr = *mc_addr;
1518 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1524 return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1527 int __connman_inet_ipv6_send_rs(int index, int timeout,
1528 __connman_inet_rs_cb_t callback, void *user_data)
1530 struct rs_cb_data *data;
1531 struct icmp6_filter filter;
1532 struct in6_addr solicit;
1533 struct in6_addr dst = in6addr_all_routers_mc;
1541 data = g_try_malloc0(sizeof(struct rs_cb_data));
1545 data->callback = callback;
1546 data->user_data = user_data;
1547 data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1549 sk = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
1553 ICMP6_FILTER_SETBLOCKALL(&filter);
1554 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1556 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1557 sizeof(struct icmp6_filter));
1559 ipv6_addr_solict_mult(&dst, &solicit);
1560 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1561 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1563 data->channel = g_io_channel_unix_new(sk);
1564 g_io_channel_set_close_on_unref(data->channel, TRUE);
1566 g_io_channel_set_encoding(data->channel, NULL, NULL);
1567 g_io_channel_set_buffered(data->channel, FALSE);
1569 g_io_add_watch(data->channel,
1570 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1571 icmpv6_event, data);
1573 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);