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