Imported Upstream version 1.40
[platform/upstream/connman.git] / src / inet.c
1 /*
2  *
3  *  Connection Manager
4  *
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
8  *
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.
12  *
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.
17  *
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
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/stat.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <linux/sockios.h>
37 #include <netdb.h>
38 #include <arpa/inet.h>
39 #include <net/route.h>
40 #include <net/ethernet.h>
41 #include <net/if.h>
42 #include <net/if_arp.h>
43 #include <netinet/icmp6.h>
44 #include <fcntl.h>
45 #include <linux/if_tun.h>
46 #include <ctype.h>
47 #include <ifaddrs.h>
48 #include <linux/fib_rules.h>
49
50 #include "connman.h"
51 #include <gdhcp/gdhcp.h>
52
53 #define NLMSG_TAIL(nmsg)                                \
54         ((struct rtattr *) (((uint8_t*) (nmsg)) +       \
55         NLMSG_ALIGN((nmsg)->nlmsg_len)))
56
57 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
58                                 int type, const void *data, size_t data_length)
59 {
60         size_t length;
61         struct rtattr *rta;
62
63         length = RTA_LENGTH(data_length);
64
65         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
66                 return -E2BIG;
67
68         rta = NLMSG_TAIL(n);
69         rta->rta_type = type;
70         rta->rta_len = length;
71         memcpy(RTA_DATA(rta), data, data_length);
72         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
73
74         return 0;
75 }
76
77 int __connman_inet_modify_address(int cmd, int flags,
78                                 int index, int family,
79                                 const char *address,
80                                 const char *peer,
81                                 unsigned char prefixlen,
82                                 const char *broadcast,
83                                 bool is_p2p)
84 {
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))];
89
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;
95         int sk, err;
96
97         DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
98                 "prefixlen %hhu broadcast %s p2p %s", cmd, flags, index,
99                 family, address, peer, prefixlen, broadcast,
100                 is_p2p ? "true" : "false");
101
102         if (!address)
103                 return -EINVAL;
104
105         if (family != AF_INET && family != AF_INET6)
106                 return -EINVAL;
107
108         memset(&request, 0, sizeof(request));
109
110         header = (struct nlmsghdr *)request;
111         header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
112         header->nlmsg_type = cmd;
113         header->nlmsg_flags = NLM_F_REQUEST | flags;
114         header->nlmsg_seq = 1;
115
116         ifaddrmsg = NLMSG_DATA(header);
117         ifaddrmsg->ifa_family = family;
118         ifaddrmsg->ifa_prefixlen = prefixlen;
119         ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
120         ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
121         ifaddrmsg->ifa_index = index;
122
123         if (family == AF_INET) {
124                 if (inet_pton(AF_INET, address, &ipv4_addr) != 1)
125                         return -1;
126
127                 if (peer) {
128                         if (inet_pton(AF_INET, peer, &ipv4_dest) != 1)
129                                 return -1;
130
131                         err = __connman_inet_rtnl_addattr_l(header,
132                                                         sizeof(request),
133                                                         IFA_ADDRESS,
134                                                         &ipv4_dest,
135                                                         sizeof(ipv4_dest));
136                         if (err < 0)
137                                 return err;
138                 }
139
140                 err = __connman_inet_rtnl_addattr_l(header,
141                                                 sizeof(request),
142                                                 IFA_LOCAL,
143                                                 &ipv4_addr,
144                                                 sizeof(ipv4_addr));
145                 if (err < 0)
146                         return err;
147
148                 /*
149                  * Broadcast address must not be added for P2P / VPN as
150                  * getifaddrs() cannot interpret destination address.
151                  */
152                 if (!is_p2p) {
153                         if (broadcast)
154                                 inet_pton(AF_INET, broadcast, &ipv4_bcast);
155                         else
156                                 ipv4_bcast.s_addr = ipv4_addr.s_addr |
157                                         htonl(0xfffffffflu >> prefixlen);
158
159                         err = __connman_inet_rtnl_addattr_l(header,
160                                                         sizeof(request),
161                                                         IFA_BROADCAST,
162                                                         &ipv4_bcast,
163                                                         sizeof(ipv4_bcast));
164                         if (err < 0)
165                                 return err;
166                 }
167         } else if (family == AF_INET6) {
168                 if (inet_pton(AF_INET6, address, &ipv6_addr) != 1)
169                         return -1;
170
171                 err = __connman_inet_rtnl_addattr_l(header,
172                                                 sizeof(request),
173                                                 IFA_LOCAL,
174                                                 &ipv6_addr,
175                                                 sizeof(ipv6_addr));
176                 if (err < 0)
177                         return err;
178         }
179
180         sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
181         if (sk < 0)
182                 return -errno;
183
184         memset(&nl_addr, 0, sizeof(nl_addr));
185         nl_addr.nl_family = AF_NETLINK;
186
187         if ((err = sendto(sk, request, header->nlmsg_len, 0,
188                         (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
189                 goto done;
190
191         err = 0;
192
193 done:
194         close(sk);
195
196         return err;
197 }
198
199 static bool is_addr_unspec(int family, struct sockaddr *addr)
200 {
201         struct sockaddr_in *in4;
202         struct sockaddr_in6 *in6;
203
204         switch (family) {
205         case AF_INET:
206                 in4 = (struct sockaddr_in*) addr;
207                 return in4->sin_addr.s_addr == INADDR_ANY;
208         case AF_INET6:
209                 in6 = (struct sockaddr_in6*) addr;
210                 return IN6_IS_ADDR_UNSPECIFIED(&in6->sin6_addr);
211         default:
212                 return false;
213         }
214 }
215
216 static bool is_addr_ll(int family, struct sockaddr *addr)
217 {
218         struct sockaddr_in *in4;
219         struct sockaddr_in6 *in6;
220
221         switch (family) {
222         case AF_INET:
223                 in4 = (struct sockaddr_in*) addr;
224                 return (in4->sin_addr.s_addr & IN_CLASSB_NET) ==
225                                         ((in_addr_t) htonl(0xa9fe0000));
226         case AF_INET6:
227                 in6 = (struct sockaddr_in6*) addr;
228                 return IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr);
229         default:
230                 return false;
231         }
232 }
233
234 bool __connman_inet_is_any_addr(const char *address, int family)
235 {
236         bool ret = false;
237         struct addrinfo hints;
238         struct addrinfo *result = NULL;
239
240         if (!address || !*address)
241                 goto out;
242
243         memset(&hints, 0, sizeof(struct addrinfo));
244
245         hints.ai_family = family;
246
247         if (getaddrinfo(address, NULL, &hints, &result))
248                 goto out;
249
250         if (result) {
251                 ret = is_addr_unspec(result->ai_family, result->ai_addr);
252                 freeaddrinfo(result);
253         }
254
255 out:
256         return ret;
257 }
258
259 int connman_inet_ifindex(const char *name)
260 {
261         struct ifreq ifr;
262         int sk, err;
263
264         if (!name)
265                 return -1;
266
267         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
268         if (sk < 0)
269                 return -1;
270
271         memset(&ifr, 0, sizeof(ifr));
272         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name) - 1);
273
274         err = ioctl(sk, SIOCGIFINDEX, &ifr);
275
276         close(sk);
277
278         if (err < 0)
279                 return -1;
280
281         return ifr.ifr_ifindex;
282 }
283
284 char *connman_inet_ifname(int index)
285 {
286         struct ifreq ifr;
287         int sk, err;
288
289         if (index < 0)
290                 return NULL;
291
292         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
293         if (sk < 0)
294                 return NULL;
295
296         memset(&ifr, 0, sizeof(ifr));
297         ifr.ifr_ifindex = index;
298
299         err = ioctl(sk, SIOCGIFNAME, &ifr);
300
301         close(sk);
302
303         if (err < 0)
304                 return NULL;
305
306         return g_strdup(ifr.ifr_name);
307 }
308
309 int connman_inet_ifup(int index)
310 {
311         struct ifreq ifr;
312         int sk, err;
313
314         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
315         if (sk < 0)
316                 return -errno;
317
318         memset(&ifr, 0, sizeof(ifr));
319         ifr.ifr_ifindex = index;
320
321         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
322                 err = -errno;
323                 goto done;
324         }
325
326         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
327                 err = -errno;
328                 goto done;
329         }
330
331         if (ifr.ifr_flags & IFF_UP) {
332                 err = -EALREADY;
333                 goto done;
334         }
335
336         ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
337
338         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
339                 err = -errno;
340                 goto done;
341         }
342
343         err = 0;
344
345 done:
346         close(sk);
347
348         return err;
349 }
350
351 int connman_inet_ifdown(int index)
352 {
353         struct ifreq ifr, addr_ifr;
354         struct sockaddr_in *addr;
355         int sk, err;
356
357         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
358         if (sk < 0)
359                 return -errno;
360
361         memset(&ifr, 0, sizeof(ifr));
362         ifr.ifr_ifindex = index;
363
364         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
365                 err = -errno;
366                 goto done;
367         }
368
369         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
370                 err = -errno;
371                 goto done;
372         }
373
374         memset(&addr_ifr, 0, sizeof(addr_ifr));
375         memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
376         addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
377         addr->sin_family = AF_INET;
378         if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
379                 connman_warn("Could not clear IPv4 address index %d", index);
380
381         if (!(ifr.ifr_flags & IFF_UP)) {
382                 err = -EALREADY;
383                 goto done;
384         }
385
386         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
387
388         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
389                 err = -errno;
390         else
391                 err = 0;
392
393 done:
394         close(sk);
395
396         return err;
397 }
398
399 bool connman_inet_is_ifup(int index)
400 {
401         int sk;
402         struct ifreq ifr;
403         bool ret = false;
404
405         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
406         if (sk < 0) {
407                 connman_warn("Failed to open socket");
408                 return false;
409         }
410
411         memset(&ifr, 0, sizeof(ifr));
412         ifr.ifr_ifindex = index;
413
414         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
415                 connman_warn("Failed to get interface name for interface %d", index);
416                 goto done;
417         }
418
419         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
420                 connman_warn("Failed to get interface flags for index %d", index);
421                 goto done;
422         }
423
424         if (ifr.ifr_flags & IFF_UP)
425                 ret = true;
426
427 done:
428         close(sk);
429
430         return ret;
431 }
432
433 struct in6_ifreq {
434         struct in6_addr ifr6_addr;
435         __u32 ifr6_prefixlen;
436         unsigned int ifr6_ifindex;
437 };
438
439 int connman_inet_set_ipv6_address(int index,
440                 struct connman_ipaddress *ipaddress)
441 {
442         int err;
443         unsigned char prefix_len;
444         const char *address;
445         bool is_p2p;
446
447         if (!ipaddress->local)
448                 return 0;
449
450         prefix_len = ipaddress->prefixlen;
451         address = ipaddress->local;
452         is_p2p = ipaddress->is_p2p;
453
454         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
455
456         err = __connman_inet_modify_address(RTM_NEWADDR,
457                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
458                                 address, NULL, prefix_len, NULL, is_p2p);
459         if (err < 0) {
460                 connman_error("%s: %s", __func__, strerror(-err));
461                 return err;
462         }
463
464         return 0;
465 }
466
467 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
468 {
469         int err;
470         unsigned char prefix_len;
471         const char *address, *broadcast, *peer;
472         bool is_p2p;
473
474         if (!ipaddress->local)
475                 return -1;
476
477         prefix_len = ipaddress->prefixlen;
478         address = ipaddress->local;
479         broadcast = ipaddress->broadcast;
480         peer = ipaddress->peer;
481         is_p2p = ipaddress->is_p2p;
482
483         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
484
485         err = __connman_inet_modify_address(RTM_NEWADDR,
486                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
487                                 address, peer, prefix_len, broadcast, is_p2p);
488         if (err < 0) {
489                 connman_error("%s: %s", __func__, strerror(-err));
490                 return err;
491         }
492
493         return 0;
494 }
495
496 int connman_inet_clear_ipv6_address(int index,
497                                         struct connman_ipaddress *ipaddress)
498 {
499         int err;
500         int prefix_len;
501         const char *address;
502         bool is_p2p;
503
504         address = ipaddress->local;
505         prefix_len = ipaddress->prefixlen;
506         is_p2p = ipaddress->is_p2p;
507
508         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
509
510         if (!address)
511                 return -EINVAL;
512
513         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
514                                 address, NULL, prefix_len, NULL, is_p2p);
515         if (err < 0) {
516                 connman_error("%s: %s", __func__, strerror(-err));
517                 return err;
518         }
519
520         return 0;
521 }
522
523 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
524 {
525         int err;
526         unsigned char prefix_len;
527         const char *address, *broadcast, *peer;
528         bool is_p2p;
529
530         prefix_len = ipaddress->prefixlen;
531         address = ipaddress->local;
532         broadcast = ipaddress->broadcast;
533         peer = ipaddress->peer;
534         is_p2p = ipaddress->is_p2p;
535
536         DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
537                 address, prefix_len, peer, broadcast);
538
539         if (!address)
540                 return -EINVAL;
541
542         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
543                                 address, peer, prefix_len, broadcast, is_p2p);
544         if (err < 0) {
545                 connman_error("%s: %s", __func__, strerror(-err));
546                 return err;
547         }
548
549         return 0;
550 }
551
552 int connman_inet_add_host_route(int index, const char *host,
553                                 const char *gateway)
554 {
555         return connman_inet_add_network_route(index, host, gateway, NULL);
556 }
557
558 int connman_inet_del_host_route(int index, const char *host)
559 {
560         return connman_inet_del_network_route(index, host);
561 }
562
563 int connman_inet_add_network_route(int index, const char *host,
564                                         const char *gateway,
565                                         const char *netmask)
566 {
567         struct ifreq ifr;
568         struct rtentry rt;
569         struct sockaddr_in addr;
570         int sk, err = 0;
571
572         DBG("index %d host %s gateway %s netmask %s", index,
573                 host, gateway, netmask);
574
575         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
576         if (sk < 0) {
577                 err = -errno;
578                 goto out;
579         }
580
581         memset(&ifr, 0, sizeof(ifr));
582         ifr.ifr_ifindex = index;
583
584         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
585                 err = -errno;
586                 close(sk);
587                 goto out;
588         }
589
590         DBG("ifname %s", ifr.ifr_name);
591
592         memset(&rt, 0, sizeof(rt));
593         rt.rt_flags = RTF_UP;
594
595         /*
596          * Set RTF_GATEWAY only when gateway is set and the gateway IP address
597          * is not IPv4 any address (0.0.0.0). If the given gateway IP address is
598          * any address adding of route will fail when RTF_GATEWAY set. Passing
599          * gateway as NULL or INADDR_ANY should have the same effect. Setting
600          * the gateway address later to the struct is not affected by this,
601          * since given IPv4 any address (0.0.0.0) equals the value set with
602          * INADDR_ANY.
603          */
604         if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET))
605                 rt.rt_flags |= RTF_GATEWAY;
606         if (!netmask)
607                 rt.rt_flags |= RTF_HOST;
608
609         memset(&addr, 0, sizeof(addr));
610         addr.sin_family = AF_INET;
611         addr.sin_addr.s_addr = inet_addr(host);
612         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
613
614         memset(&addr, 0, sizeof(addr));
615         addr.sin_family = AF_INET;
616         if (gateway)
617                 addr.sin_addr.s_addr = inet_addr(gateway);
618         else
619                 addr.sin_addr.s_addr = INADDR_ANY;
620         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
621
622         memset(&addr, 0, sizeof(addr));
623         addr.sin_family = AF_INET;
624         addr.sin_addr.s_addr = INADDR_ANY;
625         if (netmask)
626                 addr.sin_addr.s_addr = inet_addr(netmask);
627         else
628                 addr.sin_addr.s_addr = INADDR_ANY;
629         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
630
631         rt.rt_dev = ifr.ifr_name;
632
633         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
634                 err = -errno;
635
636         close(sk);
637
638 out:
639         if (err < 0)
640                 connman_error("Adding host route failed (%s)",
641                                                         strerror(-err));
642
643         return err;
644 }
645
646 int connman_inet_del_network_route(int index, const char *host)
647 {
648         struct ifreq ifr;
649         struct rtentry rt;
650         struct sockaddr_in addr;
651         int sk, err = 0;
652
653         DBG("index %d host %s", index, host);
654
655         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
656         if (sk < 0) {
657                 err = -errno;
658                 goto out;
659         }
660
661         memset(&ifr, 0, sizeof(ifr));
662         ifr.ifr_ifindex = index;
663
664         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
665                 err = -errno;
666                 close(sk);
667                 goto out;
668         }
669
670         DBG("ifname %s", ifr.ifr_name);
671
672         memset(&rt, 0, sizeof(rt));
673         rt.rt_flags = RTF_UP | RTF_HOST;
674
675         memset(&addr, 0, sizeof(addr));
676         addr.sin_family = AF_INET;
677         addr.sin_addr.s_addr = inet_addr(host);
678         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
679
680         rt.rt_dev = ifr.ifr_name;
681
682         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
683                 err = -errno;
684
685         close(sk);
686
687 out:
688         if (err < 0)
689                 connman_error("Deleting host route failed (%s)",
690                                                         strerror(-err));
691
692         return err;
693 }
694
695 int connman_inet_del_ipv6_network_route(int index, const char *host,
696                                                 unsigned char prefix_len)
697 {
698         struct in6_rtmsg rt;
699         int sk, err = 0;
700
701         DBG("index %d host %s", index, host);
702
703         if (!host)
704                 return -EINVAL;
705
706         memset(&rt, 0, sizeof(rt));
707
708         rt.rtmsg_dst_len = prefix_len;
709
710         if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) != 1) {
711                 err = -errno;
712                 goto out;
713         }
714
715         rt.rtmsg_flags = RTF_UP | RTF_HOST;
716
717         rt.rtmsg_metric = 1;
718         rt.rtmsg_ifindex = index;
719
720         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
721         if (sk < 0) {
722                 err = -errno;
723                 goto out;
724         }
725
726         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
727                 err = -errno;
728
729         close(sk);
730
731 out:
732         if (err < 0)
733                 connman_error("Del IPv6 host route error (%s)",
734                                                 strerror(-err));
735
736         return err;
737 }
738
739 int connman_inet_del_ipv6_host_route(int index, const char *host)
740 {
741         return connman_inet_del_ipv6_network_route(index, host, 128);
742 }
743
744 int connman_inet_add_ipv6_network_route(int index, const char *host,
745                                         const char *gateway,
746                                         unsigned char prefix_len)
747 {
748         struct in6_rtmsg rt;
749         int sk, err = 0;
750
751         DBG("index %d host %s gateway %s", index, host, gateway);
752
753         if (!host)
754                 return -EINVAL;
755
756         memset(&rt, 0, sizeof(rt));
757
758         rt.rtmsg_dst_len = prefix_len;
759
760         if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) != 1) {
761                 err = -errno;
762                 goto out;
763         }
764
765         rt.rtmsg_flags = RTF_UP | RTF_HOST;
766
767         /*
768          * Set RTF_GATEWAY only when gateway is set, the gateway IP address is
769          * not IPv6 any address (e.g., ::) and the address is valid (conversion
770          * succeeds). If the given gateway IP address is any address then
771          * adding of route will fail when RTF_GATEWAY set. Passing gateway as
772          * NULL or IPv6 any address should have the same effect.
773          */
774
775         if (gateway && !__connman_inet_is_any_addr(gateway, AF_INET6) &&
776                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) == 1)
777                 rt.rtmsg_flags |= RTF_GATEWAY;
778
779         rt.rtmsg_metric = 1;
780         rt.rtmsg_ifindex = index;
781
782         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
783         if (sk < 0) {
784                 err = -errno;
785                 goto out;
786         }
787
788         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
789                 err = -errno;
790
791         close(sk);
792
793 out:
794         if (err < 0)
795                 connman_error("Set IPv6 host route error (%s)",
796                                                 strerror(-err));
797
798         return err;
799 }
800
801 int connman_inet_add_ipv6_host_route(int index, const char *host,
802                                         const char *gateway)
803 {
804         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
805 }
806
807 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
808 {
809         struct in6_rtmsg rt;
810         int sk, err = 0;
811
812         DBG("index %d gateway %s", index, gateway);
813
814         if (!gateway)
815                 return -EINVAL;
816
817         memset(&rt, 0, sizeof(rt));
818
819         if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) != 1) {
820                 err = -errno;
821                 goto out;
822         }
823
824         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
825         rt.rtmsg_metric = 1;
826         rt.rtmsg_dst_len = 0;
827         rt.rtmsg_ifindex = index;
828
829         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
830         if (sk < 0) {
831                 err = -errno;
832                 goto out;
833         }
834
835         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
836                 err = -errno;
837
838         close(sk);
839
840 out:
841         if (err < 0)
842                 connman_error("Clear default IPv6 gateway error (%s)",
843                                                 strerror(-err));
844
845         return err;
846 }
847
848 int connman_inet_set_gateway_interface(int index)
849 {
850         struct ifreq ifr;
851         struct rtentry rt;
852         struct sockaddr_in addr;
853         int sk, err = 0;
854
855         DBG("index %d", index);
856
857         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
858         if (sk < 0) {
859                 err = -errno;
860                 goto out;
861         }
862
863         memset(&ifr, 0, sizeof(ifr));
864         ifr.ifr_ifindex = index;
865
866         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
867                 err = -errno;
868                 close(sk);
869                 goto out;
870         }
871
872         DBG("ifname %s", ifr.ifr_name);
873
874         memset(&rt, 0, sizeof(rt));
875         rt.rt_flags = RTF_UP;
876
877         memset(&addr, 0, sizeof(addr));
878         addr.sin_family = AF_INET;
879         addr.sin_addr.s_addr = INADDR_ANY;
880
881         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
882         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
883         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
884
885         rt.rt_dev = ifr.ifr_name;
886
887         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
888                 err = -errno;
889
890         close(sk);
891
892 out:
893         if (err < 0)
894                 connman_error("Setting default interface route failed (%s)",
895                                                         strerror(-err));
896
897         return err;
898 }
899
900 int connman_inet_set_ipv6_gateway_interface(int index)
901 {
902         struct ifreq ifr;
903         struct rtentry rt;
904         struct sockaddr_in6 addr;
905         const struct in6_addr any = IN6ADDR_ANY_INIT;
906         int sk, err = 0;
907
908         DBG("index %d", index);
909
910         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
911         if (sk < 0) {
912                 err = -errno;
913                 goto out;
914         }
915
916         memset(&ifr, 0, sizeof(ifr));
917         ifr.ifr_ifindex = index;
918
919         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
920                 err = -errno;
921                 close(sk);
922                 goto out;
923         }
924
925         DBG("ifname %s", ifr.ifr_name);
926
927         memset(&rt, 0, sizeof(rt));
928         rt.rt_flags = RTF_UP;
929
930         memset(&addr, 0, sizeof(addr));
931         addr.sin6_family = AF_INET6;
932         addr.sin6_addr = any;
933
934         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
935         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
936         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
937
938         rt.rt_dev = ifr.ifr_name;
939
940         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
941                 err = -errno;
942
943         close(sk);
944
945 out:
946         if (err < 0)
947                 connman_error("Setting default interface route failed (%s)",
948                                                         strerror(-err));
949
950         return err;
951 }
952
953 int connman_inet_clear_gateway_address(int index, const char *gateway)
954 {
955         struct ifreq ifr;
956         struct rtentry rt;
957         struct sockaddr_in addr;
958         int sk, err = 0;
959
960         DBG("index %d gateway %s", index, gateway);
961
962         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
963         if (sk < 0) {
964                 err = -errno;
965                 goto out;
966         }
967
968         memset(&ifr, 0, sizeof(ifr));
969         ifr.ifr_ifindex = index;
970
971         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
972                 err = -errno;
973                 close(sk);
974                 goto out;
975         }
976
977         DBG("ifname %s", ifr.ifr_name);
978
979         memset(&rt, 0, sizeof(rt));
980         rt.rt_flags = RTF_UP | RTF_GATEWAY;
981
982         memset(&addr, 0, sizeof(addr));
983         addr.sin_family = AF_INET;
984         addr.sin_addr.s_addr = INADDR_ANY;
985         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
986
987         memset(&addr, 0, sizeof(addr));
988         addr.sin_family = AF_INET;
989         addr.sin_addr.s_addr = inet_addr(gateway);
990         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
991
992         memset(&addr, 0, sizeof(addr));
993         addr.sin_family = AF_INET;
994         addr.sin_addr.s_addr = INADDR_ANY;
995         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
996
997         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
998                 err = -errno;
999
1000         close(sk);
1001
1002 out:
1003         if (err < 0)
1004                 connman_error("Removing default gateway route failed (%s)",
1005                                                         strerror(-err));
1006
1007         return err;
1008 }
1009
1010 int connman_inet_clear_gateway_interface(int index)
1011 {
1012         struct ifreq ifr;
1013         struct rtentry rt;
1014         struct sockaddr_in addr;
1015         int sk, err = 0;
1016
1017         DBG("index %d", index);
1018
1019         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1020         if (sk < 0) {
1021                 err = -errno;
1022                 goto out;
1023         }
1024
1025         memset(&ifr, 0, sizeof(ifr));
1026         ifr.ifr_ifindex = index;
1027
1028         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1029                 err = -errno;
1030                 close(sk);
1031                 goto out;
1032         }
1033
1034         DBG("ifname %s", ifr.ifr_name);
1035
1036         memset(&rt, 0, sizeof(rt));
1037         rt.rt_flags = RTF_UP;
1038
1039         memset(&addr, 0, sizeof(addr));
1040         addr.sin_family = AF_INET;
1041         addr.sin_addr.s_addr = INADDR_ANY;
1042
1043         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1044         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1045         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1046
1047         rt.rt_dev = ifr.ifr_name;
1048
1049         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1050                 err = -errno;
1051
1052         close(sk);
1053
1054 out:
1055         if (err < 0)
1056                 connman_error("Removing default interface route failed (%s)",
1057                                                         strerror(-err));
1058
1059         return err;
1060 }
1061
1062 int connman_inet_clear_ipv6_gateway_interface(int index)
1063 {
1064         struct ifreq ifr;
1065         struct rtentry rt;
1066         struct sockaddr_in6 addr;
1067         const struct in6_addr any = IN6ADDR_ANY_INIT;
1068         int sk, err = 0;
1069
1070         DBG("index %d", index);
1071
1072         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1073         if (sk < 0) {
1074                 err = -errno;
1075                 goto out;
1076         }
1077
1078         memset(&ifr, 0, sizeof(ifr));
1079         ifr.ifr_ifindex = index;
1080
1081         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1082                 err = -errno;
1083                 close(sk);
1084                 goto out;
1085         }
1086
1087         DBG("ifname %s", ifr.ifr_name);
1088
1089         memset(&rt, 0, sizeof(rt));
1090         rt.rt_flags = RTF_UP;
1091
1092         memset(&addr, 0, sizeof(addr));
1093         addr.sin6_family = AF_INET6;
1094         addr.sin6_addr = any;
1095
1096         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1097         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1098         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1099
1100         rt.rt_dev = ifr.ifr_name;
1101
1102         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1103                 err = -errno;
1104
1105         close(sk);
1106
1107 out:
1108         if (err < 0)
1109                 connman_error("Removing default interface route failed (%s)",
1110                                                         strerror(-err));
1111
1112         return err;
1113 }
1114
1115 #define ADDR_TYPE_MAX 4
1116
1117 struct interface_address {
1118         int index;
1119         int family;
1120         bool allow_unspec;
1121          /* Applies only to ADDR_TYPE_IPADDR in ipaddrs */
1122         bool require_ll;
1123         /* Real types must be in_addr for AF_INET and in6_addr for AF_INET6 */
1124         void *ipaddrs[ADDR_TYPE_MAX];
1125 };
1126
1127 enum ipaddr_type {
1128         ADDR_TYPE_IPADDR = 0,
1129         ADDR_TYPE_NETMASK,
1130         ADDR_TYPE_BRDADDR,
1131         ADDR_TYPE_DSTADDR
1132 };
1133
1134 static int get_interface_addresses(struct interface_address *if_addr)
1135 {
1136         struct ifaddrs *ifaddr;
1137         struct ifaddrs *ifa;
1138         struct sockaddr *addrs[ADDR_TYPE_MAX] = { 0 };
1139         struct sockaddr_in *addr_in;
1140         struct sockaddr_in6 *addr_in6;
1141         char name[IF_NAMESIZE] = { 0 };
1142         size_t len;
1143         int err = -ENOENT;
1144         int i;
1145
1146         if (!if_addr)
1147                 return -EINVAL;
1148
1149         if (!if_indextoname(if_addr->index, name))
1150                 return -EINVAL;
1151
1152         DBG("index %d interface %s", if_addr->index, name);
1153
1154         if (getifaddrs(&ifaddr) < 0) {
1155                 connman_error("Cannot get addresses err %d/%s", errno,
1156                                                         strerror(errno));
1157                 return -errno;
1158         }
1159
1160         for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1161                 if (!ifa->ifa_addr)
1162                         continue;
1163
1164                 if (g_strcmp0(ifa->ifa_name, name) ||
1165                                         ifa->ifa_addr->sa_family !=
1166                                                 if_addr->family)
1167                         continue;
1168
1169
1170                 if (if_addr->ipaddrs[ADDR_TYPE_IPADDR]) {
1171                         if (!if_addr->allow_unspec && is_addr_unspec(
1172                                                 if_addr->family,
1173                                                 ifa->ifa_addr))
1174                                 continue;
1175
1176                         if (if_addr->require_ll && !is_addr_ll(if_addr->family,
1177                                                 ifa->ifa_addr))
1178                                 continue;
1179
1180                         addrs[ADDR_TYPE_IPADDR] = ifa->ifa_addr;
1181                 }
1182
1183                 if (if_addr->ipaddrs[ADDR_TYPE_NETMASK]) {
1184                         if (!if_addr->allow_unspec && is_addr_unspec(
1185                                                 if_addr->family,
1186                                                 ifa->ifa_netmask))
1187                                 continue;
1188
1189                         addrs[ADDR_TYPE_NETMASK] = ifa->ifa_netmask;
1190                 }
1191
1192                 if (if_addr->ipaddrs[ADDR_TYPE_BRDADDR] &&
1193                                         (ifa->ifa_flags & IFF_BROADCAST)) {
1194                         if (!if_addr->allow_unspec && is_addr_unspec(
1195                                                 if_addr->family,
1196                                                 ifa->ifa_ifu.ifu_broadaddr))
1197                                 continue;
1198
1199                         addrs[ADDR_TYPE_BRDADDR] = ifa->ifa_ifu.ifu_broadaddr;
1200                 }
1201
1202                 if (if_addr->ipaddrs[ADDR_TYPE_DSTADDR] &&
1203                                         (ifa->ifa_flags & IFF_POINTOPOINT)) {
1204                         if (!if_addr->allow_unspec && is_addr_unspec(
1205                                                 if_addr->family,
1206                                                 ifa->ifa_ifu.ifu_dstaddr))
1207                                 continue;
1208
1209                         addrs[ADDR_TYPE_DSTADDR] = ifa->ifa_ifu.ifu_dstaddr;
1210                 }
1211
1212                 err = 0;
1213
1214                 break;
1215         }
1216
1217         if (err)
1218                 goto out;
1219
1220         for (i = 0; i < ADDR_TYPE_MAX; i++) {
1221                 if (!addrs[i])
1222                         continue;
1223
1224                 switch (if_addr->family) {
1225                 case AF_INET:
1226                         len = sizeof(struct in_addr);
1227                         addr_in = (struct sockaddr_in*) addrs[i];
1228                         memcpy(if_addr->ipaddrs[i], &addr_in->sin_addr, len);
1229                         break;
1230                 case AF_INET6:
1231                         len = sizeof(struct in6_addr);
1232                         addr_in6 = (struct sockaddr_in6*) addrs[i];
1233                         memcpy(if_addr->ipaddrs[i], &addr_in6->sin6_addr, len);
1234                         break;
1235                 default:
1236                         err = -EINVAL;
1237                         break;
1238                 }
1239         }
1240
1241 out:
1242         freeifaddrs(ifaddr);
1243         return err;
1244 }
1245
1246 bool connman_inet_compare_subnet(int index, const char *host)
1247 {
1248         struct interface_address if_addr = { 0 };
1249         struct in_addr iaddr = { 0 };
1250         struct in_addr imask = { 0 };
1251         struct in_addr haddr = { 0 };
1252
1253         DBG("host %s", host);
1254
1255         if (!host)
1256                 return false;
1257
1258         if (inet_pton(AF_INET, host, &haddr) != 1)
1259                 return false;
1260
1261         if_addr.index = index;
1262         if_addr.family = AF_INET;
1263         if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &iaddr;
1264         if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &imask;
1265
1266         if (get_interface_addresses(&if_addr))
1267                 return false;
1268
1269         return (iaddr.s_addr & imask.s_addr) == (haddr.s_addr & imask.s_addr);
1270 }
1271
1272 static bool mem_mask_equal(const void *a, const void *b,
1273                                         const void *mask, size_t n)
1274 {
1275         const unsigned char *addr1 = a;
1276         const unsigned char *addr2 = b;
1277         const unsigned char *bitmask = mask;
1278         size_t i;
1279
1280         for (i = 0; i < n; i++) {
1281                 if ((addr1[i] ^ addr2[i]) & bitmask[i])
1282                         return false;
1283         }
1284
1285         return true;
1286 }
1287
1288 bool connman_inet_compare_ipv6_subnet(int index, const char *host)
1289 {
1290         struct interface_address addr = { 0 };
1291         struct in6_addr iaddr = { 0 };
1292         struct in6_addr imask = { 0 };
1293         struct in6_addr haddr = { 0 };
1294
1295         if (inet_pton(AF_INET6, host, &haddr) != 1)
1296                 return false;
1297
1298         addr.index = index;
1299         addr.family = AF_INET6;
1300         addr.ipaddrs[ADDR_TYPE_IPADDR] = &iaddr;
1301         addr.ipaddrs[ADDR_TYPE_NETMASK] = &imask;
1302
1303         if (get_interface_addresses(&addr))
1304                 return false;
1305
1306         return mem_mask_equal(&iaddr, &haddr, &imask, sizeof(haddr));
1307 }
1308
1309 int connman_inet_remove_from_bridge(int index, const char *bridge)
1310 {
1311         struct ifreq ifr;
1312         int sk, err = 0;
1313
1314         if (!bridge)
1315                 return -EINVAL;
1316
1317         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1318         if (sk < 0) {
1319                 err = -errno;
1320                 goto out;
1321         }
1322
1323         memset(&ifr, 0, sizeof(ifr));
1324         strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1325         ifr.ifr_ifindex = index;
1326
1327         if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1328                 err = -errno;
1329
1330         close(sk);
1331
1332 out:
1333         if (err < 0)
1334                 connman_error("Remove interface from bridge error %s",
1335                                                         strerror(-err));
1336
1337         return err;
1338 }
1339
1340 int connman_inet_add_to_bridge(int index, const char *bridge)
1341 {
1342         struct ifreq ifr;
1343         int sk, err = 0;
1344
1345         if (!bridge)
1346                 return -EINVAL;
1347
1348         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1349         if (sk < 0) {
1350                 err = -errno;
1351                 goto out;
1352         }
1353
1354         memset(&ifr, 0, sizeof(ifr));
1355         strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1356         ifr.ifr_ifindex = index;
1357
1358         if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1359                 err = -errno;
1360
1361         close(sk);
1362
1363 out:
1364         if (err < 0)
1365                 connman_error("Add interface to bridge error %s",
1366                                                         strerror(-err));
1367
1368         return err;
1369 }
1370
1371 int connman_inet_set_mtu(int index, int mtu)
1372 {
1373         struct ifreq ifr;
1374         int sk, err;
1375
1376         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1377         if (sk < 0)
1378                 return sk;
1379
1380         memset(&ifr, 0, sizeof(ifr));
1381         ifr.ifr_ifindex = index;
1382
1383         err = ioctl(sk, SIOCGIFNAME, &ifr);
1384         if (err == 0) {
1385                 ifr.ifr_mtu = mtu;
1386                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1387         }
1388
1389         close(sk);
1390         return err;
1391 }
1392
1393 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1394 {
1395         struct ifreq ifr;
1396         int sk, err, index;
1397         __u32 mask;
1398         __u32 flags;
1399
1400         if (!tunnel)
1401                 return -EINVAL;
1402
1403         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1404         if (sk < 0)
1405                 return sk;
1406
1407         index = if_nametoindex(tunnel);
1408
1409         err = connman_inet_set_mtu(index, mtu);
1410         if (err != 0)
1411                 goto done;
1412
1413         memset(&ifr, 0, sizeof(ifr));
1414         strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1415         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1416         if (err)
1417                 goto done;
1418
1419         mask = IFF_UP;
1420         flags = IFF_UP;
1421
1422         if ((ifr.ifr_flags ^ flags) & mask) {
1423                 ifr.ifr_flags &= ~mask;
1424                 ifr.ifr_flags |= mask & flags;
1425                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1426                 if (err)
1427                         connman_error("SIOCSIFFLAGS failed: %s",
1428                                                         strerror(errno));
1429         }
1430
1431 done:
1432         close(sk);
1433         return err;
1434 }
1435
1436 int connman_inet_create_tunnel(char **iface)
1437 {
1438         struct ifreq ifr;
1439         int i, fd;
1440
1441         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1442         if (fd < 0) {
1443                 i = -errno;
1444                 connman_error("Failed to open /dev/net/tun: %s",
1445                                 strerror(errno));
1446                 return i;
1447         }
1448
1449         memset(&ifr, 0, sizeof(ifr));
1450         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1451
1452         for (i = 0; i < 256; i++) {
1453                 sprintf(ifr.ifr_name, "tun%d", i);
1454
1455                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1456                         break;
1457         }
1458
1459         if (i == 256) {
1460                 connman_error("Failed to find available tun device");
1461                 close(fd);
1462                 return -ENODEV;
1463         }
1464
1465         *iface = g_strdup(ifr.ifr_name);
1466
1467         return fd;
1468 }
1469
1470 /*
1471  * This callback struct is used when sending router and neighbor
1472  * solicitation and advertisement messages.
1473  */
1474 struct xs_cb_data {
1475         GIOChannel *channel;
1476         void *callback;
1477         struct sockaddr_in6 addr;
1478         guint timeout;
1479         guint watch_id;
1480         void *user_data;
1481 };
1482
1483 #define CMSG_BUF_LEN 512
1484 #define IN6ADDR_ALL_NODES_MC_INIT \
1485         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1486 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1487         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1488
1489 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1490 static const struct in6_addr in6addr_all_routers_mc =
1491                                                 IN6ADDR_ALL_ROUTERS_MC_INIT;
1492
1493 static void xs_cleanup(struct xs_cb_data *data)
1494 {
1495         if (data->channel) {
1496                 g_io_channel_shutdown(data->channel, TRUE, NULL);
1497                 g_io_channel_unref(data->channel);
1498                 data->channel = NULL;
1499         }
1500
1501         if (data->timeout > 0)
1502                 g_source_remove(data->timeout);
1503
1504         if (data->watch_id > 0)
1505                 g_source_remove(data->watch_id);
1506
1507         g_free(data);
1508 }
1509
1510 static gboolean rs_timeout_cb(gpointer user_data)
1511 {
1512         struct xs_cb_data *data = user_data;
1513
1514         DBG("user data %p", user_data);
1515
1516         if (!data)
1517                 return FALSE;
1518
1519         if (data->callback) {
1520                 __connman_inet_rs_cb_t cb = data->callback;
1521                 cb(NULL, 0, data->user_data);
1522         }
1523
1524         data->timeout = 0;
1525         xs_cleanup(data);
1526         return FALSE;
1527 }
1528
1529 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1530 {
1531         struct msghdr mhdr;
1532         struct iovec iov;
1533         unsigned char chdr[CMSG_BUF_LEN];
1534         unsigned char buf[1540];
1535         struct nd_router_advert *hdr;
1536         struct sockaddr_in6 saddr;
1537         ssize_t len;
1538         __connman_inet_rs_cb_t cb = data->callback;
1539
1540         DBG("");
1541
1542         iov.iov_len = sizeof(buf);
1543         iov.iov_base = buf;
1544
1545         mhdr.msg_name = (void *)&saddr;
1546         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1547         mhdr.msg_flags = 0;
1548         mhdr.msg_iov = &iov;
1549         mhdr.msg_iovlen = 1;
1550         mhdr.msg_control = (void *)chdr;
1551         mhdr.msg_controllen = CMSG_BUF_LEN;
1552
1553         len = recvmsg(fd, &mhdr, 0);
1554         if (len < 0) {
1555                 cb(NULL, 0, data->user_data);
1556                 return -errno;
1557         }
1558
1559         hdr = (struct nd_router_advert *)buf;
1560         DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1561                                 sizeof(struct nd_router_advert));
1562         if (hdr->nd_ra_code != 0)
1563                 return 0;
1564
1565         cb(hdr, len, data->user_data);
1566
1567         return len;
1568 }
1569
1570 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1571 {
1572         int fd, ret;
1573         struct xs_cb_data *xs_data = data;
1574
1575         DBG("");
1576
1577         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1578                 goto cleanup;
1579
1580         fd = g_io_channel_unix_get_fd(chan);
1581         ret = icmpv6_recv(fd, xs_data);
1582         if (ret == 0)
1583                 return TRUE;
1584
1585 cleanup:
1586         xs_cleanup(xs_data);
1587         return TRUE;
1588 }
1589
1590 /* Adapted from RFC 1071 "C" Implementation Example */
1591 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1592                 const void *extra_data, socklen_t extra_datalen)
1593 {
1594         register unsigned long sum = 0;
1595         socklen_t count;
1596         uint16_t *addr;
1597         int i;
1598
1599         /* caller must make sure datalen is even */
1600
1601         addr = (uint16_t *)phdr;
1602         for (i = 0; i < 20; i++)
1603                 sum += *addr++;
1604
1605         count = datalen;
1606         addr = (uint16_t *)data;
1607
1608         while (count > 1) {
1609                 sum += *(addr++);
1610                 count -= 2;
1611         }
1612
1613         if (extra_data) {
1614                 count = extra_datalen;
1615                 addr = (uint16_t *)extra_data;
1616
1617                 while (count > 1) {
1618                         sum += *(addr++);
1619                         count -= 2;
1620                 }
1621         }
1622
1623         while (sum >> 16)
1624                 sum = (sum & 0xffff) + (sum >> 16);
1625
1626         return (uint16_t)~sum;
1627 }
1628
1629 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1630                         const struct in6_addr *source,
1631                         unsigned char *buf, size_t len, uint16_t lifetime)
1632 {
1633         struct _phdr {
1634                 struct in6_addr src;
1635                 struct in6_addr dst;
1636                 uint32_t plen;
1637                 uint8_t reserved[3];
1638                 uint8_t nxt;
1639         } phdr;
1640
1641         struct {
1642                 struct ip6_hdr ip;
1643                 union {
1644                         struct icmp6_hdr icmp;
1645                         struct nd_neighbor_solicit ns;
1646                         struct nd_router_solicit rs;
1647                         struct nd_router_advert ra;
1648                 } i;
1649         } frame;
1650
1651         struct msghdr msgh;
1652         struct cmsghdr *cmsg;
1653         struct in6_pktinfo *pinfo;
1654         struct sockaddr_in6 dst, src;
1655         char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1656         struct iovec iov[2];
1657         int fd, datalen, ret, iovlen = 1;
1658
1659         DBG("");
1660
1661         fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1662         if (fd < 0)
1663                 return -errno;
1664
1665         memset(&frame, 0, sizeof(frame));
1666         memset(&dst, 0, sizeof(dst));
1667
1668         if (type == ND_ROUTER_SOLICIT)
1669                 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1670         else if (type == ND_ROUTER_ADVERT) {
1671                 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1672                 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1673         } else if (type == ND_NEIGHBOR_SOLICIT) {
1674                 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1675                 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1676         } else {
1677                 close(fd);
1678                 return -EINVAL;
1679         }
1680
1681         dst.sin6_addr = *dest;
1682
1683         if (source)
1684                 src.sin6_addr = *source;
1685         else
1686                 src.sin6_addr = in6addr_any;
1687
1688         /* Fill in the IPv6 header */
1689         frame.ip.ip6_vfc = 0x60;
1690         frame.ip.ip6_plen = htons(datalen + len);
1691         frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1692         frame.ip.ip6_hlim = 255;
1693         frame.ip.ip6_dst = dst.sin6_addr;
1694         frame.ip.ip6_src = src.sin6_addr;
1695         /* all other fields are already set to zero */
1696
1697         /* Prepare pseudo header for csum */
1698         memset(&phdr, 0, sizeof(phdr));
1699         phdr.dst = dst.sin6_addr;
1700         phdr.src = src.sin6_addr;
1701         phdr.plen = htonl(datalen + len);
1702         phdr.nxt = IPPROTO_ICMPV6;
1703
1704         /* Fill in remaining ICMP header fields */
1705         frame.i.icmp.icmp6_type = type;
1706         frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1707
1708         iov[0].iov_base = &frame;
1709         iov[0].iov_len = sizeof(frame.ip) + datalen;
1710
1711         if (buf) {
1712                 iov[1].iov_base = buf;
1713                 iov[1].iov_len = len;
1714                 iovlen = 2;
1715         }
1716
1717         dst.sin6_family = AF_INET6;
1718         msgh.msg_name = &dst;
1719         msgh.msg_namelen = sizeof(dst);
1720         msgh.msg_iov = iov;
1721         msgh.msg_iovlen = iovlen;
1722         msgh.msg_flags = 0;
1723
1724         memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1725         cmsg = (struct cmsghdr *)cbuf;
1726         pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1727         pinfo->ipi6_ifindex = oif;
1728
1729         cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1730         cmsg->cmsg_level = IPPROTO_IPV6;
1731         cmsg->cmsg_type = IPV6_PKTINFO;
1732         msgh.msg_control = cmsg;
1733         msgh.msg_controllen = cmsg->cmsg_len;
1734
1735         ret = sendmsg(fd, &msgh, 0);
1736
1737         close(fd);
1738         return ret;
1739 }
1740
1741 static inline void ipv6_addr_set(struct in6_addr *addr,
1742                                 uint32_t w1, uint32_t w2,
1743                                 uint32_t w3, uint32_t w4)
1744 {
1745         addr->s6_addr32[0] = w1;
1746         addr->s6_addr32[1] = w2;
1747         addr->s6_addr32[2] = w3;
1748         addr->s6_addr32[3] = w4;
1749 }
1750
1751 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1752                                         struct in6_addr *solicited)
1753 {
1754         ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1755                         htonl(0xFF000000) | addr->s6_addr32[3]);
1756 }
1757
1758 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1759                                                                 int cmd)
1760 {
1761         unsigned int val = 0;
1762         struct ipv6_mreq mreq;
1763         int ret;
1764
1765         memset(&mreq, 0, sizeof(mreq));
1766         mreq.ipv6mr_interface = ifindex;
1767         mreq.ipv6mr_multiaddr = *mc_addr;
1768
1769         ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1770                         &val, sizeof(int));
1771         if (ret < 0) {
1772                 ret = -errno;
1773                 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1774                         strerror(-ret));
1775                 return ret;
1776         }
1777
1778         ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1779         if (ret < 0) {
1780                 ret = -errno;
1781                 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1782                 return ret;
1783         }
1784
1785         return 0;
1786 }
1787
1788 int __connman_inet_ipv6_send_rs(int index, int timeout,
1789                         __connman_inet_rs_cb_t callback, void *user_data)
1790 {
1791         struct xs_cb_data *data;
1792         struct icmp6_filter filter;
1793         struct in6_addr solicit;
1794         struct in6_addr dst = in6addr_all_routers_mc;
1795         int sk;
1796
1797         if (timeout <= 0)
1798                 return -EINVAL;
1799
1800         data = g_try_malloc0(sizeof(struct xs_cb_data));
1801         if (!data)
1802                 return -ENOMEM;
1803
1804         data->callback = callback;
1805         data->user_data = user_data;
1806         data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1807
1808         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1809         if (sk < 0)
1810                 return -errno;
1811
1812         DBG("sock %d", sk);
1813
1814         ICMP6_FILTER_SETBLOCKALL(&filter);
1815         ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1816
1817         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1818                                                 sizeof(struct icmp6_filter));
1819
1820         ipv6_addr_solict_mult(&dst, &solicit);
1821         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1822         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1823
1824         data->channel = g_io_channel_unix_new(sk);
1825         g_io_channel_set_close_on_unref(data->channel, TRUE);
1826
1827         g_io_channel_set_encoding(data->channel, NULL, NULL);
1828         g_io_channel_set_buffered(data->channel, FALSE);
1829
1830         data->watch_id = g_io_add_watch(data->channel,
1831                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1832                         icmpv6_event, data);
1833
1834         ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1835
1836         return 0;
1837 }
1838
1839 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1840                                         struct in6_addr *advert)
1841 {
1842         ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1843                         htonl(0xFF000000) | addr->s6_addr32[3]);
1844 }
1845
1846 #define MSG_SIZE_SEND 1452
1847
1848 static int inc_len(int len, int inc)
1849 {
1850         if (len > MSG_SIZE_SEND)
1851                 return -EINVAL;
1852
1853         len += inc;
1854         return len;
1855 }
1856
1857 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1858                                 GSList *prefixes, int router_lifetime)
1859 {
1860         GSList *list;
1861         struct in6_addr src, *source;
1862         struct in6_addr dst = in6addr_all_nodes_mc;
1863         GDHCPIAPrefix *prefix;
1864         unsigned char buf[MSG_SIZE_SEND];
1865         char addr_str[INET6_ADDRSTRLEN];
1866         int sk, err = 0;
1867         int len, count = 0;
1868
1869         if (!prefixes)
1870                 return -EINVAL;
1871
1872         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1873         if (sk < 0)
1874                 return -errno;
1875
1876         if (!src_addr) {
1877                 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1878                 source = &src;
1879         } else
1880                 source = src_addr;
1881
1882         DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1883                 prefixes, inet_ntop(AF_INET6, source, addr_str,
1884                                 INET6_ADDRSTRLEN),
1885                 router_lifetime);
1886
1887         memset(buf, 0, MSG_SIZE_SEND);
1888         len = 0;
1889
1890         for (list = prefixes; list; list = list->next) {
1891                 struct nd_opt_prefix_info *pinfo;
1892
1893                 prefix = list->data;
1894                 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1895
1896                 len = inc_len(len, sizeof(*pinfo));
1897                 if (len < 0) {
1898                         err = len;
1899                         goto out;
1900                 }
1901
1902                 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1903                 pinfo->nd_opt_pi_len = 4;
1904                 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1905                 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1906                 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1907                 if (router_lifetime > 0) {
1908                         pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1909                         pinfo->nd_opt_pi_preferred_time =
1910                                                 htonl(prefix->preferred);
1911                 }
1912                 pinfo->nd_opt_pi_reserved2 = 0;
1913
1914                 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1915                                                 sizeof(struct in6_addr));
1916
1917                 DBG("[%d] index %d prefix %s/%d", count, index,
1918                         inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1919                                 INET6_ADDRSTRLEN), prefix->prefixlen);
1920
1921                 count++;
1922         }
1923
1924         if (count > 0) {
1925                 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1926                                         buf, len, router_lifetime);
1927                 if (err < 0)
1928                         DBG("cannot send RA %d/%s", err, strerror(-err));
1929         }
1930
1931 out:
1932         close(sk);
1933         return err;
1934 }
1935
1936 void __connman_inet_ipv6_stop_recv_rs(void *context)
1937 {
1938         if (!context)
1939                 return;
1940
1941         xs_cleanup(context);
1942 }
1943
1944 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1945 {
1946         struct msghdr mhdr;
1947         struct iovec iov;
1948         unsigned char chdr[CMSG_BUF_LEN];
1949         unsigned char buf[1540];
1950         struct nd_router_solicit *hdr;
1951         struct sockaddr_in6 saddr;
1952         ssize_t len;
1953         __connman_inet_recv_rs_cb_t cb = data->callback;
1954
1955         DBG("");
1956
1957         iov.iov_len = sizeof(buf);
1958         iov.iov_base = buf;
1959
1960         mhdr.msg_name = (void *)&saddr;
1961         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1962         mhdr.msg_flags = 0;
1963         mhdr.msg_iov = &iov;
1964         mhdr.msg_iovlen = 1;
1965         mhdr.msg_control = (void *)chdr;
1966         mhdr.msg_controllen = CMSG_BUF_LEN;
1967
1968         len = recvmsg(fd, &mhdr, 0);
1969         if (len < 0) {
1970                 cb(NULL, 0, data->user_data);
1971                 return -errno;
1972         }
1973
1974         hdr = (struct nd_router_solicit *)buf;
1975         DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1976                                 sizeof(struct nd_router_solicit));
1977         if (hdr->nd_rs_code != 0)
1978                 return 0;
1979
1980         cb(hdr, len, data->user_data);
1981         return len;
1982 }
1983
1984 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1985                                                                 gpointer data)
1986 {
1987         int fd, ret;
1988         struct xs_cb_data *xs_data = data;
1989
1990         DBG("");
1991
1992         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1993                 goto cleanup;
1994
1995         fd = g_io_channel_unix_get_fd(chan);
1996         ret = icmpv6_rs_recv(fd, xs_data);
1997         if (ret == 0)
1998                 return TRUE;
1999
2000 cleanup:
2001         xs_data->watch_id = 0;
2002         return FALSE;
2003 }
2004
2005 int __connman_inet_ipv6_start_recv_rs(int index,
2006                                         __connman_inet_recv_rs_cb_t callback,
2007                                         void *user_data,
2008                                         void **context)
2009 {
2010         struct xs_cb_data *data;
2011         struct icmp6_filter filter;
2012         char addr_str[INET6_ADDRSTRLEN];
2013         int sk, err;
2014
2015         data = g_try_malloc0(sizeof(struct xs_cb_data));
2016         if (!data)
2017                 return -ENOMEM;
2018
2019         data->callback = callback;
2020         data->user_data = user_data;
2021
2022         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2023         if (sk < 0) {
2024                 g_free(data);
2025                 return -errno;
2026         }
2027
2028         DBG("sock %d", sk);
2029
2030         ICMP6_FILTER_SETBLOCKALL(&filter);
2031         ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
2032
2033         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2034                                                 sizeof(struct icmp6_filter));
2035
2036         err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
2037         if (err < 0)
2038                 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
2039                         &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
2040                         err, strerror(-err));
2041
2042         data->channel = g_io_channel_unix_new(sk);
2043         g_io_channel_set_close_on_unref(data->channel, TRUE);
2044
2045         g_io_channel_set_encoding(data->channel, NULL, NULL);
2046         g_io_channel_set_buffered(data->channel, FALSE);
2047
2048         data->watch_id = g_io_add_watch(data->channel,
2049                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2050                         icmpv6_rs_event, data);
2051
2052         *context = data;
2053
2054         return 0;
2055 }
2056
2057 static gboolean ns_timeout_cb(gpointer user_data)
2058 {
2059         struct xs_cb_data *data = user_data;
2060
2061         DBG("user data %p", user_data);
2062
2063         if (!data)
2064                 return FALSE;
2065
2066         if (data->callback) {
2067                 __connman_inet_ns_cb_t cb = data->callback;
2068                 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2069         }
2070
2071         data->timeout = 0;
2072         xs_cleanup(data);
2073         return FALSE;
2074 }
2075
2076 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
2077 {
2078         struct msghdr mhdr;
2079         struct iovec iov;
2080         unsigned char chdr[CMSG_BUF_LEN];
2081         unsigned char buf[1540];
2082         struct nd_neighbor_advert *hdr;
2083         struct sockaddr_in6 saddr;
2084         ssize_t len;
2085         __connman_inet_ns_cb_t cb = data->callback;
2086
2087         DBG("");
2088
2089         iov.iov_len = sizeof(buf);
2090         iov.iov_base = buf;
2091
2092         mhdr.msg_name = (void *)&saddr;
2093         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
2094         mhdr.msg_flags = 0;
2095         mhdr.msg_iov = &iov;
2096         mhdr.msg_iovlen = 1;
2097         mhdr.msg_control = (void *)chdr;
2098         mhdr.msg_controllen = CMSG_BUF_LEN;
2099
2100         len = recvmsg(fd, &mhdr, 0);
2101         if (len < 0) {
2102                 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
2103                 return -errno;
2104         }
2105
2106         hdr = (struct nd_neighbor_advert *)buf;
2107         DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
2108                                 sizeof(struct nd_neighbor_advert));
2109         if (hdr->nd_na_code != 0)
2110                 return 0;
2111
2112         /*
2113          * We can receive any neighbor advertisement so we need to check if the
2114          * packet was meant for us and ignore the packet otherwise.
2115          */
2116         if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
2117                         sizeof(struct in6_addr)))
2118                 return 0;
2119
2120         cb(hdr, len, &data->addr.sin6_addr, data->user_data);
2121
2122         return len;
2123 }
2124
2125 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
2126                                                                 gpointer data)
2127 {
2128         int fd, ret;
2129         struct xs_cb_data *xs_data = data;
2130
2131         DBG("");
2132
2133         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2134                 goto cleanup;
2135
2136         fd = g_io_channel_unix_get_fd(chan);
2137         ret = icmpv6_nd_recv(fd, xs_data);
2138         if (ret == 0)
2139                 return TRUE;
2140
2141 cleanup:
2142         xs_cleanup(xs_data);
2143         return TRUE;
2144 }
2145
2146 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
2147                                 struct in6_addr *addr,
2148                                 __connman_inet_ns_cb_t callback,
2149                                 void *user_data)
2150 {
2151         struct xs_cb_data *data;
2152         struct icmp6_filter filter;
2153         struct in6_addr solicit;
2154         int sk, err, val = 1;
2155
2156         if (timeout_ms <= 0)
2157                 return -EINVAL;
2158
2159         data = g_try_malloc0(sizeof(struct xs_cb_data));
2160         if (!data)
2161                 return -ENOMEM;
2162
2163         data->callback = callback;
2164         data->user_data = user_data;
2165         data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
2166                                         (guint)timeout_ms,
2167                                         ns_timeout_cb,
2168                                         data,
2169                                         NULL);
2170         memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
2171
2172         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
2173         if (sk < 0)
2174                 return -errno;
2175
2176         DBG("sock %d", sk);
2177
2178         ICMP6_FILTER_SETBLOCKALL(&filter);
2179         ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
2180
2181         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2182                                                 sizeof(struct icmp6_filter));
2183
2184         if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2185                                                 &val, sizeof(val)) < 0) {
2186                 err = -errno;
2187                 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2188                                                         strerror(-err));
2189                 close(sk);
2190                 return err;
2191         }
2192
2193         if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2194                                                 &val, sizeof(val)) < 0) {
2195                 err = -errno;
2196                 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2197                                                         strerror(-err));
2198                 close(sk);
2199                 return err;
2200         }
2201
2202         val = 0;
2203         setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2204
2205         ipv6_addr_solict_mult(addr, &solicit);
2206         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2207         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2208
2209         data->channel = g_io_channel_unix_new(sk);
2210         g_io_channel_set_close_on_unref(data->channel, TRUE);
2211
2212         g_io_channel_set_encoding(data->channel, NULL, NULL);
2213         g_io_channel_set_buffered(data->channel, FALSE);
2214
2215         data->watch_id = g_io_add_watch(data->channel,
2216                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2217                         icmpv6_nd_event, data);
2218
2219         err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2220                         (unsigned char *)addr, 0, 0);
2221         if (err < 0) {
2222                 DBG("Cannot send NS %d/%s", err, strerror(-err));
2223                 xs_cleanup(data);
2224         }
2225
2226         return err;
2227 }
2228
2229 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2230                                         unsigned int length)
2231 {
2232         GSList *prefixes = NULL;
2233         uint8_t *pos;
2234         int len;
2235
2236         if (length <= sizeof(struct nd_router_advert))
2237                 return NULL;
2238
2239         len = length - sizeof(struct nd_router_advert);
2240         pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2241
2242         while (len > 0) {
2243                 struct nd_opt_prefix_info *pinfo;
2244                 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2245                 const char *prefix;
2246                 int optlen;
2247
2248                 if (len < 2)
2249                         break;
2250
2251                 optlen = pos[1] << 3;
2252                 if (optlen == 0 || optlen > len)
2253                         break;
2254
2255                 switch (pos[0]) {
2256                 case ND_OPT_PREFIX_INFORMATION:
2257                         pinfo = (struct nd_opt_prefix_info *)pos;
2258                         prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2259                                         prefix_str, INET6_ADDRSTRLEN);
2260                         if (!prefix)
2261                                 break;
2262
2263                         str = g_strdup_printf("%s/%d", prefix,
2264                                                 pinfo->nd_opt_pi_prefix_len);
2265                         prefixes = g_slist_prepend(prefixes, str);
2266
2267                         DBG("prefix %s", str);
2268
2269                         break;
2270                 }
2271
2272                 len -= optlen;
2273                 pos += optlen;
2274         }
2275
2276         return prefixes;
2277 }
2278
2279 int connman_inet_get_dest_addr(int index, char **dest)
2280 {
2281         struct interface_address if_addr = { 0 };
2282         struct in_addr dstaddr = { 0 };
2283         char buf[INET_ADDRSTRLEN] = { 0 };
2284         int err;
2285
2286         if (!dest)
2287                 return -EINVAL;
2288
2289         if_addr.index = index;
2290         if_addr.family = AF_INET;
2291         if_addr.allow_unspec = true;
2292         if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dstaddr;
2293
2294         err = get_interface_addresses(&if_addr);
2295         if (err)
2296                 return err;
2297
2298         if (inet_ntop(AF_INET, &dstaddr, buf, INET_ADDRSTRLEN))
2299                 *dest = g_strdup(buf);
2300
2301         DBG("destination %s", *dest);
2302
2303         return *dest && **dest ? 0 : -ENOENT;
2304 }
2305
2306 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2307 {
2308         struct interface_address if_addr = { 0 };
2309         struct in_addr dstaddr = { 0 };
2310         char buf[INET6_ADDRSTRLEN] = { 0 };
2311         int err;
2312
2313         if (!dest)
2314                 return -EINVAL;
2315
2316         if_addr.index = index;
2317         if_addr.family = AF_INET6;
2318         if_addr.allow_unspec = true;
2319         if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dstaddr;
2320
2321         err = get_interface_addresses(&if_addr);
2322         if (err)
2323                 return err;
2324
2325         if (inet_ntop(AF_INET6, &dstaddr, buf, INET6_ADDRSTRLEN))
2326                 *dest = g_strdup(buf);
2327
2328         DBG("destination %s", *dest);
2329
2330         return *dest && **dest ? 0 : -ENOENT;
2331 }
2332
2333 /* destination is optional */
2334 int connman_inet_get_route_addresses(int index, char **network, char **netmask,
2335                                                         char **destination)
2336 {
2337         struct interface_address if_addr = { 0 };
2338         struct in_addr addr = { 0 };
2339         struct in_addr mask = { 0 };
2340         struct in_addr dest = { 0 };
2341         struct in_addr nw_addr = { 0 };
2342         char buf[INET_ADDRSTRLEN] = { 0 };
2343         int err;
2344
2345         if (!network || !netmask)
2346                 return -EINVAL;
2347
2348         if_addr.index = index;
2349         if_addr.family = AF_INET;
2350         if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &addr;
2351         if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &mask;
2352         if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dest;
2353
2354         err = get_interface_addresses(&if_addr);
2355         if (err)
2356                 return err;
2357
2358         nw_addr.s_addr = (addr.s_addr & mask.s_addr);
2359
2360         if (inet_ntop(AF_INET, &nw_addr, buf, INET_ADDRSTRLEN))
2361                 *network = g_strdup(buf);
2362
2363         memset(&buf, 0, INET_ADDRSTRLEN);
2364
2365         if (inet_ntop(AF_INET, &mask, buf, INET_ADDRSTRLEN))
2366                 *netmask = g_strdup(buf);
2367
2368         if (destination) {
2369                 memset(&buf, 0, INET_ADDRSTRLEN);
2370
2371                 if (inet_ntop(AF_INET, &dest, buf, INET_ADDRSTRLEN))
2372                         *destination = g_strdup(buf);
2373         }
2374
2375         DBG("network %s netmask %s destination %s", *network, *netmask,
2376                                 destination ? *destination : NULL);
2377
2378         return *network && **network && *netmask && **netmask ? 0 : -ENOENT;
2379 }
2380
2381 int connman_inet_ipv6_get_route_addresses(int index, char **network,
2382                                         char **netmask, char **destination)
2383 {
2384         struct interface_address if_addr = { 0 };
2385         struct in6_addr addr = { 0 };
2386         struct in6_addr mask = { 0 };
2387         struct in6_addr dest = { 0 };
2388         struct in6_addr nw_addr  = { 0 };
2389         char buf[INET6_ADDRSTRLEN] = { 0 };
2390         int err;
2391
2392         if (!network)
2393                 return -EINVAL;
2394
2395         if_addr.index = index;
2396         if_addr.family = AF_INET6;
2397         if_addr.ipaddrs[ADDR_TYPE_IPADDR] = &addr;
2398         if_addr.ipaddrs[ADDR_TYPE_NETMASK] = &mask;
2399         if_addr.ipaddrs[ADDR_TYPE_DSTADDR] = &dest;
2400
2401         err = get_interface_addresses(&if_addr);
2402         if (err)
2403                 return err;
2404
2405         ipv6_addr_set(&nw_addr, addr.s6_addr32[0] & mask.s6_addr32[0],
2406                                 addr.s6_addr32[1] & mask.s6_addr32[1],
2407                                 addr.s6_addr32[2] & mask.s6_addr32[2],
2408                                 addr.s6_addr32[3] & mask.s6_addr32[3]);
2409
2410         if (inet_ntop(AF_INET6, &nw_addr, buf, INET6_ADDRSTRLEN))
2411                 *network = g_strdup(buf);
2412
2413         memset(&buf, 0, INET6_ADDRSTRLEN);
2414
2415         if (inet_ntop(AF_INET6, &mask, buf, INET6_ADDRSTRLEN))
2416                 *netmask = g_strdup(buf);
2417
2418         if (destination) {
2419                 memset(&buf, 0, INET6_ADDRSTRLEN);
2420
2421                 if (inet_ntop(AF_INET6, &dest, buf, INET6_ADDRSTRLEN))
2422                         *destination = g_strdup(buf);
2423         }
2424
2425         DBG("network %s netmask %s destination %s", *network, *netmask,
2426                                 destination ? *destination : NULL);
2427
2428         return *network && **network && *netmask && **netmask ? 0 : -ENOENT;
2429 }
2430
2431 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2432 {
2433         int sndbuf = 1024;
2434         int rcvbuf = 1024 * 4;
2435
2436         rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2437         if (rth->fd < 0) {
2438                 connman_error("Can not open netlink socket: %s",
2439                                                 strerror(errno));
2440                 return -errno;
2441         }
2442
2443         if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2444                         sizeof(sndbuf)) < 0) {
2445                 connman_error("SO_SNDBUF: %s", strerror(errno));
2446                 return -errno;
2447         }
2448
2449         if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2450                         sizeof(rcvbuf)) < 0) {
2451                 connman_error("SO_RCVBUF: %s", strerror(errno));
2452                 return -errno;
2453         }
2454
2455         memset(&rth->local, 0, sizeof(rth->local));
2456         rth->local.nl_family = AF_NETLINK;
2457         rth->local.nl_groups = 0;
2458
2459         if (bind(rth->fd, (struct sockaddr *)&rth->local,
2460                                                 sizeof(rth->local)) < 0) {
2461                 connman_error("Can not bind netlink socket: %s",
2462                                                         strerror(errno));
2463                 return -errno;
2464         }
2465
2466         rth->seq = time(NULL);
2467
2468         DBG("fd %d", rth->fd);
2469
2470         return 0;
2471 }
2472
2473 struct inet_rtnl_cb_data {
2474         GIOChannel *channel;
2475         __connman_inet_rtnl_cb_t callback;
2476         guint rtnl_timeout;
2477         guint watch_id;
2478         struct __connman_inet_rtnl_handle *rtnl;
2479         void *user_data;
2480 };
2481
2482 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2483 {
2484         struct __connman_inet_rtnl_handle *rth = data->rtnl;
2485
2486         if (data->channel) {
2487                 g_io_channel_shutdown(data->channel, TRUE, NULL);
2488                 g_io_channel_unref(data->channel);
2489                 data->channel = NULL;
2490         }
2491
2492         DBG("data %p", data);
2493
2494         if (data->rtnl_timeout > 0)
2495                 g_source_remove(data->rtnl_timeout);
2496
2497         if (data->watch_id > 0)
2498                 g_source_remove(data->watch_id);
2499
2500         if (rth) {
2501                 __connman_inet_rtnl_close(rth);
2502                 g_free(rth);
2503         }
2504
2505         g_free(data);
2506 }
2507
2508 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2509 {
2510         struct inet_rtnl_cb_data *data = user_data;
2511
2512         DBG("user data %p", user_data);
2513
2514         if (!data)
2515                 return FALSE;
2516
2517         if (data->callback)
2518                 data->callback(NULL, data->user_data);
2519
2520         data->rtnl_timeout = 0;
2521         inet_rtnl_cleanup(data);
2522         return FALSE;
2523 }
2524
2525 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2526 {
2527         struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2528         struct nlmsghdr *h = NULL;
2529         struct sockaddr_nl nladdr;
2530         socklen_t addr_len = sizeof(nladdr);
2531         unsigned char buf[4096];
2532         void *ptr = buf;
2533         gsize len;
2534         int status, fd;
2535
2536         memset(buf, 0, sizeof(buf));
2537         memset(&nladdr, 0, sizeof(nladdr));
2538
2539         fd = g_io_channel_unix_get_fd(chan);
2540
2541         status = recvfrom(fd, buf, sizeof(buf), 0,
2542                        (struct sockaddr *) &nladdr, &addr_len);
2543         if (status < 0) {
2544                 if (errno == EINTR || errno == EAGAIN)
2545                         return 0;
2546
2547                 return -1;
2548         }
2549
2550         if (status == 0)
2551                 return -1;
2552
2553         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2554                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2555                 return 0;
2556         }
2557
2558         len = status;
2559
2560         while (len > 0) {
2561                 struct nlmsgerr *err;
2562
2563                 h = ptr;
2564
2565                 if (!NLMSG_OK(h, len))
2566                         return -1;
2567
2568                 if (h->nlmsg_seq != rth->seq) {
2569                         /* Skip this msg */
2570                         DBG("skip %d/%d len %d", rth->seq,
2571                                 h->nlmsg_seq, h->nlmsg_len);
2572
2573                         len -= h->nlmsg_len;
2574                         ptr += h->nlmsg_len;
2575                         continue;
2576                 }
2577
2578                 switch (h->nlmsg_type) {
2579                 case NLMSG_NOOP:
2580                 case NLMSG_OVERRUN:
2581                         return -1;
2582
2583                 case NLMSG_ERROR:
2584                         err = (struct nlmsgerr *)NLMSG_DATA(h);
2585                         connman_error("RTNETLINK answers %s (%d)",
2586                                 strerror(-err->error), -err->error);
2587                         return err->error;
2588                 }
2589
2590                 break;
2591         }
2592
2593         if (h->nlmsg_seq == rth->seq) {
2594                 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2595
2596                 rtnl_data->callback(h, rtnl_data->user_data);
2597
2598                 inet_rtnl_cleanup(rtnl_data);
2599         }
2600
2601         return 0;
2602 }
2603
2604 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2605                                                         gpointer user_data)
2606 {
2607         int ret;
2608         struct inet_rtnl_cb_data *rtnl_data = user_data;
2609
2610         DBG("");
2611
2612         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2613                 goto cleanup;
2614
2615         ret = inet_rtnl_recv(chan, rtnl_data);
2616         if (ret == 0)
2617                 return TRUE;
2618
2619 cleanup:
2620         rtnl_data->callback(NULL, rtnl_data->user_data);
2621         inet_rtnl_cleanup(rtnl_data);
2622         return TRUE;
2623 }
2624
2625 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2626                         struct nlmsghdr *n, int timeout,
2627                         __connman_inet_rtnl_cb_t callback, void *user_data)
2628 {
2629         struct sockaddr_nl nladdr;
2630         struct inet_rtnl_cb_data *data;
2631         int err;
2632
2633         memset(&nladdr, 0, sizeof(nladdr));
2634         nladdr.nl_family = AF_NETLINK;
2635
2636         n->nlmsg_seq = ++rtnl->seq;
2637
2638         if (callback) {
2639                 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2640                 if (!data)
2641                         return -ENOMEM;
2642
2643                 data->callback = callback;
2644                 data->user_data = user_data;
2645                 data->rtnl = rtnl;
2646                 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2647                                                 inet_rtnl_timeout_cb, data);
2648
2649                 data->channel = g_io_channel_unix_new(rtnl->fd);
2650
2651                 g_io_channel_set_encoding(data->channel, NULL, NULL);
2652                 g_io_channel_set_buffered(data->channel, FALSE);
2653
2654                 data->watch_id = g_io_add_watch(data->channel,
2655                                 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2656                                                 inet_rtnl_event, data);
2657         } else
2658                 n->nlmsg_flags |= NLM_F_ACK;
2659
2660         err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2661                 (struct sockaddr *) &nladdr, sizeof(nladdr));
2662         DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2663         if (err < 0) {
2664                 connman_error("Can not talk to rtnetlink err %d %s",
2665                         -errno, strerror(errno));
2666                 return -errno;
2667         }
2668
2669         if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2670                 connman_error("Sent %d bytes, msg truncated", err);
2671                 return -EINVAL;
2672         }
2673
2674         return 0;
2675 }
2676
2677 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2678 {
2679         DBG("handle %p", rth);
2680
2681         if (rth->fd >= 0) {
2682                 close(rth->fd);
2683                 rth->fd = -1;
2684         }
2685 }
2686
2687 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2688                                 __u32 data)
2689 {
2690         int len = RTA_LENGTH(4);
2691         struct rtattr *rta;
2692
2693         if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2694                 DBG("Error! max allowed bound %zd exceeded", maxlen);
2695                 return -1;
2696         }
2697         rta = NLMSG_TAIL(n);
2698         rta->rta_type = type;
2699         rta->rta_len = len;
2700         memcpy(RTA_DATA(rta), &data, 4);
2701         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2702
2703         return 0;
2704 }
2705
2706 static int parse_rtattr(struct rtattr *tb[], int max,
2707                         struct rtattr *rta, int len)
2708 {
2709         memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2710         while (RTA_OK(rta, len)) {
2711                 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2712                         tb[rta->rta_type] = rta;
2713                 rta = RTA_NEXT(rta, len);
2714         }
2715         if (len)
2716                 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2717
2718         return 0;
2719 }
2720
2721 struct get_route_cb_data {
2722         connman_inet_addr_cb_t callback;
2723         void *user_data;
2724 };
2725
2726 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2727 {
2728         struct get_route_cb_data *data = user_data;
2729         struct rtattr *tb[RTA_MAX+1];
2730         struct rtmsg *r = NLMSG_DATA(answer);
2731         int len, index = -1;
2732         char abuf[256];
2733         const char *addr = NULL;
2734
2735         DBG("answer %p data %p", answer, user_data);
2736
2737         if (!answer)
2738                 goto out;
2739
2740         len = answer->nlmsg_len;
2741
2742         if (answer->nlmsg_type != RTM_NEWROUTE &&
2743                                 answer->nlmsg_type != RTM_DELROUTE) {
2744                 connman_error("Not a route: %08x %08x %08x",
2745                         answer->nlmsg_len, answer->nlmsg_type,
2746                         answer->nlmsg_flags);
2747                 goto out;
2748         }
2749
2750         len -= NLMSG_LENGTH(sizeof(*r));
2751         if (len < 0) {
2752                 connman_error("BUG: wrong nlmsg len %d", len);
2753                 goto out;
2754         }
2755
2756         parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2757
2758         if (tb[RTA_OIF])
2759                 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2760
2761         if (tb[RTA_GATEWAY])
2762                 addr = inet_ntop(r->rtm_family,
2763                                 RTA_DATA(tb[RTA_GATEWAY]),
2764                                 abuf, sizeof(abuf));
2765
2766         DBG("addr %s index %d user %p", addr, index, data->user_data);
2767
2768 out:
2769         if (data && data->callback)
2770                 data->callback(addr, index, data->user_data);
2771
2772         g_free(data);
2773 }
2774
2775 /*
2776  * Return the interface index that contains route to host.
2777  */
2778 int __connman_inet_get_route(const char *dest_address,
2779                         connman_inet_addr_cb_t callback, void *user_data)
2780 {
2781         struct get_route_cb_data *data;
2782         struct addrinfo hints, *rp;
2783         struct __connman_inet_rtnl_handle *rth;
2784         int err;
2785
2786         DBG("dest %s", dest_address);
2787
2788         if (!dest_address)
2789                 return -EINVAL;
2790
2791         memset(&hints, 0, sizeof(hints));
2792         hints.ai_family = AF_UNSPEC;
2793         hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2794
2795         err = getaddrinfo(dest_address, NULL, &hints, &rp);
2796         if (err)
2797                 return -EINVAL;
2798
2799         rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2800         if (!rth) {
2801                 freeaddrinfo(rp);
2802                 return -ENOMEM;
2803         }
2804
2805         rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2806         rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2807         rth->req.n.nlmsg_type = RTM_GETROUTE;
2808         rth->req.u.r.rt.rtm_family = rp->ai_family;
2809         rth->req.u.r.rt.rtm_table = 0;
2810         rth->req.u.r.rt.rtm_protocol = 0;
2811         rth->req.u.r.rt.rtm_scope = 0;
2812         rth->req.u.r.rt.rtm_type = 0;
2813         rth->req.u.r.rt.rtm_src_len = 0;
2814         rth->req.u.r.rt.rtm_tos = 0;
2815
2816         if (rp->ai_family == AF_INET) {
2817                 struct sockaddr_in *sin = (struct sockaddr_in *)rp->ai_addr;
2818
2819                 rth->req.u.r.rt.rtm_dst_len = 32;
2820                 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2821                         RTA_DST, &sin->sin_addr, sizeof(sin->sin_addr));
2822         } else if (rp->ai_family == AF_INET6) {
2823                 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)rp->ai_addr;
2824
2825                 rth->req.u.r.rt.rtm_dst_len = 128;
2826                 __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req),
2827                         RTA_DST, &sin6->sin6_addr, sizeof(sin6->sin6_addr));
2828         }
2829
2830         freeaddrinfo(rp);
2831
2832         err = __connman_inet_rtnl_open(rth);
2833         if (err < 0)
2834                 goto fail;
2835
2836         data = g_try_malloc(sizeof(struct get_route_cb_data));
2837         if (!data) {
2838                 err = -ENOMEM;
2839                 goto done;
2840         }
2841
2842         data->callback = callback;
2843         data->user_data = user_data;
2844
2845 #define GET_ROUTE_TIMEOUT 2
2846         err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2847                                 get_route_cb, data);
2848         if (err < 0) {
2849                 g_free(data);
2850                 goto done;
2851         }
2852
2853         return 0;
2854
2855 done:
2856         __connman_inet_rtnl_close(rth);
2857
2858 fail:
2859         g_free(rth);
2860         return err;
2861 }
2862
2863 int connman_inet_check_ipaddress(const char *host)
2864 {
2865         struct addrinfo hints;
2866         struct addrinfo *addr;
2867         int result;
2868
2869         memset(&hints, 0, sizeof(struct addrinfo));
2870         hints.ai_flags = AI_NUMERICHOST;
2871         addr = NULL;
2872
2873         result = getaddrinfo(host, NULL, &hints, &addr);
2874         if (result == 0) {
2875                 result = addr->ai_family;
2876                 freeaddrinfo(addr);
2877         }
2878
2879         return result;
2880 }
2881
2882 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2883 bool connman_inet_check_hostname(const char *ptr, size_t len)
2884 {
2885         const char *p;
2886
2887         /*
2888          * Not empty or complete length not over 255 characters.
2889          */
2890         if ((len == 0) || (len > 256))
2891                 return false;
2892
2893         /*
2894          * Consists of [[:alnum:]-]+ labels separated by [.]
2895          * a [_] is against RFC but seems to be "widely used"
2896          */
2897         for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2898
2899                 if ((*p == '-') || (*p == '_')) {
2900                         /*
2901                          * Not allowed at begin or end of a label.
2902                          */
2903                         if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2904                                 return false;
2905
2906                 } else if (*p == '.') {
2907                         /*
2908                          * Each label has to be 1-63 characters;
2909                          * we allow [.] at the end ('foo.bar.')
2910                          */
2911                         size_t d = p - ptr;
2912
2913                         if ((d <= 0) || (d >= 64))
2914                                 return false;
2915
2916                         ptr = p + 1; /* Jump to the next label */
2917
2918                 } else if (isalnum((unsigned char)*p) == 0) {
2919                         /*
2920                          * Also numbers at the begin are fine
2921                          */
2922                         return false;
2923                 }
2924         }
2925
2926         return true;
2927 }
2928
2929 char **__connman_inet_get_running_interfaces(void)
2930 {
2931         char **result;
2932         struct ifconf ifc;
2933         struct ifreq *ifr = NULL;
2934         int sk, i, numif, count = 0;
2935
2936         memset(&ifc, 0, sizeof(ifc));
2937
2938         sk = socket(AF_INET, SOCK_DGRAM, 0);
2939         if (sk < 0)
2940                 return NULL;
2941
2942         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2943                 goto error;
2944
2945         /*
2946          * Allocate some extra bytes just in case there will
2947          * be new interfaces added between two SIOCGIFCONF
2948          * calls.
2949          */
2950         ifr = g_try_malloc0(ifc.ifc_len * 2);
2951         if (!ifr)
2952                 goto error;
2953
2954         ifc.ifc_req = ifr;
2955
2956         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2957                 goto error;
2958
2959         numif = ifc.ifc_len / sizeof(struct ifreq);
2960
2961         result = g_try_malloc0((numif + 1) * sizeof(char *));
2962         if (!result)
2963                 goto error;
2964
2965         close(sk);
2966
2967         for (i = 0; i < numif; i++) {
2968                 struct ifreq *r = &ifr[i];
2969                 struct in6_addr *addr6;
2970                 in_addr_t addr4;
2971
2972                 /*
2973                  * Note that we do not return loopback interfaces here as they
2974                  * are not needed for our purposes.
2975                  */
2976                 switch (r->ifr_addr.sa_family) {
2977                 case AF_INET:
2978                         addr4 = ntohl(((struct sockaddr_in *)
2979                                                 &r->ifr_addr)->sin_addr.s_addr);
2980                         if (((addr4 & 0xff000000) >> 24) == 127)
2981                                 continue;
2982                         break;
2983                 case AF_INET6:
2984                         addr6 = &((struct sockaddr_in6 *)
2985                                                 &r->ifr_addr)->sin6_addr;
2986                         if (IN6_IS_ADDR_LINKLOCAL(addr6))
2987                                 continue;
2988                         break;
2989                 }
2990
2991                 result[count++] = g_strdup(r->ifr_name);
2992         }
2993
2994         g_free(ifr);
2995
2996         if (count < numif) {
2997                 char **prev_result = result;
2998                 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2999                 if (!result) {
3000                         g_free(prev_result);
3001                         return NULL;
3002                 }
3003         }
3004
3005         return result;
3006
3007 error:
3008         close(sk);
3009         g_free(ifr);
3010         return NULL;
3011 }
3012
3013 bool connman_inet_is_ipv6_supported()
3014 {
3015         int sk;
3016
3017         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3018         if (sk < 0)
3019                 return false;
3020
3021         close(sk);
3022         return true;
3023 }
3024
3025 /*
3026  * Omits checking of the gateway matching the actual gateway IP since both
3027  * connmand and vpnd use inet.c, getting the route is via ipconfig and ipconfig
3028  * is different for both. Gateway is left here for possible future use.
3029  *
3030  * Gateway can be NULL and connection.c then assigns 0.0.0.0 address or ::,
3031  * depending on IP family.
3032  */
3033 bool connman_inet_is_default_route(int family, const char *host,
3034                                 const char *gateway, const char *netmask)
3035 {
3036         return __connman_inet_is_any_addr(host, family) &&
3037                                 __connman_inet_is_any_addr(netmask, family);
3038 }
3039
3040 int __connman_inet_get_interface_address(int index, int family, void *address)
3041 {
3042         struct interface_address if_addr = { 0 };
3043
3044         if_addr.index = index;
3045         if_addr.family = family;
3046         if_addr.ipaddrs[ADDR_TYPE_IPADDR] = address;
3047
3048         return get_interface_addresses(&if_addr);
3049 }
3050
3051 int __connman_inet_get_interface_mac_address(int index, uint8_t *mac_address)
3052 {
3053         struct ifreq ifr;
3054         int sk, err;
3055         int ret = -EINVAL;
3056
3057         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3058         if (sk < 0) {
3059                 DBG("Open socket error");
3060                 return ret;
3061         }
3062
3063         memset(&ifr, 0, sizeof(ifr));
3064         ifr.ifr_ifindex = index;
3065
3066         err = ioctl(sk, SIOCGIFNAME, &ifr);
3067         if (err < 0) {
3068                 DBG("Get interface name error");
3069                 goto done;
3070         }
3071
3072         err = ioctl(sk, SIOCGIFHWADDR, &ifr);
3073         if (err < 0) {
3074                 DBG("Get MAC address error");
3075                 goto done;
3076         }
3077
3078         memcpy(mac_address, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
3079         ret = 0;
3080
3081 done:
3082         close(sk);
3083         return ret;
3084 }
3085
3086 static int iprule_modify(int cmd, int family, uint32_t table_id,
3087                         uint32_t fwmark)
3088 {
3089         struct __connman_inet_rtnl_handle rth;
3090         int ret;
3091
3092         memset(&rth, 0, sizeof(rth));
3093
3094         rth.req.n.nlmsg_type = cmd;
3095         rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3096         rth.req.n.nlmsg_flags = NLM_F_REQUEST;
3097         rth.req.u.r.rt.rtm_family = family;
3098         rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3099         rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3100         rth.req.u.r.rt.rtm_table = table_id;
3101         rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
3102         rth.req.u.r.rt.rtm_flags = 0;
3103
3104         if (cmd == RTM_NEWRULE) {
3105                 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
3106                 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3107         }
3108
3109         __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3110                                                         FRA_FWMARK, fwmark);
3111
3112         if (table_id < 256) {
3113                 rth.req.u.r.rt.rtm_table = table_id;
3114         } else {
3115                 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3116                 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3117                                                 FRA_TABLE, table_id);
3118         }
3119
3120         if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
3121                 rth.req.u.r.rt.rtm_family = AF_INET;
3122
3123         ret = __connman_inet_rtnl_open(&rth);
3124         if (ret < 0)
3125                 goto done;
3126
3127         ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3128
3129 done:
3130         __connman_inet_rtnl_close(&rth);
3131
3132         return ret;
3133 }
3134
3135 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3136 {
3137         /* ip rule add fwmark 9876 table 1234 */
3138
3139         return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
3140 }
3141
3142 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
3143 {
3144         return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
3145 }
3146
3147 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
3148                         const char *gateway, unsigned char prefixlen)
3149 {
3150         struct __connman_inet_rtnl_handle rth;
3151         unsigned char buf[sizeof(struct in6_addr)];
3152         int ret, len;
3153         int family = connman_inet_check_ipaddress(gateway);
3154         char *dst = NULL;
3155
3156         DBG("gateway %s/%u table %u", gateway, prefixlen, table_id);
3157
3158         switch (family) {
3159         case AF_INET:
3160                 len = 4;
3161                 break;
3162         case AF_INET6:
3163                 len = 16;
3164                 break;
3165         default:
3166                 return -EINVAL;
3167         }
3168
3169         if (prefixlen) {
3170                 struct in_addr ipv4_subnet_addr, ipv4_mask;
3171
3172                 memset(&ipv4_subnet_addr, 0, sizeof(ipv4_subnet_addr));
3173                 ipv4_mask.s_addr = htonl((0xffffffff << (32 - prefixlen)) & 0xffffffff);
3174                 ipv4_subnet_addr.s_addr = inet_addr(gateway);
3175                 ipv4_subnet_addr.s_addr &= ipv4_mask.s_addr;
3176
3177                 dst = g_strdup(inet_ntoa(ipv4_subnet_addr));
3178         }
3179
3180         ret = inet_pton(family, dst ? dst : gateway, buf);
3181         g_free(dst);
3182         if (ret != 1)
3183                 return -EINVAL;
3184
3185         memset(&rth, 0, sizeof(rth));
3186
3187         rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
3188         rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
3189         rth.req.n.nlmsg_type = cmd;
3190         rth.req.u.r.rt.rtm_family = family;
3191         rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
3192         rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
3193         rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
3194         rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
3195         rth.req.u.r.rt.rtm_type = RTN_UNICAST;
3196         rth.req.u.r.rt.rtm_dst_len = prefixlen;
3197
3198         __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req),
3199                 prefixlen > 0 ? RTA_DST : RTA_GATEWAY, buf, len);
3200
3201         if (table_id < 256) {
3202                 rth.req.u.r.rt.rtm_table = table_id;
3203         } else {
3204                 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
3205                 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3206                                                         RTA_TABLE, table_id);
3207         }
3208
3209         __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
3210                                                         RTA_OIF, ifindex);
3211
3212         ret = __connman_inet_rtnl_open(&rth);
3213         if (ret < 0)
3214                 goto done;
3215
3216         ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
3217
3218 done:
3219         __connman_inet_rtnl_close(&rth);
3220
3221         return ret;
3222 }
3223
3224 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
3225                                                 const char *gateway)
3226 {
3227         /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
3228
3229         return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 0);
3230 }
3231
3232 int __connman_inet_add_subnet_to_table(uint32_t table_id, int ifindex,
3233                                                 const char *gateway, unsigned char prefixlen)
3234 {
3235         /* ip route add 1.2.3.4/24 dev eth0 table 1234 */
3236         return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, prefixlen);
3237 }
3238
3239 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
3240                                                 const char *gateway)
3241 {
3242         /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
3243
3244         return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 0);
3245 }
3246
3247 int __connman_inet_del_subnet_from_table(uint32_t table_id, int ifindex,
3248                                                 const char *gateway, unsigned char prefixlen)
3249 {
3250         /* ip route del 1.2.3.4/24 dev eth0 table 1234 */
3251         return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, prefixlen);
3252 }
3253
3254 int __connman_inet_get_interface_ll_address(int index, int family,
3255                                                                 void *address)
3256 {
3257         struct interface_address if_addr = { 0 };
3258
3259         if_addr.index = index;
3260         if_addr.family = family;
3261         if_addr.require_ll = true;
3262         if_addr.ipaddrs[ADDR_TYPE_IPADDR] = address;
3263
3264         return get_interface_addresses(&if_addr);
3265 }
3266
3267 int __connman_inet_get_address_netmask(int ifindex,
3268                                         struct sockaddr_in *address,
3269                                         struct sockaddr_in *netmask)
3270 {
3271         int sk, ret = -EINVAL;
3272         struct ifreq ifr;
3273
3274         DBG("index %d", ifindex);
3275
3276         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3277         if (sk < 0)
3278                 return -EINVAL;
3279
3280         memset(&ifr, 0, sizeof(ifr));
3281         ifr.ifr_ifindex = ifindex;
3282
3283         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3284                 goto out;
3285
3286         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3287                 goto out;
3288
3289         memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3290                                                 sizeof(struct sockaddr_in));
3291
3292         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3293                 goto out;
3294
3295         memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3296                                                 sizeof(struct sockaddr_in));
3297         ret = 0;
3298
3299 out:
3300         close(sk);
3301         return ret;
3302 }
3303
3304 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3305                                 struct in_addr *addr)
3306 {
3307         char *s, *nfsargs;
3308         size_t len;
3309         char addrstr[INET_ADDRSTRLEN];
3310         struct in_addr taddr;
3311         GError *error = NULL;
3312         char *cmdline = NULL;
3313         char *pnp = NULL;
3314         char **args = NULL;
3315         char **pnpent = NULL;
3316         char **pp = NULL;
3317         int err = -1;
3318
3319         if (!cmdline_file)
3320                 cmdline_file = "/proc/cmdline";
3321         if (!pnp_file)
3322                 pnp_file = "/proc/net/pnp";
3323         if (!addr)
3324                 addr = &taddr;
3325         addr->s_addr = INADDR_NONE;
3326
3327         if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3328                 connman_error("%s: Cannot read %s %s\n", __func__,
3329                                 cmdline_file, error->message);
3330                 goto out;
3331         }
3332
3333         if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3334                 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3335                         connman_error("%s: Cannot read %s %s\n", __func__,
3336                                                   pnp_file, error->message);
3337                         goto out;
3338                 }
3339         } else
3340                 goto out;
3341
3342         len = strlen(cmdline);
3343         if (len <= 1) {
3344                 /* too short */
3345                 goto out;
3346         }
3347         /* remove newline */
3348         if (cmdline[len - 1] == '\n')
3349                 cmdline[--len] = '\0';
3350
3351         /* split in arguments (separated by space) */
3352         args = g_strsplit(cmdline, " ", 0);
3353         if (!args) {
3354                 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3355                                 cmdline);
3356                 goto out;
3357         }
3358
3359         /* split in entries (by newlines) */
3360         pnpent = g_strsplit(pnp, "\n", 0);
3361         if (!pnpent) {
3362                 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3363                                 pnp_file);
3364                 goto out;
3365         }
3366
3367         /* first find root argument */
3368         for (pp = args; *pp; pp++) {
3369                 if (!strcmp(*pp, "root=/dev/nfs"))
3370                         break;
3371         }
3372         /* no rootnfs found */
3373         if (!*pp)
3374                 goto out;
3375
3376         /* locate nfsroot argument */
3377         for (pp = args; *pp; pp++) {
3378                 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3379                         break;
3380         }
3381         /* no nfsroot argument found */
3382         if (!*pp)
3383                 goto out;
3384
3385         /* determine if nfsroot server is provided */
3386         nfsargs = strchr(*pp, '=');
3387         if (!nfsargs)
3388                 goto out;
3389         nfsargs++;
3390
3391         /* find whether serverip is present */
3392         s = strchr(nfsargs, ':');
3393         if (s) {
3394                 len = s - nfsargs;
3395                 s = nfsargs;
3396         } else {
3397                 /* no serverip, use bootserver */
3398                 for (pp = pnpent; *pp; pp++) {
3399                         if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3400                                 break;
3401                 }
3402                 /* no bootserver found */
3403                 if (!*pp)
3404                         goto out;
3405                 s = *pp + strlen("bootserver ");
3406                 len = strlen(s);
3407         }
3408
3409         /* copy to addr string buffer */
3410         if (len >= sizeof(addrstr)) {
3411                 connman_error("%s: Bad server\n", __func__);
3412                 goto out;
3413         }
3414         memcpy(addrstr, s, len);
3415         addrstr[len] = '\0';
3416
3417         err = inet_pton(AF_INET, addrstr, addr);
3418         if (err != 1) {
3419                 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3420                                 __func__, addrstr);
3421                 err = -1;
3422                 goto out;
3423         }
3424
3425         /* all done */
3426         err = 0;
3427 out:
3428         g_strfreev(pnpent);
3429         g_strfreev(args);
3430         if (error)
3431                 g_error_free(error);
3432         g_free(pnp);
3433         g_free(cmdline);
3434
3435         return err;
3436 }
3437
3438 /* get interface out of which peer is reachable (IPv4 only) */
3439 static int get_peer_iface(struct in_addr *addr, char *ifname)
3440 {
3441         struct ifaddrs *ifaddr, *ifa;
3442         struct sockaddr_in saddr, *ifsaddr;
3443         socklen_t socklen;
3444         int s;
3445         int err = -1;
3446
3447         /* Obtain address(es) matching host/port */
3448         err = getifaddrs(&ifaddr);
3449         if (err < 0) {
3450                 connman_error("%s: getifaddrs() failed %d (%s)\n",
3451                                 __func__, errno, strerror(errno));
3452                 return -1;
3453         }
3454
3455         s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3456         if (s < 0) {
3457                 connman_error("%s: socket() failed %d (%s)\n",
3458                                 __func__, errno, strerror(errno));
3459                 return -1;
3460         }
3461
3462         memset(&saddr, 0, sizeof(saddr));
3463         saddr.sin_family = AF_INET;
3464         saddr.sin_port = 0;     /* any port */
3465         saddr.sin_addr = *addr;
3466
3467         /* no need to bind, connect will select iface */
3468         err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3469         if (err < 0) {
3470                 connman_error("%s: connect() failed: %d (%s)\n",
3471                                 __func__, errno, strerror(errno));
3472                 goto out;
3473         }
3474
3475         socklen = sizeof(saddr);
3476         err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3477         if (err < 0) {
3478                 connman_error("%s: getsockname() failed: %d (%s)\n",
3479                                 __func__, errno, strerror(errno));
3480                 goto out;
3481         }
3482
3483         err = -1;
3484         for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3485                 if (!ifa->ifa_addr)
3486                         continue;
3487
3488                 /* only IPv4 address */
3489                 if (ifa->ifa_addr->sa_family != AF_INET)
3490                         continue;
3491
3492                 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3493
3494                 /* match address? */
3495                 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3496                         break;
3497         }
3498
3499         if (ifa) {
3500                 err = 0;
3501                 if (ifname)
3502                         strcpy(ifname, ifa->ifa_name);
3503         }
3504
3505 out:
3506         close(s);
3507
3508         freeifaddrs(ifaddr);
3509
3510         return err;
3511 }
3512
3513 bool __connman_inet_isrootnfs_device(const char *devname)
3514 {
3515         struct in_addr addr;
3516         char ifname[IFNAMSIZ];
3517
3518         return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3519                get_peer_iface(&addr, ifname) == 0 &&
3520                strcmp(devname, ifname) == 0;
3521 }
3522
3523 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3524 {
3525         char **pp;
3526         char *s;
3527         int pass, count;
3528         GError *error = NULL;
3529         char *pnp = NULL;
3530         char **pnpent = NULL;
3531         char **nameservers = NULL;
3532
3533         if (!pnp_file)
3534                 pnp_file = "/proc/net/pnp";
3535
3536         if (!g_file_test(pnp_file, G_FILE_TEST_EXISTS))
3537                 goto out;
3538
3539         if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3540                 connman_error("%s: Cannot read %s %s\n", __func__,
3541                                 pnp_file, error->message);
3542                 goto out;
3543         }
3544
3545         /* split in entries (by newlines) */
3546         pnpent = g_strsplit(pnp, "\n", 0);
3547         if (!pnpent) {
3548                 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3549                                 pnp_file);
3550                 goto out;
3551         }
3552
3553         /*
3554          * Perform two passes to retrieve a char ** array of
3555          * nameservers that are not 0.0.0.0
3556          *
3557          * The first pass counts them, the second fills in the
3558          * array.
3559          */
3560         count = 0;
3561         nameservers = NULL;
3562         for (pass = 1; pass <= 2; pass++) {
3563
3564                 /* at the start of the second pass allocate */
3565                 if (pass == 2)
3566                         nameservers = g_new(char *, count + 1);
3567
3568                 count = 0;
3569                 for (pp = pnpent; *pp; pp++) {
3570                         /* match 'nameserver ' at the start of each line */
3571                         if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3572                                 continue;
3573
3574                         /* compare it against 0.0.0.0 */
3575                         s = *pp + strlen("nameserver ");
3576                         if (!strcmp(s, "0.0.0.0"))
3577                                 continue;
3578
3579                         /* on second pass fill in array */
3580                         if (pass == 2)
3581                                 nameservers[count] = g_strdup(s);
3582                         count++;
3583                 }
3584
3585                 /* no nameservers? */
3586                 if (count == 0)
3587                         goto out;
3588
3589                 /* and terminate char ** array with NULL */
3590                 if (pass == 2)
3591                         nameservers[count] = NULL;
3592
3593         }
3594
3595 out:
3596         g_strfreev(pnpent);
3597         g_free(pnp);
3598         if (error)
3599                 g_error_free(error);
3600
3601         return nameservers;
3602 }