5 * Copyright (C) 2007-2013 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>
49 #include <linux/fib_rules.h>
52 #include <gdhcp/gdhcp.h>
54 #define NLMSG_TAIL(nmsg) \
55 ((struct rtattr *) (((uint8_t*) (nmsg)) + \
56 NLMSG_ALIGN((nmsg)->nlmsg_len)))
58 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
59 int type, const void *data, size_t data_length)
64 length = RTA_LENGTH(data_length);
66 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
71 rta->rta_len = length;
72 memcpy(RTA_DATA(rta), data, data_length);
73 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
78 int __connman_inet_modify_address(int cmd, int flags,
79 int index, int family,
82 unsigned char prefixlen,
83 const char *broadcast)
85 uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
86 NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
87 RTA_LENGTH(sizeof(struct in6_addr)) +
88 RTA_LENGTH(sizeof(struct in6_addr))];
90 struct nlmsghdr *header;
91 struct sockaddr_nl nl_addr;
92 struct ifaddrmsg *ifaddrmsg;
93 struct in6_addr ipv6_addr;
94 struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
97 DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
98 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
99 address, peer, prefixlen, broadcast);
104 if (family != AF_INET && family != AF_INET6)
107 memset(&request, 0, sizeof(request));
109 header = (struct nlmsghdr *)request;
110 header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
111 header->nlmsg_type = cmd;
112 header->nlmsg_flags = NLM_F_REQUEST | flags;
113 header->nlmsg_seq = 1;
115 ifaddrmsg = NLMSG_DATA(header);
116 ifaddrmsg->ifa_family = family;
117 ifaddrmsg->ifa_prefixlen = prefixlen;
118 ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
119 ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
120 ifaddrmsg->ifa_index = index;
122 if (family == AF_INET) {
123 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
127 inet_pton(AF_INET, broadcast, &ipv4_bcast);
129 ipv4_bcast.s_addr = ipv4_addr.s_addr |
130 htonl(0xfffffffflu >> prefixlen);
133 if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
136 err = __connman_inet_rtnl_addattr_l(header,
145 err = __connman_inet_rtnl_addattr_l(header,
153 err = __connman_inet_rtnl_addattr_l(header,
161 } else if (family == AF_INET6) {
162 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
165 err = __connman_inet_rtnl_addattr_l(header,
174 sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
178 memset(&nl_addr, 0, sizeof(nl_addr));
179 nl_addr.nl_family = AF_NETLINK;
181 if ((err = sendto(sk, request, header->nlmsg_len, 0,
182 (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
193 int connman_inet_ifindex(const char *name)
201 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
205 memset(&ifr, 0, sizeof(ifr));
206 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
208 err = ioctl(sk, SIOCGIFINDEX, &ifr);
215 return ifr.ifr_ifindex;
218 char *connman_inet_ifname(int index)
226 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
230 memset(&ifr, 0, sizeof(ifr));
231 ifr.ifr_ifindex = index;
233 err = ioctl(sk, SIOCGIFNAME, &ifr);
240 return g_strdup(ifr.ifr_name);
243 int connman_inet_ifup(int index)
248 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
252 memset(&ifr, 0, sizeof(ifr));
253 ifr.ifr_ifindex = index;
255 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
260 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
265 if (ifr.ifr_flags & IFF_UP) {
270 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
272 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
285 int connman_inet_ifdown(int index)
287 struct ifreq ifr, addr_ifr;
288 struct sockaddr_in *addr;
291 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
295 memset(&ifr, 0, sizeof(ifr));
296 ifr.ifr_ifindex = index;
298 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
303 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
308 memset(&addr_ifr, 0, sizeof(addr_ifr));
309 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
310 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
311 addr->sin_family = AF_INET;
312 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
313 connman_warn("Could not clear IPv4 address index %d", index);
315 if (!(ifr.ifr_flags & IFF_UP)) {
320 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
322 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
333 #if defined TIZEN_EXT
334 void connman_inet_update_device_ident(struct connman_device *device)
337 enum connman_device_type type;
338 char *ident = NULL, *addr = NULL;
340 index = connman_device_get_index(device);
341 type = connman_device_get_type(device);
344 case CONNMAN_DEVICE_TYPE_UNKNOWN:
346 case CONNMAN_DEVICE_TYPE_ETHERNET:
347 case CONNMAN_DEVICE_TYPE_GADGET:
348 case CONNMAN_DEVICE_TYPE_WIFI:
349 addr = index2addr(index);
351 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
352 case CONNMAN_DEVICE_TYPE_CELLULAR:
353 case CONNMAN_DEVICE_TYPE_GPS:
354 case CONNMAN_DEVICE_TYPE_VENDOR:
359 case CONNMAN_DEVICE_TYPE_UNKNOWN:
360 case CONNMAN_DEVICE_TYPE_VENDOR:
361 case CONNMAN_DEVICE_TYPE_GPS:
363 case CONNMAN_DEVICE_TYPE_ETHERNET:
364 case CONNMAN_DEVICE_TYPE_GADGET:
365 ident = index2ident(index, NULL);
367 case CONNMAN_DEVICE_TYPE_WIFI:
368 ident = index2ident(index, NULL);
370 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
372 case CONNMAN_DEVICE_TYPE_CELLULAR:
373 ident = index2ident(index, NULL);
378 connman_device_set_ident(device, ident);
383 connman_device_set_string(device, "Address", addr);
390 struct in6_addr ifr6_addr;
391 __u32 ifr6_prefixlen;
392 unsigned int ifr6_ifindex;
395 int connman_inet_set_ipv6_address(int index,
396 struct connman_ipaddress *ipaddress)
399 unsigned char prefix_len;
402 if (!ipaddress->local)
405 prefix_len = ipaddress->prefixlen;
406 address = ipaddress->local;
408 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
410 err = __connman_inet_modify_address(RTM_NEWADDR,
411 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
412 address, NULL, prefix_len, NULL);
414 connman_error("%s: %s", __func__, strerror(-err));
421 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
424 unsigned char prefix_len;
425 const char *address, *broadcast, *peer;
427 if (!ipaddress->local)
430 prefix_len = ipaddress->prefixlen;
431 address = ipaddress->local;
432 broadcast = ipaddress->broadcast;
433 peer = ipaddress->peer;
435 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
437 err = __connman_inet_modify_address(RTM_NEWADDR,
438 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
439 address, peer, prefix_len, broadcast);
441 connman_error("%s: %s", __func__, strerror(-err));
448 int connman_inet_clear_ipv6_address(int index, const char *address,
453 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
458 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
459 address, NULL, prefix_len, NULL);
461 connman_error("%s: %s", __func__, strerror(-err));
468 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
471 unsigned char prefix_len;
472 const char *address, *broadcast, *peer;
474 prefix_len = ipaddress->prefixlen;
475 address = ipaddress->local;
476 broadcast = ipaddress->broadcast;
477 peer = ipaddress->peer;
479 DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
480 address, prefix_len, peer, broadcast);
485 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
486 address, peer, prefix_len, broadcast);
488 connman_error("%s: %s", __func__, strerror(-err));
495 int connman_inet_add_host_route(int index, const char *host,
498 return connman_inet_add_network_route(index, host, gateway, NULL);
501 int connman_inet_del_host_route(int index, const char *host)
503 return connman_inet_del_network_route(index, host);
506 int connman_inet_add_network_route(int index, const char *host,
512 struct sockaddr_in addr;
515 DBG("index %d host %s gateway %s netmask %s", index,
516 host, gateway, netmask);
518 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
524 memset(&ifr, 0, sizeof(ifr));
525 ifr.ifr_ifindex = index;
527 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
533 DBG("ifname %s", ifr.ifr_name);
535 memset(&rt, 0, sizeof(rt));
536 rt.rt_flags = RTF_UP;
538 rt.rt_flags |= RTF_GATEWAY;
540 rt.rt_flags |= RTF_HOST;
542 memset(&addr, 0, sizeof(addr));
543 addr.sin_family = AF_INET;
544 addr.sin_addr.s_addr = inet_addr(host);
545 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
547 memset(&addr, 0, sizeof(addr));
548 addr.sin_family = AF_INET;
550 addr.sin_addr.s_addr = inet_addr(gateway);
552 addr.sin_addr.s_addr = INADDR_ANY;
553 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
555 memset(&addr, 0, sizeof(addr));
556 addr.sin_family = AF_INET;
557 addr.sin_addr.s_addr = INADDR_ANY;
559 addr.sin_addr.s_addr = inet_addr(netmask);
561 addr.sin_addr.s_addr = INADDR_ANY;
562 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
564 rt.rt_dev = ifr.ifr_name;
566 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
573 connman_error("Adding host route failed (%s)",
579 int connman_inet_del_network_route(int index, const char *host)
583 struct sockaddr_in addr;
586 DBG("index %d host %s", index, host);
588 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
594 memset(&ifr, 0, sizeof(ifr));
595 ifr.ifr_ifindex = index;
597 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
603 DBG("ifname %s", ifr.ifr_name);
605 memset(&rt, 0, sizeof(rt));
606 rt.rt_flags = RTF_UP | RTF_HOST;
608 memset(&addr, 0, sizeof(addr));
609 addr.sin_family = AF_INET;
610 addr.sin_addr.s_addr = inet_addr(host);
611 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
613 rt.rt_dev = ifr.ifr_name;
615 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
622 connman_error("Deleting host route failed (%s)",
628 int connman_inet_del_ipv6_network_route(int index, const char *host,
629 unsigned char prefix_len)
634 DBG("index %d host %s", index, host);
639 memset(&rt, 0, sizeof(rt));
641 rt.rtmsg_dst_len = prefix_len;
643 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
648 rt.rtmsg_flags = RTF_UP | RTF_HOST;
651 rt.rtmsg_ifindex = index;
653 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
659 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
666 connman_error("Del IPv6 host route error (%s)",
672 int connman_inet_del_ipv6_host_route(int index, const char *host)
674 return connman_inet_del_ipv6_network_route(index, host, 128);
677 int connman_inet_add_ipv6_network_route(int index, const char *host,
679 unsigned char prefix_len)
684 DBG("index %d host %s gateway %s", index, host, gateway);
689 memset(&rt, 0, sizeof(rt));
691 rt.rtmsg_dst_len = prefix_len;
693 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
698 rt.rtmsg_flags = RTF_UP | RTF_HOST;
701 rt.rtmsg_flags |= RTF_GATEWAY;
702 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
706 rt.rtmsg_ifindex = index;
708 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
714 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
721 connman_error("Set IPv6 host route error (%s)",
727 int connman_inet_add_ipv6_host_route(int index, const char *host,
730 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
733 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
738 DBG("index %d gateway %s", index, gateway);
743 memset(&rt, 0, sizeof(rt));
745 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
750 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
752 rt.rtmsg_dst_len = 0;
753 rt.rtmsg_ifindex = index;
755 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
761 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
768 connman_error("Clear default IPv6 gateway error (%s)",
774 int connman_inet_set_gateway_interface(int index)
778 struct sockaddr_in addr;
781 DBG("index %d", index);
783 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
789 memset(&ifr, 0, sizeof(ifr));
790 ifr.ifr_ifindex = index;
792 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
798 DBG("ifname %s", ifr.ifr_name);
800 memset(&rt, 0, sizeof(rt));
801 rt.rt_flags = RTF_UP;
803 memset(&addr, 0, sizeof(addr));
804 addr.sin_family = AF_INET;
805 addr.sin_addr.s_addr = INADDR_ANY;
807 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
808 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
809 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
811 rt.rt_dev = ifr.ifr_name;
813 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
820 connman_error("Setting default interface route failed (%s)",
826 int connman_inet_set_ipv6_gateway_interface(int index)
830 struct sockaddr_in6 addr;
831 const struct in6_addr any = IN6ADDR_ANY_INIT;
834 DBG("index %d", index);
836 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
842 memset(&ifr, 0, sizeof(ifr));
843 ifr.ifr_ifindex = index;
845 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
851 DBG("ifname %s", ifr.ifr_name);
853 memset(&rt, 0, sizeof(rt));
854 rt.rt_flags = RTF_UP;
856 memset(&addr, 0, sizeof(addr));
857 addr.sin6_family = AF_INET6;
858 addr.sin6_addr = any;
860 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
861 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
862 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
864 rt.rt_dev = ifr.ifr_name;
866 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
873 connman_error("Setting default interface route failed (%s)",
879 int connman_inet_clear_gateway_address(int index, const char *gateway)
883 struct sockaddr_in addr;
886 DBG("index %d gateway %s", index, gateway);
888 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
894 memset(&ifr, 0, sizeof(ifr));
895 ifr.ifr_ifindex = index;
897 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
903 DBG("ifname %s", ifr.ifr_name);
905 memset(&rt, 0, sizeof(rt));
906 rt.rt_flags = RTF_UP | RTF_GATEWAY;
908 memset(&addr, 0, sizeof(addr));
909 addr.sin_family = AF_INET;
910 addr.sin_addr.s_addr = INADDR_ANY;
911 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
913 memset(&addr, 0, sizeof(addr));
914 addr.sin_family = AF_INET;
915 addr.sin_addr.s_addr = inet_addr(gateway);
916 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
918 memset(&addr, 0, sizeof(addr));
919 addr.sin_family = AF_INET;
920 addr.sin_addr.s_addr = INADDR_ANY;
921 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
923 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
930 connman_error("Removing default gateway route failed (%s)",
936 int connman_inet_clear_gateway_interface(int index)
940 struct sockaddr_in addr;
943 DBG("index %d", index);
945 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
951 memset(&ifr, 0, sizeof(ifr));
952 ifr.ifr_ifindex = index;
954 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
960 DBG("ifname %s", ifr.ifr_name);
962 memset(&rt, 0, sizeof(rt));
963 rt.rt_flags = RTF_UP;
965 memset(&addr, 0, sizeof(addr));
966 addr.sin_family = AF_INET;
967 addr.sin_addr.s_addr = INADDR_ANY;
969 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
970 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
971 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
973 rt.rt_dev = ifr.ifr_name;
975 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
982 connman_error("Removing default interface route failed (%s)",
988 int connman_inet_clear_ipv6_gateway_interface(int index)
992 struct sockaddr_in6 addr;
993 const struct in6_addr any = IN6ADDR_ANY_INIT;
996 DBG("index %d", index);
998 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1004 memset(&ifr, 0, sizeof(ifr));
1005 ifr.ifr_ifindex = index;
1007 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1013 DBG("ifname %s", ifr.ifr_name);
1015 memset(&rt, 0, sizeof(rt));
1016 rt.rt_flags = RTF_UP;
1018 memset(&addr, 0, sizeof(addr));
1019 addr.sin6_family = AF_INET6;
1020 addr.sin6_addr = any;
1022 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1023 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1024 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1026 rt.rt_dev = ifr.ifr_name;
1028 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1035 connman_error("Removing default interface route failed (%s)",
1041 bool connman_inet_compare_subnet(int index, const char *host)
1044 struct in_addr _host_addr;
1045 in_addr_t host_addr, netmask_addr, if_addr;
1046 struct sockaddr_in *netmask, *addr;
1049 DBG("host %s", host);
1054 if (inet_aton(host, &_host_addr) == 0)
1056 host_addr = _host_addr.s_addr;
1058 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1062 memset(&ifr, 0, sizeof(ifr));
1063 ifr.ifr_ifindex = index;
1065 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1070 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1075 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1076 netmask_addr = netmask->sin_addr.s_addr;
1078 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1085 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1086 if_addr = addr->sin_addr.s_addr;
1088 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1091 int connman_inet_remove_from_bridge(int index, const char *bridge)
1099 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1105 memset(&ifr, 0, sizeof(ifr));
1106 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1107 ifr.ifr_ifindex = index;
1109 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1116 connman_error("Remove interface from bridge error %s",
1122 int connman_inet_add_to_bridge(int index, const char *bridge)
1130 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1136 memset(&ifr, 0, sizeof(ifr));
1137 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1138 ifr.ifr_ifindex = index;
1140 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1147 connman_error("Add interface to bridge error %s",
1153 int connman_inet_set_mtu(int index, int mtu)
1158 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1162 memset(&ifr, 0, sizeof(ifr));
1163 ifr.ifr_ifindex = index;
1165 err = ioctl(sk, SIOCGIFNAME, &ifr);
1168 err = ioctl(sk, SIOCSIFMTU, &ifr);
1175 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1185 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1189 index = if_nametoindex(tunnel);
1191 err = connman_inet_set_mtu(index, mtu);
1195 memset(&ifr, 0, sizeof(ifr));
1196 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1197 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1204 if ((ifr.ifr_flags ^ flags) & mask) {
1205 ifr.ifr_flags &= ~mask;
1206 ifr.ifr_flags |= mask & flags;
1207 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1209 connman_error("SIOCSIFFLAGS failed: %s",
1218 int connman_inet_create_tunnel(char **iface)
1223 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1226 connman_error("Failed to open /dev/net/tun: %s",
1231 memset(&ifr, 0, sizeof(ifr));
1232 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1234 for (i = 0; i < 256; i++) {
1235 sprintf(ifr.ifr_name, "tun%d", i);
1237 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1242 connman_error("Failed to find available tun device");
1247 *iface = g_strdup(ifr.ifr_name);
1253 * This callback struct is used when sending router and neighbor
1254 * solicitation and advertisement messages.
1257 GIOChannel *channel;
1259 struct sockaddr_in6 addr;
1265 #define CMSG_BUF_LEN 512
1266 #define IN6ADDR_ALL_NODES_MC_INIT \
1267 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1268 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1269 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1271 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1272 static const struct in6_addr in6addr_all_routers_mc =
1273 IN6ADDR_ALL_ROUTERS_MC_INIT;
1275 static void xs_cleanup(struct xs_cb_data *data)
1277 if (data->channel) {
1278 g_io_channel_shutdown(data->channel, TRUE, NULL);
1279 g_io_channel_unref(data->channel);
1280 data->channel = NULL;
1283 if (data->timeout > 0)
1284 g_source_remove(data->timeout);
1286 if (data->watch_id > 0)
1287 g_source_remove(data->watch_id);
1292 static gboolean rs_timeout_cb(gpointer user_data)
1294 struct xs_cb_data *data = user_data;
1296 DBG("user data %p", user_data);
1301 if (data->callback) {
1302 __connman_inet_rs_cb_t cb = data->callback;
1303 cb(NULL, 0, data->user_data);
1311 static int icmpv6_recv(int fd, gpointer user_data)
1315 unsigned char chdr[CMSG_BUF_LEN];
1316 unsigned char buf[1540];
1317 struct xs_cb_data *data = user_data;
1318 struct nd_router_advert *hdr;
1319 struct sockaddr_in6 saddr;
1321 __connman_inet_rs_cb_t cb = data->callback;
1325 iov.iov_len = sizeof(buf);
1328 mhdr.msg_name = (void *)&saddr;
1329 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1331 mhdr.msg_iov = &iov;
1332 mhdr.msg_iovlen = 1;
1333 mhdr.msg_control = (void *)chdr;
1334 mhdr.msg_controllen = CMSG_BUF_LEN;
1336 len = recvmsg(fd, &mhdr, 0);
1338 cb(NULL, 0, data->user_data);
1343 #if defined TIZEN_EXT
1344 /* Set Received Source Address from router as IPv6 Gateway Address */
1345 char src_addr[INET6_ADDRSTRLEN];
1346 if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
1351 DBG("Received Source Address %s from router", src_addr);
1353 /* icmpv6_recv() function can be called in two scenarios :
1354 * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
1355 * 2. When __connman_inet_ipv6_send_rs() is called from
1356 * __connman_6to4_probe()
1357 * In the second case it is not required to set DHCPv6 Gateway Address
1358 * as DHCPv6 was not started and network structure was not passed as
1359 * user_data. If it is tried to add Source Address as Gateway Address
1360 * then it will lead to crash because of user_data being ip_address
1361 * instead of network structure. So Adding Gateway Address in case 1st
1364 char *address = data->user_data;
1366 unsigned char buffer[sizeof(struct in6_addr)] = {0, };
1367 /* Checking if user_data is an ip_address */
1368 err = inet_pton(AF_INET, address, buffer);
1369 /* Setting Received Source Address from
1370 * router as Gateway Address */
1372 __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
1374 hdr = (struct nd_router_advert *)buf;
1375 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1376 sizeof(struct nd_router_advert));
1377 if (hdr->nd_ra_code != 0)
1380 cb(hdr, len, data->user_data);
1386 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1392 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1395 fd = g_io_channel_unix_get_fd(chan);
1396 ret = icmpv6_recv(fd, data);
1403 /* Adapted from RFC 1071 "C" Implementation Example */
1404 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1405 const void *extra_data, socklen_t extra_datalen)
1407 register unsigned long sum = 0;
1412 /* caller must make sure datalen is even */
1414 addr = (uint16_t *)phdr;
1415 for (i = 0; i < 20; i++)
1419 addr = (uint16_t *)data;
1427 count = extra_datalen;
1428 addr = (uint16_t *)extra_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,
1443 const struct in6_addr *source,
1444 unsigned char *buf, size_t len, uint16_t lifetime)
1447 struct in6_addr src;
1448 struct in6_addr dst;
1450 uint8_t reserved[3];
1457 struct icmp6_hdr icmp;
1458 struct nd_neighbor_solicit ns;
1459 struct nd_router_solicit rs;
1460 struct nd_router_advert ra;
1465 struct cmsghdr *cmsg;
1466 struct in6_pktinfo *pinfo;
1467 struct sockaddr_in6 dst, src;
1468 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1469 struct iovec iov[2];
1470 int fd, datalen, ret, iovlen = 1;
1471 #if defined TIZEN_EXT
1477 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1481 memset(&frame, 0, sizeof(frame));
1482 memset(&dst, 0, sizeof(dst));
1484 if (type == ND_ROUTER_SOLICIT)
1485 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1486 else if (type == ND_ROUTER_ADVERT) {
1487 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1488 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1489 } else if (type == ND_NEIGHBOR_SOLICIT) {
1490 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1491 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1497 dst.sin6_addr = *dest;
1500 src.sin6_addr = *source;
1502 src.sin6_addr = in6addr_any;
1504 /* Fill in the IPv6 header */
1505 frame.ip.ip6_vfc = 0x60;
1506 frame.ip.ip6_plen = htons(datalen + len);
1507 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1508 frame.ip.ip6_hlim = 255;
1509 frame.ip.ip6_dst = dst.sin6_addr;
1510 frame.ip.ip6_src = src.sin6_addr;
1511 /* all other fields are already set to zero */
1513 /* Prepare pseudo header for csum */
1514 memset(&phdr, 0, sizeof(phdr));
1515 phdr.dst = dst.sin6_addr;
1516 phdr.src = src.sin6_addr;
1517 phdr.plen = htonl(datalen + len);
1518 phdr.nxt = IPPROTO_ICMPV6;
1520 /* Fill in remaining ICMP header fields */
1521 frame.i.icmp.icmp6_type = type;
1522 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1524 iov[0].iov_base = &frame;
1525 iov[0].iov_len = sizeof(frame.ip) + datalen;
1528 iov[1].iov_base = buf;
1529 iov[1].iov_len = len;
1533 dst.sin6_family = AF_INET6;
1534 msgh.msg_name = &dst;
1535 msgh.msg_namelen = sizeof(dst);
1537 msgh.msg_iovlen = iovlen;
1540 memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1541 cmsg = (struct cmsghdr *)cbuf;
1542 pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1543 pinfo->ipi6_ifindex = oif;
1545 cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1546 cmsg->cmsg_level = IPPROTO_IPV6;
1547 cmsg->cmsg_type = IPV6_PKTINFO;
1548 msgh.msg_control = cmsg;
1549 msgh.msg_controllen = cmsg->cmsg_len;
1551 ret = sendmsg(fd, &msgh, 0);
1552 #if defined TIZEN_EXT
1553 DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
1560 static inline void ipv6_addr_set(struct in6_addr *addr,
1561 uint32_t w1, uint32_t w2,
1562 uint32_t w3, uint32_t w4)
1564 addr->s6_addr32[0] = w1;
1565 addr->s6_addr32[1] = w2;
1566 addr->s6_addr32[2] = w3;
1567 addr->s6_addr32[3] = w4;
1570 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1571 struct in6_addr *solicited)
1573 ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1574 htonl(0xFF000000) | addr->s6_addr32[3]);
1577 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1580 unsigned int val = 0;
1581 struct ipv6_mreq mreq;
1584 memset(&mreq, 0, sizeof(mreq));
1585 mreq.ipv6mr_interface = ifindex;
1586 mreq.ipv6mr_multiaddr = *mc_addr;
1588 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1592 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1597 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1600 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1607 int __connman_inet_ipv6_send_rs(int index, int timeout,
1608 __connman_inet_rs_cb_t callback, void *user_data)
1610 struct xs_cb_data *data;
1611 struct icmp6_filter filter;
1612 struct in6_addr solicit;
1613 struct in6_addr dst = in6addr_all_routers_mc;
1619 data = g_try_malloc0(sizeof(struct xs_cb_data));
1623 data->callback = callback;
1624 data->user_data = user_data;
1625 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1627 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, NULL, NULL, 0, 0);
1658 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1659 struct in6_addr *advert)
1661 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1662 htonl(0xFF000000) | addr->s6_addr32[3]);
1665 #define MSG_SIZE_SEND 1452
1667 static int inc_len(int len, int inc)
1669 if (len > MSG_SIZE_SEND)
1676 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1677 GSList *prefixes, int router_lifetime)
1680 struct in6_addr src, *source;
1681 struct in6_addr dst = in6addr_all_nodes_mc;
1682 GDHCPIAPrefix *prefix;
1683 unsigned char buf[MSG_SIZE_SEND];
1684 char addr_str[INET6_ADDRSTRLEN];
1691 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1696 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1701 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1702 prefixes, inet_ntop(AF_INET6, source, addr_str,
1706 memset(buf, 0, MSG_SIZE_SEND);
1709 for (list = prefixes; list; list = list->next) {
1710 struct nd_opt_prefix_info *pinfo;
1712 prefix = list->data;
1713 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1715 len = inc_len(len, sizeof(*pinfo));
1721 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1722 pinfo->nd_opt_pi_len = 4;
1723 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1724 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1725 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1726 if (router_lifetime > 0) {
1727 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1728 pinfo->nd_opt_pi_preferred_time =
1729 htonl(prefix->preferred);
1731 pinfo->nd_opt_pi_reserved2 = 0;
1733 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1734 sizeof(struct in6_addr));
1736 DBG("[%d] index %d prefix %s/%d", count, index,
1737 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1738 INET6_ADDRSTRLEN), prefix->prefixlen);
1744 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1745 buf, len, router_lifetime);
1747 DBG("cannot send RA %d/%s", err, strerror(-err));
1755 void __connman_inet_ipv6_stop_recv_rs(void *context)
1760 xs_cleanup(context);
1763 static int icmpv6_rs_recv(int fd, gpointer user_data)
1767 unsigned char chdr[CMSG_BUF_LEN];
1768 unsigned char buf[1540];
1769 struct xs_cb_data *data = user_data;
1770 struct nd_router_solicit *hdr;
1771 struct sockaddr_in6 saddr;
1773 __connman_inet_recv_rs_cb_t cb = data->callback;
1777 iov.iov_len = sizeof(buf);
1780 mhdr.msg_name = (void *)&saddr;
1781 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1783 mhdr.msg_iov = &iov;
1784 mhdr.msg_iovlen = 1;
1785 mhdr.msg_control = (void *)chdr;
1786 mhdr.msg_controllen = CMSG_BUF_LEN;
1788 len = recvmsg(fd, &mhdr, 0);
1790 cb(NULL, 0, data->user_data);
1794 hdr = (struct nd_router_solicit *)buf;
1795 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1796 sizeof(struct nd_router_solicit));
1797 if (hdr->nd_rs_code != 0)
1800 cb(hdr, len, data->user_data);
1804 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1811 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1814 fd = g_io_channel_unix_get_fd(chan);
1815 ret = icmpv6_rs_recv(fd, data);
1822 int __connman_inet_ipv6_start_recv_rs(int index,
1823 __connman_inet_recv_rs_cb_t callback,
1827 struct xs_cb_data *data;
1828 struct icmp6_filter filter;
1829 char addr_str[INET6_ADDRSTRLEN];
1832 data = g_try_malloc0(sizeof(struct xs_cb_data));
1836 data->callback = callback;
1837 data->user_data = user_data;
1839 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1847 ICMP6_FILTER_SETBLOCKALL(&filter);
1848 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1850 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1851 sizeof(struct icmp6_filter));
1853 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1855 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1856 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1857 err, strerror(-err));
1859 data->channel = g_io_channel_unix_new(sk);
1860 g_io_channel_set_close_on_unref(data->channel, TRUE);
1862 g_io_channel_set_encoding(data->channel, NULL, NULL);
1863 g_io_channel_set_buffered(data->channel, FALSE);
1865 data->watch_id = g_io_add_watch(data->channel,
1866 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1867 icmpv6_rs_event, data);
1874 static gboolean ns_timeout_cb(gpointer user_data)
1876 struct xs_cb_data *data = user_data;
1878 DBG("user data %p", user_data);
1883 if (data->callback) {
1884 __connman_inet_ns_cb_t cb = data->callback;
1885 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1893 static int icmpv6_nd_recv(int fd, gpointer user_data)
1897 unsigned char chdr[CMSG_BUF_LEN];
1898 unsigned char buf[1540];
1899 struct xs_cb_data *data = user_data;
1900 struct nd_neighbor_advert *hdr;
1901 struct sockaddr_in6 saddr;
1903 __connman_inet_ns_cb_t cb = data->callback;
1907 iov.iov_len = sizeof(buf);
1910 mhdr.msg_name = (void *)&saddr;
1911 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1913 mhdr.msg_iov = &iov;
1914 mhdr.msg_iovlen = 1;
1915 mhdr.msg_control = (void *)chdr;
1916 mhdr.msg_controllen = CMSG_BUF_LEN;
1918 len = recvmsg(fd, &mhdr, 0);
1920 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1925 hdr = (struct nd_neighbor_advert *)buf;
1926 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1927 sizeof(struct nd_neighbor_advert));
1928 if (hdr->nd_na_code != 0)
1932 * We can receive any neighbor advertisement so we need to check if the
1933 * packet was meant for us and ignore the packet otherwise.
1935 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1936 sizeof(struct in6_addr)))
1939 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1945 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
1952 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1955 fd = g_io_channel_unix_get_fd(chan);
1956 ret = icmpv6_nd_recv(fd, data);
1963 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
1964 struct in6_addr *addr,
1965 __connman_inet_ns_cb_t callback,
1968 struct xs_cb_data *data;
1969 struct icmp6_filter filter;
1970 struct in6_addr solicit;
1971 int sk, err, val = 1;
1973 if (timeout_ms <= 0)
1976 data = g_try_malloc0(sizeof(struct xs_cb_data));
1980 data->callback = callback;
1981 data->user_data = user_data;
1982 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
1987 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
1989 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1995 ICMP6_FILTER_SETBLOCKALL(&filter);
1996 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
1998 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1999 sizeof(struct icmp6_filter));
2001 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2002 &val, sizeof(val)) < 0) {
2004 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2010 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2011 &val, sizeof(val)) < 0) {
2013 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2020 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2022 ipv6_addr_solict_mult(addr, &solicit);
2023 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2024 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2026 data->channel = g_io_channel_unix_new(sk);
2027 g_io_channel_set_close_on_unref(data->channel, TRUE);
2029 g_io_channel_set_encoding(data->channel, NULL, NULL);
2030 g_io_channel_set_buffered(data->channel, FALSE);
2032 data->watch_id = g_io_add_watch(data->channel,
2033 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2034 icmpv6_nd_event, data);
2036 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2037 (unsigned char *)addr, 0, 0);
2039 DBG("Cannot send NS %d/%s", err, strerror(-err));
2046 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2047 unsigned int length)
2049 GSList *prefixes = NULL;
2053 if (length <= sizeof(struct nd_router_advert))
2056 len = length - sizeof(struct nd_router_advert);
2057 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2060 struct nd_opt_prefix_info *pinfo;
2061 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2068 optlen = pos[1] << 3;
2069 if (optlen == 0 || optlen > len)
2073 case ND_OPT_PREFIX_INFORMATION:
2074 pinfo = (struct nd_opt_prefix_info *)pos;
2075 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2076 prefix_str, INET6_ADDRSTRLEN);
2080 str = g_strdup_printf("%s/%d", prefix,
2081 pinfo->nd_opt_pi_prefix_len);
2082 prefixes = g_slist_prepend(prefixes, str);
2084 DBG("prefix %s", str);
2096 static int get_dest_addr(int family, int index, char *buf, int len)
2102 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2106 memset(&ifr, 0, sizeof(ifr));
2107 ifr.ifr_ifindex = index;
2109 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2110 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2115 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2116 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2121 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2127 DBG("index %d %s", index, ifr.ifr_name);
2129 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2130 connman_error("Get destination address failed (%s)",
2140 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2143 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2150 if (!inet_ntop(family, addr, buf, len)) {
2151 DBG("error %d/%s", errno, strerror(errno));
2158 int connman_inet_get_dest_addr(int index, char **dest)
2160 char addr[INET_ADDRSTRLEN];
2163 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2167 *dest = g_strdup(addr);
2169 DBG("destination %s", *dest);
2174 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2176 char addr[INET6_ADDRSTRLEN];
2179 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2183 *dest = g_strdup(addr);
2185 DBG("destination %s", *dest);
2190 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2193 int rcvbuf = 1024 * 4;
2195 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2197 connman_error("Can not open netlink socket: %s",
2202 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2203 sizeof(sndbuf)) < 0) {
2204 connman_error("SO_SNDBUF: %s", strerror(errno));
2208 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2209 sizeof(rcvbuf)) < 0) {
2210 connman_error("SO_RCVBUF: %s", strerror(errno));
2214 memset(&rth->local, 0, sizeof(rth->local));
2215 rth->local.nl_family = AF_NETLINK;
2216 rth->local.nl_groups = 0;
2218 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2219 sizeof(rth->local)) < 0) {
2220 connman_error("Can not bind netlink socket: %s",
2225 rth->seq = time(NULL);
2227 DBG("fd %d", rth->fd);
2232 struct inet_rtnl_cb_data {
2233 GIOChannel *channel;
2234 __connman_inet_rtnl_cb_t callback;
2237 struct __connman_inet_rtnl_handle *rtnl;
2241 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2243 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2245 if (data->channel) {
2246 g_io_channel_shutdown(data->channel, TRUE, NULL);
2247 g_io_channel_unref(data->channel);
2248 data->channel = NULL;
2251 DBG("data %p", data);
2253 if (data->rtnl_timeout > 0)
2254 g_source_remove(data->rtnl_timeout);
2256 if (data->watch_id > 0)
2257 g_source_remove(data->watch_id);
2260 __connman_inet_rtnl_close(rth);
2267 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2269 struct inet_rtnl_cb_data *data = user_data;
2271 DBG("user data %p", user_data);
2277 data->callback(NULL, data->user_data);
2279 data->rtnl_timeout = 0;
2280 inet_rtnl_cleanup(data);
2284 static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
2286 struct inet_rtnl_cb_data *rtnl_data = user_data;
2287 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2288 struct nlmsghdr *h = NULL;
2289 struct sockaddr_nl nladdr;
2290 socklen_t addr_len = sizeof(nladdr);
2291 unsigned char buf[4096];
2296 memset(buf, 0, sizeof(buf));
2297 memset(&nladdr, 0, sizeof(nladdr));
2299 fd = g_io_channel_unix_get_fd(chan);
2301 status = recvfrom(fd, buf, sizeof(buf), 0,
2302 (struct sockaddr *) &nladdr, &addr_len);
2304 if (errno == EINTR || errno == EAGAIN)
2313 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2314 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2321 struct nlmsgerr *err;
2325 if (!NLMSG_OK(h, len))
2328 if (h->nlmsg_seq != rth->seq) {
2330 DBG("skip %d/%d len %d", rth->seq,
2331 h->nlmsg_seq, h->nlmsg_len);
2333 len -= h->nlmsg_len;
2334 ptr += h->nlmsg_len;
2338 switch (h->nlmsg_type) {
2344 err = (struct nlmsgerr *)NLMSG_DATA(h);
2345 connman_error("RTNETLINK answers %s (%d)",
2346 strerror(-err->error), -err->error);
2353 if (h->nlmsg_seq == rth->seq) {
2354 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2356 rtnl_data->callback(h, rtnl_data->user_data);
2358 inet_rtnl_cleanup(rtnl_data);
2364 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2371 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2374 ret = inet_rtnl_recv(chan, user_data);
2381 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2382 struct nlmsghdr *n, int timeout,
2383 __connman_inet_rtnl_cb_t callback, void *user_data)
2385 struct sockaddr_nl nladdr;
2386 struct inet_rtnl_cb_data *data;
2390 memset(&nladdr, 0, sizeof(nladdr));
2391 nladdr.nl_family = AF_NETLINK;
2393 n->nlmsg_seq = seq = ++rtnl->seq;
2396 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2400 data->callback = callback;
2401 data->user_data = user_data;
2403 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2404 inet_rtnl_timeout_cb, data);
2406 data->channel = g_io_channel_unix_new(rtnl->fd);
2407 g_io_channel_set_close_on_unref(data->channel, TRUE);
2409 g_io_channel_set_encoding(data->channel, NULL, NULL);
2410 g_io_channel_set_buffered(data->channel, FALSE);
2412 data->watch_id = g_io_add_watch(data->channel,
2413 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2414 inet_rtnl_event, data);
2416 n->nlmsg_flags |= NLM_F_ACK;
2418 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2419 (struct sockaddr *) &nladdr, sizeof(nladdr));
2420 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2422 connman_error("Can not talk to rtnetlink err %d %s",
2423 -errno, strerror(errno));
2427 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2428 connman_error("Sent %d bytes, msg truncated", err);
2435 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2437 DBG("handle %p", rth);
2445 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2448 int len = RTA_LENGTH(4);
2451 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2452 DBG("Error! max allowed bound %zd exceeded", maxlen);
2455 rta = NLMSG_TAIL(n);
2456 rta->rta_type = type;
2458 memcpy(RTA_DATA(rta), &data, 4);
2459 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2464 static int parse_rtattr(struct rtattr *tb[], int max,
2465 struct rtattr *rta, int len)
2467 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2468 while (RTA_OK(rta, len)) {
2469 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2470 tb[rta->rta_type] = rta;
2471 rta = RTA_NEXT(rta, len);
2474 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2479 struct get_route_cb_data {
2480 connman_inet_addr_cb_t callback;
2484 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2486 struct get_route_cb_data *data = user_data;
2487 struct rtattr *tb[RTA_MAX+1];
2488 struct rtmsg *r = NLMSG_DATA(answer);
2489 int len, index = -1;
2491 const char *addr = NULL;
2493 DBG("answer %p data %p", answer, user_data);
2498 len = answer->nlmsg_len;
2500 if (answer->nlmsg_type != RTM_NEWROUTE &&
2501 answer->nlmsg_type != RTM_DELROUTE) {
2502 connman_error("Not a route: %08x %08x %08x",
2503 answer->nlmsg_len, answer->nlmsg_type,
2504 answer->nlmsg_flags);
2508 len -= NLMSG_LENGTH(sizeof(*r));
2510 connman_error("BUG: wrong nlmsg len %d", len);
2514 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2517 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2519 if (tb[RTA_GATEWAY])
2520 addr = inet_ntop(r->rtm_family,
2521 RTA_DATA(tb[RTA_GATEWAY]),
2522 abuf, sizeof(abuf));
2524 DBG("addr %s index %d user %p", addr, index, data->user_data);
2527 if (data && data->callback)
2528 data->callback(addr, index, data->user_data);
2536 * Return the interface index that contains route to host.
2538 int __connman_inet_get_route(const char *dest_address,
2539 connman_inet_addr_cb_t callback, void *user_data)
2541 struct get_route_cb_data *data;
2542 struct addrinfo hints, *rp;
2543 struct __connman_inet_rtnl_handle *rth;
2546 DBG("dest %s", dest_address);
2551 memset(&hints, 0, sizeof(hints));
2552 hints.ai_family = AF_UNSPEC;
2553 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2555 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2559 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2565 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2566 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2567 rth->req.n.nlmsg_type = RTM_GETROUTE;
2568 rth->req.u.r.rt.rtm_family = rp->ai_family;
2569 rth->req.u.r.rt.rtm_table = 0;
2570 rth->req.u.r.rt.rtm_protocol = 0;
2571 rth->req.u.r.rt.rtm_scope = 0;
2572 rth->req.u.r.rt.rtm_type = 0;
2573 rth->req.u.r.rt.rtm_src_len = 0;
2574 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2575 rth->req.u.r.rt.rtm_tos = 0;
2577 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2578 &rp->ai_addr, rp->ai_addrlen);
2582 err = __connman_inet_rtnl_open(rth);
2586 data = g_try_malloc(sizeof(struct get_route_cb_data));
2592 data->callback = callback;
2593 data->user_data = user_data;
2595 #define GET_ROUTE_TIMEOUT 2
2596 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2597 get_route_cb, data);
2606 __connman_inet_rtnl_close(rth);
2613 int connman_inet_check_ipaddress(const char *host)
2615 struct addrinfo hints;
2616 struct addrinfo *addr;
2619 memset(&hints, 0, sizeof(struct addrinfo));
2620 hints.ai_flags = AI_NUMERICHOST;
2623 result = getaddrinfo(host, NULL, &hints, &addr);
2625 result = addr->ai_family;
2631 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2632 bool connman_inet_check_hostname(const char *ptr, size_t len)
2637 * Not empty or complete length not over 255 characters.
2639 if ((len == 0) || (len > 256))
2643 * Consists of [[:alnum:]-]+ labels separated by [.]
2644 * a [_] is against RFC but seems to be "widely used"
2646 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2648 if ((*p == '-') || (*p == '_')) {
2650 * Not allowed at begin or end of a label.
2652 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2655 } else if (*p == '.') {
2657 * Each label has to be 1-63 characters;
2658 * we allow [.] at the end ('foo.bar.')
2662 if ((d <= 0) || (d >= 64))
2665 ptr = p + 1; /* Jump to the next label */
2667 } else if (isalnum((unsigned char)*p) == 0) {
2669 * Also numbers at the begin are fine
2678 char **__connman_inet_get_running_interfaces(void)
2682 struct ifreq *ifr = NULL;
2683 int sk, i, numif, count = 0;
2685 memset(&ifc, 0, sizeof(ifc));
2687 sk = socket(AF_INET, SOCK_DGRAM, 0);
2691 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2695 * Allocate some extra bytes just in case there will
2696 * be new interfaces added between two SIOCGIFCONF
2699 ifr = g_try_malloc0(ifc.ifc_len * 2);
2705 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2708 numif = ifc.ifc_len / sizeof(struct ifreq);
2710 result = g_try_malloc0((numif + 1) * sizeof(char *));
2716 for (i = 0; i < numif; i++) {
2717 struct ifreq *r = &ifr[i];
2718 struct in6_addr *addr6;
2722 * Note that we do not return loopback interfaces here as they
2723 * are not needed for our purposes.
2725 switch (r->ifr_addr.sa_family) {
2727 addr4 = ntohl(((struct sockaddr_in *)
2728 &r->ifr_addr)->sin_addr.s_addr);
2729 if (((addr4 & 0xff000000) >> 24) == 127)
2733 addr6 = &((struct sockaddr_in6 *)
2734 &r->ifr_addr)->sin6_addr;
2735 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2740 result[count++] = g_strdup(r->ifr_name);
2747 char **prev_result = result;
2748 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2750 g_free(prev_result);
2763 bool connman_inet_is_ipv6_supported()
2767 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2775 int __connman_inet_get_interface_address(int index, int family, void *address)
2777 struct ifaddrs *ifaddr, *ifa;
2779 char name[IF_NAMESIZE];
2781 if (!if_indextoname(index, name))
2784 DBG("index %d interface %s", index, name);
2786 if (getifaddrs(&ifaddr) < 0) {
2788 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2792 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2796 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2797 ifa->ifa_addr->sa_family == family) {
2798 if (family == AF_INET) {
2799 struct sockaddr_in *in4 = (struct sockaddr_in *)
2801 if (in4->sin_addr.s_addr == INADDR_ANY)
2803 memcpy(address, &in4->sin_addr,
2804 sizeof(struct in_addr));
2805 } else if (family == AF_INET6) {
2806 struct sockaddr_in6 *in6 =
2807 (struct sockaddr_in6 *)ifa->ifa_addr;
2808 if (memcmp(&in6->sin6_addr, &in6addr_any,
2809 sizeof(struct in6_addr)) == 0)
2811 memcpy(address, &in6->sin6_addr,
2812 sizeof(struct in6_addr));
2825 freeifaddrs(ifaddr);
2829 static int iprule_modify(int cmd, int family, uint32_t table_id,
2832 struct __connman_inet_rtnl_handle rth;
2835 memset(&rth, 0, sizeof(rth));
2837 rth.req.n.nlmsg_type = cmd;
2838 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2839 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2840 rth.req.u.r.rt.rtm_family = family;
2841 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2842 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2843 rth.req.u.r.rt.rtm_table = table_id;
2844 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2845 rth.req.u.r.rt.rtm_flags = 0;
2847 if (cmd == RTM_NEWRULE) {
2848 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2849 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2852 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2853 FRA_FWMARK, fwmark);
2855 if (table_id < 256) {
2856 rth.req.u.r.rt.rtm_table = table_id;
2858 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2859 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2860 FRA_TABLE, table_id);
2863 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2864 rth.req.u.r.rt.rtm_family = AF_INET;
2866 ret = __connman_inet_rtnl_open(&rth);
2870 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2873 __connman_inet_rtnl_close(&rth);
2878 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2880 /* ip rule add fwmark 9876 table 1234 */
2882 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2885 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2887 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2890 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2891 const char *gateway)
2893 struct __connman_inet_rtnl_handle rth;
2894 unsigned char buf[sizeof(struct in6_addr)];
2896 int family = connman_inet_check_ipaddress(gateway);
2909 ret = inet_pton(family, gateway, buf);
2913 memset(&rth, 0, sizeof(rth));
2915 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2916 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
2917 rth.req.n.nlmsg_type = cmd;
2918 rth.req.u.r.rt.rtm_family = family;
2919 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
2920 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
2921 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2922 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2923 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2925 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
2927 if (table_id < 256) {
2928 rth.req.u.r.rt.rtm_table = table_id;
2930 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2931 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2932 RTA_TABLE, table_id);
2935 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2938 ret = __connman_inet_rtnl_open(&rth);
2942 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2945 __connman_inet_rtnl_close(&rth);
2950 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
2951 const char *gateway)
2953 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
2955 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
2958 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
2959 const char *gateway)
2961 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
2963 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
2966 int __connman_inet_get_interface_ll_address(int index, int family,
2969 struct ifaddrs *ifaddr, *ifa;
2971 char name[IF_NAMESIZE];
2973 if (!if_indextoname(index, name))
2976 DBG("index %d interface %s", index, name);
2978 if (getifaddrs(&ifaddr) < 0) {
2980 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2984 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2988 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2989 ifa->ifa_addr->sa_family == family) {
2990 if (family == AF_INET) {
2991 struct sockaddr_in *in4 = (struct sockaddr_in *)
2993 if (in4->sin_addr.s_addr == INADDR_ANY)
2995 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
2996 ((in_addr_t) 0xa9fe0000))
2998 memcpy(address, &in4->sin_addr,
2999 sizeof(struct in_addr));
3000 } else if (family == AF_INET6) {
3001 struct sockaddr_in6 *in6 =
3002 (struct sockaddr_in6 *)ifa->ifa_addr;
3003 if (memcmp(&in6->sin6_addr, &in6addr_any,
3004 sizeof(struct in6_addr)) == 0)
3006 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
3009 memcpy(address, &in6->sin6_addr,
3010 sizeof(struct in6_addr));
3022 freeifaddrs(ifaddr);
3026 int __connman_inet_get_address_netmask(int ifindex,
3027 struct sockaddr_in *address,
3028 struct sockaddr_in *netmask)
3030 int sk, ret = -EINVAL;
3033 DBG("index %d", ifindex);
3035 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3039 memset(&ifr, 0, sizeof(ifr));
3040 ifr.ifr_ifindex = ifindex;
3042 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3045 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3048 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3049 sizeof(struct sockaddr_in));
3051 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3054 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3055 sizeof(struct sockaddr_in));