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 short int connman_inet_ifflags(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) {
273 int connman_inet_ifup(int index)
278 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
282 memset(&ifr, 0, sizeof(ifr));
283 ifr.ifr_ifindex = index;
285 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
290 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
295 if (ifr.ifr_flags & IFF_UP) {
300 ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
302 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
315 int connman_inet_ifdown(int index)
317 struct ifreq ifr, addr_ifr;
318 struct sockaddr_in *addr;
321 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
325 memset(&ifr, 0, sizeof(ifr));
326 ifr.ifr_ifindex = index;
328 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
333 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
338 memset(&addr_ifr, 0, sizeof(addr_ifr));
339 memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
340 addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
341 addr->sin_family = AF_INET;
342 if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
343 connman_warn("Could not clear IPv4 address index %d", index);
345 if (!(ifr.ifr_flags & IFF_UP)) {
350 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
352 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
363 bool connman_inet_is_cfg80211(int index)
366 char phy80211_path[PATH_MAX];
371 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
375 memset(&ifr, 0, sizeof(ifr));
376 ifr.ifr_ifindex = index;
378 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
381 snprintf(phy80211_path, PATH_MAX,
382 "/sys/class/net/%s/phy80211", ifr.ifr_name);
384 if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
394 struct in6_addr ifr6_addr;
395 __u32 ifr6_prefixlen;
396 unsigned int ifr6_ifindex;
399 int connman_inet_set_ipv6_address(int index,
400 struct connman_ipaddress *ipaddress)
403 unsigned char prefix_len;
406 if (!ipaddress->local)
409 prefix_len = ipaddress->prefixlen;
410 address = ipaddress->local;
412 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
414 err = __connman_inet_modify_address(RTM_NEWADDR,
415 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
416 address, NULL, prefix_len, NULL);
418 connman_error("%s: %s", __func__, strerror(-err));
425 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
428 unsigned char prefix_len;
429 const char *address, *broadcast, *peer;
431 if (!ipaddress->local)
434 prefix_len = ipaddress->prefixlen;
435 address = ipaddress->local;
436 broadcast = ipaddress->broadcast;
437 peer = ipaddress->peer;
439 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
441 err = __connman_inet_modify_address(RTM_NEWADDR,
442 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
443 address, peer, prefix_len, broadcast);
445 connman_error("%s: %s", __func__, strerror(-err));
452 int connman_inet_clear_ipv6_address(int index, const char *address,
457 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
462 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
463 address, NULL, prefix_len, NULL);
465 connman_error("%s: %s", __func__, strerror(-err));
472 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
475 unsigned char prefix_len;
476 const char *address, *broadcast, *peer;
478 prefix_len = ipaddress->prefixlen;
479 address = ipaddress->local;
480 broadcast = ipaddress->broadcast;
481 peer = ipaddress->peer;
483 DBG("index %d address %s prefix_len %d", index, address, prefix_len);
488 err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
489 address, peer, prefix_len, broadcast);
491 connman_error("%s: %s", __func__, strerror(-err));
498 int connman_inet_add_host_route(int index, const char *host,
501 return connman_inet_add_network_route(index, host, gateway, NULL);
504 int connman_inet_del_host_route(int index, const char *host)
506 return connman_inet_del_network_route(index, host);
509 int connman_inet_add_network_route(int index, const char *host,
515 struct sockaddr_in addr;
518 DBG("index %d host %s gateway %s netmask %s", index,
519 host, gateway, netmask);
521 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
527 memset(&ifr, 0, sizeof(ifr));
528 ifr.ifr_ifindex = index;
530 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
536 DBG("ifname %s", ifr.ifr_name);
538 memset(&rt, 0, sizeof(rt));
539 rt.rt_flags = RTF_UP;
541 rt.rt_flags |= RTF_GATEWAY;
543 rt.rt_flags |= RTF_HOST;
545 memset(&addr, 0, sizeof(addr));
546 addr.sin_family = AF_INET;
547 addr.sin_addr.s_addr = inet_addr(host);
548 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
550 memset(&addr, 0, sizeof(addr));
551 addr.sin_family = AF_INET;
553 addr.sin_addr.s_addr = inet_addr(gateway);
555 addr.sin_addr.s_addr = INADDR_ANY;
556 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
558 memset(&addr, 0, sizeof(addr));
559 addr.sin_family = AF_INET;
560 addr.sin_addr.s_addr = INADDR_ANY;
562 addr.sin_addr.s_addr = inet_addr(netmask);
564 addr.sin_addr.s_addr = INADDR_ANY;
565 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
567 rt.rt_dev = ifr.ifr_name;
569 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
576 connman_error("Adding host route failed (%s)",
582 int connman_inet_del_network_route(int index, const char *host)
586 struct sockaddr_in addr;
589 DBG("index %d host %s", index, host);
591 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
597 memset(&ifr, 0, sizeof(ifr));
598 ifr.ifr_ifindex = index;
600 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
606 DBG("ifname %s", ifr.ifr_name);
608 memset(&rt, 0, sizeof(rt));
609 rt.rt_flags = RTF_UP | RTF_HOST;
611 memset(&addr, 0, sizeof(addr));
612 addr.sin_family = AF_INET;
613 addr.sin_addr.s_addr = inet_addr(host);
614 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
616 rt.rt_dev = ifr.ifr_name;
618 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
625 connman_error("Deleting host route failed (%s)",
631 int connman_inet_del_ipv6_network_route(int index, const char *host,
632 unsigned char prefix_len)
637 DBG("index %d host %s", index, host);
642 memset(&rt, 0, sizeof(rt));
644 rt.rtmsg_dst_len = prefix_len;
646 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
651 rt.rtmsg_flags = RTF_UP | RTF_HOST;
654 rt.rtmsg_ifindex = index;
656 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
662 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
669 connman_error("Del IPv6 host route error (%s)",
675 int connman_inet_del_ipv6_host_route(int index, const char *host)
677 return connman_inet_del_ipv6_network_route(index, host, 128);
680 int connman_inet_add_ipv6_network_route(int index, const char *host,
682 unsigned char prefix_len)
687 DBG("index %d host %s gateway %s", index, host, gateway);
692 memset(&rt, 0, sizeof(rt));
694 rt.rtmsg_dst_len = prefix_len;
696 if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
701 rt.rtmsg_flags = RTF_UP | RTF_HOST;
704 rt.rtmsg_flags |= RTF_GATEWAY;
705 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
709 rt.rtmsg_ifindex = index;
711 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
717 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
724 connman_error("Set IPv6 host route error (%s)",
730 int connman_inet_add_ipv6_host_route(int index, const char *host,
733 return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
736 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
741 DBG("index %d gateway %s", index, gateway);
746 memset(&rt, 0, sizeof(rt));
748 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
753 rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
755 rt.rtmsg_dst_len = 0;
756 rt.rtmsg_ifindex = index;
758 sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
764 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
771 connman_error("Clear default IPv6 gateway error (%s)",
777 int connman_inet_set_gateway_interface(int index)
781 struct sockaddr_in addr;
784 DBG("index %d", index);
786 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
792 memset(&ifr, 0, sizeof(ifr));
793 ifr.ifr_ifindex = index;
795 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
801 DBG("ifname %s", ifr.ifr_name);
803 memset(&rt, 0, sizeof(rt));
804 rt.rt_flags = RTF_UP;
806 memset(&addr, 0, sizeof(addr));
807 addr.sin_family = AF_INET;
808 addr.sin_addr.s_addr = INADDR_ANY;
810 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
811 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
812 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
814 rt.rt_dev = ifr.ifr_name;
816 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
823 connman_error("Setting default interface route failed (%s)",
829 int connman_inet_set_ipv6_gateway_interface(int index)
833 struct sockaddr_in6 addr;
834 const struct in6_addr any = IN6ADDR_ANY_INIT;
837 DBG("index %d", index);
839 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
845 memset(&ifr, 0, sizeof(ifr));
846 ifr.ifr_ifindex = index;
848 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
854 DBG("ifname %s", ifr.ifr_name);
856 memset(&rt, 0, sizeof(rt));
857 rt.rt_flags = RTF_UP;
859 memset(&addr, 0, sizeof(addr));
860 addr.sin6_family = AF_INET6;
861 addr.sin6_addr = any;
863 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
864 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
865 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
867 rt.rt_dev = ifr.ifr_name;
869 if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
876 connman_error("Setting default interface route failed (%s)",
882 int connman_inet_clear_gateway_address(int index, const char *gateway)
886 struct sockaddr_in addr;
889 DBG("index %d gateway %s", index, gateway);
891 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
897 memset(&ifr, 0, sizeof(ifr));
898 ifr.ifr_ifindex = index;
900 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
906 DBG("ifname %s", ifr.ifr_name);
908 memset(&rt, 0, sizeof(rt));
909 rt.rt_flags = RTF_UP | RTF_GATEWAY;
911 memset(&addr, 0, sizeof(addr));
912 addr.sin_family = AF_INET;
913 addr.sin_addr.s_addr = INADDR_ANY;
914 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
916 memset(&addr, 0, sizeof(addr));
917 addr.sin_family = AF_INET;
918 addr.sin_addr.s_addr = inet_addr(gateway);
919 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
921 memset(&addr, 0, sizeof(addr));
922 addr.sin_family = AF_INET;
923 addr.sin_addr.s_addr = INADDR_ANY;
924 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
926 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
933 connman_error("Removing default gateway route failed (%s)",
939 int connman_inet_clear_gateway_interface(int index)
943 struct sockaddr_in addr;
946 DBG("index %d", index);
948 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
954 memset(&ifr, 0, sizeof(ifr));
955 ifr.ifr_ifindex = index;
957 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
963 DBG("ifname %s", ifr.ifr_name);
965 memset(&rt, 0, sizeof(rt));
966 rt.rt_flags = RTF_UP;
968 memset(&addr, 0, sizeof(addr));
969 addr.sin_family = AF_INET;
970 addr.sin_addr.s_addr = INADDR_ANY;
972 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
973 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
974 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
976 rt.rt_dev = ifr.ifr_name;
978 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
985 connman_error("Removing default interface route failed (%s)",
991 int connman_inet_clear_ipv6_gateway_interface(int index)
995 struct sockaddr_in6 addr;
996 const struct in6_addr any = IN6ADDR_ANY_INIT;
999 DBG("index %d", index);
1001 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1007 memset(&ifr, 0, sizeof(ifr));
1008 ifr.ifr_ifindex = index;
1010 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1016 DBG("ifname %s", ifr.ifr_name);
1018 memset(&rt, 0, sizeof(rt));
1019 rt.rt_flags = RTF_UP;
1021 memset(&addr, 0, sizeof(addr));
1022 addr.sin6_family = AF_INET6;
1023 addr.sin6_addr = any;
1025 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1026 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1027 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1029 rt.rt_dev = ifr.ifr_name;
1031 if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1038 connman_error("Removing default interface route failed (%s)",
1044 bool connman_inet_compare_subnet(int index, const char *host)
1047 struct in_addr _host_addr;
1048 in_addr_t host_addr, netmask_addr, if_addr;
1049 struct sockaddr_in *netmask, *addr;
1052 DBG("host %s", host);
1057 if (inet_aton(host, &_host_addr) == 0)
1059 host_addr = _host_addr.s_addr;
1061 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1065 memset(&ifr, 0, sizeof(ifr));
1066 ifr.ifr_ifindex = index;
1068 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1073 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1078 netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1079 netmask_addr = netmask->sin_addr.s_addr;
1081 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1088 addr = (struct sockaddr_in *)&ifr.ifr_addr;
1089 if_addr = addr->sin_addr.s_addr;
1091 return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1094 int connman_inet_remove_from_bridge(int index, const char *bridge)
1102 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1108 memset(&ifr, 0, sizeof(ifr));
1109 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1110 ifr.ifr_ifindex = index;
1112 if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1119 connman_error("Remove interface from bridge error %s",
1125 int connman_inet_add_to_bridge(int index, const char *bridge)
1133 sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1139 memset(&ifr, 0, sizeof(ifr));
1140 strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1141 ifr.ifr_ifindex = index;
1143 if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1150 connman_error("Add interface to bridge error %s",
1156 int connman_inet_set_mtu(int index, int mtu)
1161 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1165 memset(&ifr, 0, sizeof(ifr));
1166 ifr.ifr_ifindex = index;
1168 err = ioctl(sk, SIOCGIFNAME, &ifr);
1171 err = ioctl(sk, SIOCSIFMTU, &ifr);
1178 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1188 sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1192 index = if_nametoindex(tunnel);
1194 err = connman_inet_set_mtu(index, mtu);
1198 memset(&ifr, 0, sizeof(ifr));
1199 strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1200 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1207 if ((ifr.ifr_flags ^ flags) & mask) {
1208 ifr.ifr_flags &= ~mask;
1209 ifr.ifr_flags |= mask & flags;
1210 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1212 connman_error("SIOCSIFFLAGS failed: %s",
1221 int connman_inet_create_tunnel(char **iface)
1226 fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1229 connman_error("Failed to open /dev/net/tun: %s",
1234 memset(&ifr, 0, sizeof(ifr));
1235 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1237 for (i = 0; i < 256; i++) {
1238 sprintf(ifr.ifr_name, "tun%d", i);
1240 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1245 connman_error("Failed to find available tun device");
1250 *iface = g_strdup(ifr.ifr_name);
1256 * This callback struct is used when sending router and neighbor
1257 * solicitation and advertisement messages.
1260 GIOChannel *channel;
1262 struct sockaddr_in6 addr;
1268 #define CMSG_BUF_LEN 512
1269 #define IN6ADDR_ALL_NODES_MC_INIT \
1270 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1271 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1272 { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1274 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1275 static const struct in6_addr in6addr_all_routers_mc =
1276 IN6ADDR_ALL_ROUTERS_MC_INIT;
1278 static void xs_cleanup(struct xs_cb_data *data)
1280 if (data->channel) {
1281 g_io_channel_shutdown(data->channel, TRUE, NULL);
1282 g_io_channel_unref(data->channel);
1283 data->channel = NULL;
1286 if (data->timeout > 0)
1287 g_source_remove(data->timeout);
1289 if (data->watch_id > 0)
1290 g_source_remove(data->watch_id);
1295 static gboolean rs_timeout_cb(gpointer user_data)
1297 struct xs_cb_data *data = user_data;
1299 DBG("user data %p", user_data);
1304 if (data->callback) {
1305 __connman_inet_rs_cb_t cb = data->callback;
1306 cb(NULL, 0, data->user_data);
1314 static int icmpv6_recv(int fd, gpointer user_data)
1318 unsigned char chdr[CMSG_BUF_LEN];
1319 unsigned char buf[1540];
1320 struct xs_cb_data *data = user_data;
1321 struct nd_router_advert *hdr;
1322 struct sockaddr_in6 saddr;
1324 __connman_inet_rs_cb_t cb = data->callback;
1328 iov.iov_len = sizeof(buf);
1331 mhdr.msg_name = (void *)&saddr;
1332 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1334 mhdr.msg_iov = &iov;
1335 mhdr.msg_iovlen = 1;
1336 mhdr.msg_control = (void *)chdr;
1337 mhdr.msg_controllen = CMSG_BUF_LEN;
1339 len = recvmsg(fd, &mhdr, 0);
1341 cb(NULL, 0, data->user_data);
1346 hdr = (struct nd_router_advert *)buf;
1347 DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1348 sizeof(struct nd_router_advert));
1349 if (hdr->nd_ra_code != 0)
1352 cb(hdr, len, data->user_data);
1358 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1364 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1367 fd = g_io_channel_unix_get_fd(chan);
1368 ret = icmpv6_recv(fd, data);
1375 /* Adapted from RFC 1071 "C" Implementation Example */
1376 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1377 const void *extra_data, socklen_t extra_datalen)
1379 register unsigned long sum = 0;
1384 /* caller must make sure datalen is even */
1386 addr = (uint16_t *)phdr;
1387 for (i = 0; i < 20; i++)
1391 addr = (uint16_t *)data;
1399 count = extra_datalen;
1400 addr = (uint16_t *)extra_data;
1409 sum = (sum & 0xffff) + (sum >> 16);
1411 return (uint16_t)~sum;
1414 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1415 const struct in6_addr *source,
1416 unsigned char *buf, size_t len, uint16_t lifetime)
1419 struct in6_addr src;
1420 struct in6_addr dst;
1422 uint8_t reserved[3];
1429 struct icmp6_hdr icmp;
1430 struct nd_neighbor_solicit ns;
1431 struct nd_router_solicit rs;
1432 struct nd_router_advert ra;
1437 struct cmsghdr *cmsg;
1438 struct in6_pktinfo *pinfo;
1439 struct sockaddr_in6 dst, src;
1440 char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1441 struct iovec iov[2];
1442 int fd, datalen, ret, iovlen = 1;
1446 fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1450 memset(&frame, 0, sizeof(frame));
1451 memset(&dst, 0, sizeof(dst));
1453 if (type == ND_ROUTER_SOLICIT)
1454 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1455 else if (type == ND_ROUTER_ADVERT) {
1456 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1457 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1458 } else if (type == ND_NEIGHBOR_SOLICIT) {
1459 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1460 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1466 dst.sin6_addr = *dest;
1469 src.sin6_addr = *source;
1471 src.sin6_addr = in6addr_any;
1473 /* Fill in the IPv6 header */
1474 frame.ip.ip6_vfc = 0x60;
1475 frame.ip.ip6_plen = htons(datalen + len);
1476 frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1477 frame.ip.ip6_hlim = 255;
1478 frame.ip.ip6_dst = dst.sin6_addr;
1479 frame.ip.ip6_src = src.sin6_addr;
1480 /* all other fields are already set to zero */
1482 /* Prepare pseudo header for csum */
1483 memset(&phdr, 0, sizeof(phdr));
1484 phdr.dst = dst.sin6_addr;
1485 phdr.src = src.sin6_addr;
1486 phdr.plen = htonl(datalen + len);
1487 phdr.nxt = IPPROTO_ICMPV6;
1489 /* Fill in remaining ICMP header fields */
1490 frame.i.icmp.icmp6_type = type;
1491 frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1493 iov[0].iov_base = &frame;
1494 iov[0].iov_len = sizeof(frame.ip) + datalen;
1497 iov[1].iov_base = buf;
1498 iov[1].iov_len = len;
1502 dst.sin6_family = AF_INET6;
1503 msgh.msg_name = &dst;
1504 msgh.msg_namelen = sizeof(dst);
1506 msgh.msg_iovlen = iovlen;
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,
1558 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1563 ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1566 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1573 int __connman_inet_ipv6_send_rs(int index, int timeout,
1574 __connman_inet_rs_cb_t callback, void *user_data)
1576 struct xs_cb_data *data;
1577 struct icmp6_filter filter;
1578 struct in6_addr solicit;
1579 struct in6_addr dst = in6addr_all_routers_mc;
1585 data = g_try_malloc0(sizeof(struct xs_cb_data));
1589 data->callback = callback;
1590 data->user_data = user_data;
1591 data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1593 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1599 ICMP6_FILTER_SETBLOCKALL(&filter);
1600 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1602 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1603 sizeof(struct icmp6_filter));
1605 ipv6_addr_solict_mult(&dst, &solicit);
1606 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1607 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1609 data->channel = g_io_channel_unix_new(sk);
1610 g_io_channel_set_close_on_unref(data->channel, TRUE);
1612 g_io_channel_set_encoding(data->channel, NULL, NULL);
1613 g_io_channel_set_buffered(data->channel, FALSE);
1615 data->watch_id = g_io_add_watch(data->channel,
1616 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1617 icmpv6_event, data);
1619 ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1624 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1625 struct in6_addr *advert)
1627 ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1628 htonl(0xFF000000) | addr->s6_addr32[3]);
1631 #define MSG_SIZE_SEND 1452
1633 static int inc_len(int len, int inc)
1635 if (len > MSG_SIZE_SEND)
1642 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1643 GSList *prefixes, int router_lifetime)
1646 struct in6_addr src, *source;
1647 struct in6_addr dst = in6addr_all_nodes_mc;
1648 GDHCPIAPrefix *prefix;
1649 unsigned char buf[MSG_SIZE_SEND];
1650 char addr_str[INET6_ADDRSTRLEN];
1657 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1662 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1667 DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1668 prefixes, inet_ntop(AF_INET6, source, addr_str,
1672 memset(buf, 0, MSG_SIZE_SEND);
1675 for (list = prefixes; list; list = list->next) {
1676 struct nd_opt_prefix_info *pinfo;
1678 prefix = list->data;
1679 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1681 len = inc_len(len, sizeof(*pinfo));
1687 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1688 pinfo->nd_opt_pi_len = 4;
1689 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1690 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1691 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1692 if (router_lifetime > 0) {
1693 pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1694 pinfo->nd_opt_pi_preferred_time =
1695 htonl(prefix->preferred);
1697 pinfo->nd_opt_pi_reserved2 = 0;
1699 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1700 sizeof(struct in6_addr));
1702 DBG("[%d] index %d prefix %s/%d", count, index,
1703 inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1704 INET6_ADDRSTRLEN), prefix->prefixlen);
1710 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1711 buf, len, router_lifetime);
1713 DBG("cannot send RA %d/%s", err, strerror(-err));
1721 void __connman_inet_ipv6_stop_recv_rs(void *context)
1726 xs_cleanup(context);
1729 static int icmpv6_rs_recv(int fd, gpointer user_data)
1733 unsigned char chdr[CMSG_BUF_LEN];
1734 unsigned char buf[1540];
1735 struct xs_cb_data *data = user_data;
1736 struct nd_router_solicit *hdr;
1737 struct sockaddr_in6 saddr;
1739 __connman_inet_recv_rs_cb_t cb = data->callback;
1743 iov.iov_len = sizeof(buf);
1746 mhdr.msg_name = (void *)&saddr;
1747 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1749 mhdr.msg_iov = &iov;
1750 mhdr.msg_iovlen = 1;
1751 mhdr.msg_control = (void *)chdr;
1752 mhdr.msg_controllen = CMSG_BUF_LEN;
1754 len = recvmsg(fd, &mhdr, 0);
1756 cb(NULL, 0, data->user_data);
1760 hdr = (struct nd_router_solicit *)buf;
1761 DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1762 sizeof(struct nd_router_solicit));
1763 if (hdr->nd_rs_code != 0)
1766 cb(hdr, len, data->user_data);
1770 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1777 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1780 fd = g_io_channel_unix_get_fd(chan);
1781 ret = icmpv6_rs_recv(fd, data);
1788 int __connman_inet_ipv6_start_recv_rs(int index,
1789 __connman_inet_recv_rs_cb_t callback,
1793 struct xs_cb_data *data;
1794 struct icmp6_filter filter;
1795 char addr_str[INET6_ADDRSTRLEN];
1798 data = g_try_malloc0(sizeof(struct xs_cb_data));
1802 data->callback = callback;
1803 data->user_data = user_data;
1805 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1813 ICMP6_FILTER_SETBLOCKALL(&filter);
1814 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1816 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1817 sizeof(struct icmp6_filter));
1819 err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1821 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1822 &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1823 err, strerror(-err));
1825 data->channel = g_io_channel_unix_new(sk);
1826 g_io_channel_set_close_on_unref(data->channel, TRUE);
1828 g_io_channel_set_encoding(data->channel, NULL, NULL);
1829 g_io_channel_set_buffered(data->channel, FALSE);
1831 data->watch_id = g_io_add_watch(data->channel,
1832 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1833 icmpv6_rs_event, data);
1840 static gboolean ns_timeout_cb(gpointer user_data)
1842 struct xs_cb_data *data = user_data;
1844 DBG("user data %p", user_data);
1849 if (data->callback) {
1850 __connman_inet_ns_cb_t cb = data->callback;
1851 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1859 static int icmpv6_nd_recv(int fd, gpointer user_data)
1863 unsigned char chdr[CMSG_BUF_LEN];
1864 unsigned char buf[1540];
1865 struct xs_cb_data *data = user_data;
1866 struct nd_neighbor_advert *hdr;
1867 struct sockaddr_in6 saddr;
1869 __connman_inet_ns_cb_t cb = data->callback;
1873 iov.iov_len = sizeof(buf);
1876 mhdr.msg_name = (void *)&saddr;
1877 mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1879 mhdr.msg_iov = &iov;
1880 mhdr.msg_iovlen = 1;
1881 mhdr.msg_control = (void *)chdr;
1882 mhdr.msg_controllen = CMSG_BUF_LEN;
1884 len = recvmsg(fd, &mhdr, 0);
1886 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1891 hdr = (struct nd_neighbor_advert *)buf;
1892 DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1893 sizeof(struct nd_neighbor_advert));
1894 if (hdr->nd_na_code != 0)
1898 * We can receive any neighbor advertisement so we need to check if the
1899 * packet was meant for us and ignore the packet otherwise.
1901 if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1902 sizeof(struct in6_addr)))
1905 cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1911 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
1918 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1921 fd = g_io_channel_unix_get_fd(chan);
1922 ret = icmpv6_nd_recv(fd, data);
1929 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
1930 struct in6_addr *addr,
1931 __connman_inet_ns_cb_t callback,
1934 struct xs_cb_data *data;
1935 struct icmp6_filter filter;
1936 struct in6_addr solicit;
1937 int sk, err, val = 1;
1939 if (timeout_ms <= 0)
1942 data = g_try_malloc0(sizeof(struct xs_cb_data));
1946 data->callback = callback;
1947 data->user_data = user_data;
1948 data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
1953 memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
1955 sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1961 ICMP6_FILTER_SETBLOCKALL(&filter);
1962 ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
1964 setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1965 sizeof(struct icmp6_filter));
1967 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
1968 &val, sizeof(val)) < 0) {
1970 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
1976 if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
1977 &val, sizeof(val)) < 0) {
1979 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
1986 setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
1988 ipv6_addr_solict_mult(addr, &solicit);
1989 if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1990 if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1992 data->channel = g_io_channel_unix_new(sk);
1993 g_io_channel_set_close_on_unref(data->channel, TRUE);
1995 g_io_channel_set_encoding(data->channel, NULL, NULL);
1996 g_io_channel_set_buffered(data->channel, FALSE);
1998 data->watch_id = g_io_add_watch(data->channel,
1999 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2000 icmpv6_nd_event, data);
2002 err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2003 (unsigned char *)addr, 0, 0);
2005 DBG("Cannot send NS %d/%s", err, strerror(-err));
2012 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2013 unsigned int length)
2015 GSList *prefixes = NULL;
2019 if (length <= sizeof(struct nd_router_advert))
2022 len = length - sizeof(struct nd_router_advert);
2023 pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2026 struct nd_opt_prefix_info *pinfo;
2027 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2034 optlen = pos[1] << 3;
2035 if (optlen == 0 || optlen > len)
2039 case ND_OPT_PREFIX_INFORMATION:
2040 pinfo = (struct nd_opt_prefix_info *)pos;
2041 prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2042 prefix_str, INET6_ADDRSTRLEN);
2046 str = g_strdup_printf("%s/%d", prefix,
2047 pinfo->nd_opt_pi_prefix_len);
2048 prefixes = g_slist_prepend(prefixes, str);
2050 DBG("prefix %s", str);
2062 static int get_dest_addr(int family, int index, char *buf, int len)
2068 sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2072 memset(&ifr, 0, sizeof(ifr));
2073 ifr.ifr_ifindex = index;
2075 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2076 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2081 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2082 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2087 if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2093 DBG("index %d %s", index, ifr.ifr_name);
2095 if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2096 connman_error("Get destination address failed (%s)",
2106 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2109 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2116 if (!inet_ntop(family, addr, buf, len)) {
2117 DBG("error %d/%s", errno, strerror(errno));
2124 int connman_inet_get_dest_addr(int index, char **dest)
2126 char addr[INET_ADDRSTRLEN];
2129 ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2133 *dest = g_strdup(addr);
2135 DBG("destination %s", *dest);
2140 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2142 char addr[INET6_ADDRSTRLEN];
2145 ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2149 *dest = g_strdup(addr);
2151 DBG("destination %s", *dest);
2156 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2159 int rcvbuf = 1024 * 4;
2161 rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2163 connman_error("Can not open netlink socket: %s",
2168 if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2169 sizeof(sndbuf)) < 0) {
2170 connman_error("SO_SNDBUF: %s", strerror(errno));
2174 if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2175 sizeof(rcvbuf)) < 0) {
2176 connman_error("SO_RCVBUF: %s", strerror(errno));
2180 memset(&rth->local, 0, sizeof(rth->local));
2181 rth->local.nl_family = AF_NETLINK;
2182 rth->local.nl_groups = 0;
2184 if (bind(rth->fd, (struct sockaddr *)&rth->local,
2185 sizeof(rth->local)) < 0) {
2186 connman_error("Can not bind netlink socket: %s",
2191 rth->seq = time(NULL);
2193 DBG("fd %d", rth->fd);
2198 struct inet_rtnl_cb_data {
2199 GIOChannel *channel;
2200 __connman_inet_rtnl_cb_t callback;
2203 struct __connman_inet_rtnl_handle *rtnl;
2207 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2209 struct __connman_inet_rtnl_handle *rth = data->rtnl;
2211 if (data->channel) {
2212 g_io_channel_shutdown(data->channel, TRUE, NULL);
2213 g_io_channel_unref(data->channel);
2214 data->channel = NULL;
2217 DBG("data %p", data);
2219 if (data->rtnl_timeout > 0)
2220 g_source_remove(data->rtnl_timeout);
2222 if (data->watch_id > 0)
2223 g_source_remove(data->watch_id);
2226 __connman_inet_rtnl_close(rth);
2233 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2235 struct inet_rtnl_cb_data *data = user_data;
2237 DBG("user data %p", user_data);
2243 data->callback(NULL, data->user_data);
2245 data->rtnl_timeout = 0;
2246 inet_rtnl_cleanup(data);
2250 static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
2252 struct inet_rtnl_cb_data *rtnl_data = user_data;
2253 struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2254 struct nlmsghdr *h = NULL;
2255 struct sockaddr_nl nladdr;
2256 socklen_t addr_len = sizeof(nladdr);
2257 unsigned char buf[4096];
2262 memset(buf, 0, sizeof(buf));
2263 memset(&nladdr, 0, sizeof(nladdr));
2265 fd = g_io_channel_unix_get_fd(chan);
2267 status = recvfrom(fd, buf, sizeof(buf), 0,
2268 (struct sockaddr *) &nladdr, &addr_len);
2270 if (errno == EINTR || errno == EAGAIN)
2279 if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2280 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2287 struct nlmsgerr *err;
2291 if (!NLMSG_OK(h, len)) {
2296 if (h->nlmsg_seq != rth->seq) {
2298 DBG("skip %d/%d len %d", rth->seq,
2299 h->nlmsg_seq, h->nlmsg_len);
2301 len -= h->nlmsg_len;
2302 ptr += h->nlmsg_len;
2306 switch (h->nlmsg_type) {
2312 err = (struct nlmsgerr *)NLMSG_DATA(h);
2313 connman_error("RTNETLINK answers %s (%d)",
2314 strerror(-err->error), -err->error);
2321 if (h->nlmsg_seq == rth->seq) {
2322 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2324 rtnl_data->callback(h, rtnl_data->user_data);
2326 inet_rtnl_cleanup(rtnl_data);
2332 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2339 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2342 ret = inet_rtnl_recv(chan, user_data);
2349 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2350 struct nlmsghdr *n, int timeout,
2351 __connman_inet_rtnl_cb_t callback, void *user_data)
2353 struct sockaddr_nl nladdr;
2354 struct inet_rtnl_cb_data *data;
2358 memset(&nladdr, 0, sizeof(nladdr));
2359 nladdr.nl_family = AF_NETLINK;
2361 n->nlmsg_seq = seq = ++rtnl->seq;
2364 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2368 data->callback = callback;
2369 data->user_data = user_data;
2371 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2372 inet_rtnl_timeout_cb, data);
2374 data->channel = g_io_channel_unix_new(rtnl->fd);
2375 g_io_channel_set_close_on_unref(data->channel, TRUE);
2377 g_io_channel_set_encoding(data->channel, NULL, NULL);
2378 g_io_channel_set_buffered(data->channel, FALSE);
2380 data->watch_id = g_io_add_watch(data->channel,
2381 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2382 inet_rtnl_event, data);
2384 n->nlmsg_flags |= NLM_F_ACK;
2386 err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2387 (struct sockaddr *) &nladdr, sizeof(nladdr));
2388 DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2390 connman_error("Can not talk to rtnetlink err %d %s",
2391 -errno, strerror(errno));
2395 if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2396 connman_error("Sent %d bytes, msg truncated", err);
2403 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2405 DBG("handle %p", rth);
2413 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2416 int len = RTA_LENGTH(4);
2419 if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2420 DBG("Error! max allowed bound %zd exceeded", maxlen);
2423 rta = NLMSG_TAIL(n);
2424 rta->rta_type = type;
2426 memcpy(RTA_DATA(rta), &data, 4);
2427 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2432 static int parse_rtattr(struct rtattr *tb[], int max,
2433 struct rtattr *rta, int len)
2435 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2436 while (RTA_OK(rta, len)) {
2437 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2438 tb[rta->rta_type] = rta;
2439 rta = RTA_NEXT(rta, len);
2442 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2447 struct get_route_cb_data {
2448 connman_inet_addr_cb_t callback;
2452 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2454 struct get_route_cb_data *data = user_data;
2455 struct rtattr *tb[RTA_MAX+1];
2456 struct rtmsg *r = NLMSG_DATA(answer);
2457 int len, index = -1;
2459 const char *addr = NULL;
2461 DBG("answer %p data %p", answer, user_data);
2466 len = answer->nlmsg_len;
2468 if (answer->nlmsg_type != RTM_NEWROUTE &&
2469 answer->nlmsg_type != RTM_DELROUTE) {
2470 connman_error("Not a route: %08x %08x %08x",
2471 answer->nlmsg_len, answer->nlmsg_type,
2472 answer->nlmsg_flags);
2476 len -= NLMSG_LENGTH(sizeof(*r));
2478 connman_error("BUG: wrong nlmsg len %d", len);
2482 parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2485 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2487 if (tb[RTA_GATEWAY])
2488 addr = inet_ntop(r->rtm_family,
2489 RTA_DATA(tb[RTA_GATEWAY]),
2490 abuf, sizeof(abuf));
2492 DBG("addr %s index %d user %p", addr, index, data->user_data);
2495 if (data && data->callback)
2496 data->callback(addr, index, data->user_data);
2504 * Return the interface index that contains route to host.
2506 int __connman_inet_get_route(const char *dest_address,
2507 connman_inet_addr_cb_t callback, void *user_data)
2509 struct get_route_cb_data *data;
2510 struct addrinfo hints, *rp;
2511 struct __connman_inet_rtnl_handle *rth;
2514 DBG("dest %s", dest_address);
2519 memset(&hints, 0, sizeof(hints));
2520 hints.ai_family = AF_UNSPEC;
2521 hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2523 err = getaddrinfo(dest_address, NULL, &hints, &rp);
2527 rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2533 rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2534 rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2535 rth->req.n.nlmsg_type = RTM_GETROUTE;
2536 rth->req.u.r.rt.rtm_family = rp->ai_family;
2537 rth->req.u.r.rt.rtm_table = 0;
2538 rth->req.u.r.rt.rtm_protocol = 0;
2539 rth->req.u.r.rt.rtm_scope = 0;
2540 rth->req.u.r.rt.rtm_type = 0;
2541 rth->req.u.r.rt.rtm_src_len = 0;
2542 rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2543 rth->req.u.r.rt.rtm_tos = 0;
2545 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2546 &rp->ai_addr, rp->ai_addrlen);
2550 err = __connman_inet_rtnl_open(rth);
2554 data = g_try_malloc(sizeof(struct get_route_cb_data));
2560 data->callback = callback;
2561 data->user_data = user_data;
2563 #define GET_ROUTE_TIMEOUT 2
2564 err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2565 get_route_cb, data);
2574 __connman_inet_rtnl_close(rth);
2581 int connman_inet_check_ipaddress(const char *host)
2583 struct addrinfo hints;
2584 struct addrinfo *addr;
2587 memset(&hints, 0, sizeof(struct addrinfo));
2588 hints.ai_flags = AI_NUMERICHOST;
2591 result = getaddrinfo(host, NULL, &hints, &addr);
2593 result = addr->ai_family;
2599 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2600 bool connman_inet_check_hostname(const char *ptr, size_t len)
2605 * Not empty or complete length not over 255 characters.
2607 if ((len == 0) || (len > 256))
2611 * Consists of [[:alnum:]-]+ labels separated by [.]
2612 * a [_] is against RFC but seems to be "widely used"
2614 for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2616 if ((*p == '-') || (*p == '_')) {
2618 * Not allowed at begin or end of a label.
2620 if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2623 } else if (*p == '.') {
2625 * Each label has to be 1-63 characters;
2626 * we allow [.] at the end ('foo.bar.')
2630 if ((d <= 0) || (d >= 64))
2633 ptr = p + 1; /* Jump to the next label */
2635 } else if (isalnum((unsigned char)*p) == 0) {
2637 * Also numbers at the begin are fine
2646 char **__connman_inet_get_running_interfaces(void)
2650 struct ifreq *ifr = NULL;
2651 int sk, i, numif, count = 0;
2653 memset(&ifc, 0, sizeof(ifc));
2655 sk = socket(AF_INET, SOCK_DGRAM, 0);
2659 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2663 * Allocate some extra bytes just in case there will
2664 * be new interfaces added between two SIOCGIFCONF
2667 ifr = g_try_malloc0(ifc.ifc_len * 2);
2673 if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2676 numif = ifc.ifc_len / sizeof(struct ifreq);
2678 result = g_try_malloc0((numif + 1) * sizeof(char *));
2684 for (i = 0; i < numif; i++) {
2685 struct ifreq *r = &ifr[i];
2686 struct in6_addr *addr6;
2690 * Note that we do not return loopback interfaces here as they
2691 * are not needed for our purposes.
2693 switch (r->ifr_addr.sa_family) {
2695 addr4 = ntohl(((struct sockaddr_in *)
2696 &r->ifr_addr)->sin_addr.s_addr);
2697 if (((addr4 & 0xff000000) >> 24) == 127)
2701 addr6 = &((struct sockaddr_in6 *)
2702 &r->ifr_addr)->sin6_addr;
2703 if (IN6_IS_ADDR_LINKLOCAL(addr6))
2708 result[count++] = g_strdup(r->ifr_name);
2714 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2724 bool connman_inet_is_ipv6_supported()
2728 sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2736 int __connman_inet_get_interface_address(int index, int family, void *address)
2738 struct ifaddrs *ifaddr, *ifa;
2740 char name[IF_NAMESIZE];
2742 if (!if_indextoname(index, name))
2745 DBG("index %d interface %s", index, name);
2747 if (getifaddrs(&ifaddr) < 0) {
2749 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2753 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2757 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2758 ifa->ifa_addr->sa_family == family) {
2759 if (family == AF_INET) {
2760 struct sockaddr_in *in4 = (struct sockaddr_in *)
2762 if (in4->sin_addr.s_addr == INADDR_ANY)
2764 memcpy(address, &in4->sin_addr,
2765 sizeof(struct in_addr));
2766 } else if (family == AF_INET6) {
2767 struct sockaddr_in6 *in6 =
2768 (struct sockaddr_in6 *)ifa->ifa_addr;
2769 if (memcmp(&in6->sin6_addr, &in6addr_any,
2770 sizeof(struct in6_addr)) == 0)
2772 memcpy(address, &in6->sin6_addr,
2773 sizeof(struct in6_addr));
2786 freeifaddrs(ifaddr);
2790 static int iprule_modify(int cmd, int family, uint32_t table_id,
2793 struct __connman_inet_rtnl_handle rth;
2796 memset(&rth, 0, sizeof(rth));
2798 rth.req.n.nlmsg_type = cmd;
2799 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2800 rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2801 rth.req.u.r.rt.rtm_family = family;
2802 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2803 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2804 rth.req.u.r.rt.rtm_table = table_id;
2805 rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2806 rth.req.u.r.rt.rtm_flags = 0;
2808 if (cmd == RTM_NEWRULE) {
2809 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2810 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2813 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2814 FRA_FWMARK, fwmark);
2816 if (table_id < 256) {
2817 rth.req.u.r.rt.rtm_table = table_id;
2819 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2820 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2821 FRA_TABLE, table_id);
2824 if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2825 rth.req.u.r.rt.rtm_family = AF_INET;
2827 ret = __connman_inet_rtnl_open(&rth);
2831 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2834 __connman_inet_rtnl_close(&rth);
2839 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2841 /* ip rule add fwmark 9876 table 1234 */
2843 return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2846 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2848 return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2851 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2852 const char *gateway)
2854 struct __connman_inet_rtnl_handle rth;
2855 unsigned char buf[sizeof(struct in6_addr)];
2857 int family = connman_inet_check_ipaddress(gateway);
2870 ret = inet_pton(family, gateway, buf);
2874 memset(&rth, 0, sizeof(rth));
2876 rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2877 rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
2878 rth.req.n.nlmsg_type = cmd;
2879 rth.req.u.r.rt.rtm_family = family;
2880 rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
2881 rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
2882 rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2883 rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2884 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2886 __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
2888 if (table_id < 256) {
2889 rth.req.u.r.rt.rtm_table = table_id;
2891 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2892 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2893 RTA_TABLE, table_id);
2896 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2899 ret = __connman_inet_rtnl_open(&rth);
2903 ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2906 __connman_inet_rtnl_close(&rth);
2911 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
2912 const char *gateway)
2914 /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
2916 return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
2919 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
2920 const char *gateway)
2922 /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
2924 return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
2927 int __connman_inet_get_interface_ll_address(int index, int family,
2930 struct ifaddrs *ifaddr, *ifa;
2932 char name[IF_NAMESIZE];
2934 if (!if_indextoname(index, name))
2937 DBG("index %d interface %s", index, name);
2939 if (getifaddrs(&ifaddr) < 0) {
2941 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2945 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2949 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2950 ifa->ifa_addr->sa_family == family) {
2951 if (family == AF_INET) {
2952 struct sockaddr_in *in4 = (struct sockaddr_in *)
2954 if (in4->sin_addr.s_addr == INADDR_ANY)
2956 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
2957 ((in_addr_t) 0xa9fe0000))
2959 memcpy(address, &in4->sin_addr,
2960 sizeof(struct in_addr));
2961 } else if (family == AF_INET6) {
2962 struct sockaddr_in6 *in6 =
2963 (struct sockaddr_in6 *)ifa->ifa_addr;
2964 if (memcmp(&in6->sin6_addr, &in6addr_any,
2965 sizeof(struct in6_addr)) == 0)
2967 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
2970 memcpy(address, &in6->sin6_addr,
2971 sizeof(struct in6_addr));
2983 freeifaddrs(ifaddr);
2987 int __connman_inet_get_address_netmask(int ifindex,
2988 struct sockaddr_in *address,
2989 struct sockaddr_in *netmask)
2991 int sk, ret = -EINVAL;
2994 DBG("index %d", ifindex);
2996 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3000 memset(&ifr, 0, sizeof(ifr));
3001 ifr.ifr_ifindex = ifindex;
3003 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3006 if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3009 memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3010 sizeof(struct sockaddr_in));
3012 if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3015 memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3016 sizeof(struct sockaddr_in));