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