inet: Fix debugging prints
[framework/connectivity/connman.git] / src / inet.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  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 <arpa/inet.h>
39 #include <net/route.h>
40 #include <net/ethernet.h>
41 #include <net/if.h>
42 #include <net/if_arp.h>
43 #include <netinet/icmp6.h>
44 #include <fcntl.h>
45 #include <linux/if_tun.h>
46
47 #include "connman.h"
48
49 #define NLMSG_TAIL(nmsg)                                \
50         ((struct rtattr *) (((uint8_t*) (nmsg)) +       \
51         NLMSG_ALIGN((nmsg)->nlmsg_len)))
52
53 static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
54                                 const void *data, size_t data_length)
55 {
56         size_t length;
57         struct rtattr *rta;
58
59         length = RTA_LENGTH(data_length);
60
61         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
62                 return -E2BIG;
63
64         rta = NLMSG_TAIL(n);
65         rta->rta_type = type;
66         rta->rta_len = length;
67         memcpy(RTA_DATA(rta), data, data_length);
68         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
69
70         return 0;
71 }
72
73 int __connman_inet_modify_address(int cmd, int flags,
74                                 int index, int family,
75                                 const char *address,
76                                 const char *peer,
77                                 unsigned char prefixlen,
78                                 const char *broadcast)
79 {
80         uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
81                         NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
82                         RTA_LENGTH(sizeof(struct in6_addr)) +
83                         RTA_LENGTH(sizeof(struct in6_addr))];
84
85         struct nlmsghdr *header;
86         struct sockaddr_nl nl_addr;
87         struct ifaddrmsg *ifaddrmsg;
88         struct in6_addr ipv6_addr;
89         struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
90         int sk, err;
91
92         DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
93                 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
94                 address, peer, prefixlen, broadcast);
95
96         if (address == NULL)
97                 return -EINVAL;
98
99         if (family != AF_INET && family != AF_INET6)
100                 return -EINVAL;
101
102         memset(&request, 0, sizeof(request));
103
104         header = (struct nlmsghdr *)request;
105         header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
106         header->nlmsg_type = cmd;
107         header->nlmsg_flags = NLM_F_REQUEST | flags;
108         header->nlmsg_seq = 1;
109
110         ifaddrmsg = NLMSG_DATA(header);
111         ifaddrmsg->ifa_family = family;
112         ifaddrmsg->ifa_prefixlen = prefixlen;
113         ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
114         ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
115         ifaddrmsg->ifa_index = index;
116
117         if (family == AF_INET) {
118                 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
119                         return -1;
120
121                 if (broadcast != NULL)
122                         inet_pton(AF_INET, broadcast, &ipv4_bcast);
123                 else
124                         ipv4_bcast.s_addr = ipv4_addr.s_addr |
125                                 htonl(0xfffffffflu >> prefixlen);
126
127                 if (peer != NULL) {
128                         if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
129                                 return -1;
130
131                         if ((err = add_rtattr(header, sizeof(request),
132                                         IFA_ADDRESS,
133                                         &ipv4_dest, sizeof(ipv4_dest))) < 0)
134                         return err;
135                 }
136
137                 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
138                                 &ipv4_addr, sizeof(ipv4_addr))) < 0)
139                         return err;
140
141                 if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
142                                 &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
143                         return err;
144
145         } else if (family == AF_INET6) {
146                 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
147                         return -1;
148
149                 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
150                                 &ipv6_addr, sizeof(ipv6_addr))) < 0)
151                         return err;
152         }
153
154         sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
155         if (sk < 0)
156                 return -errno;
157
158         memset(&nl_addr, 0, sizeof(nl_addr));
159         nl_addr.nl_family = AF_NETLINK;
160
161         if ((err = sendto(sk, request, header->nlmsg_len, 0,
162                         (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
163                 goto done;
164
165         err = 0;
166
167 done:
168         close(sk);
169
170         return err;
171 }
172
173 int connman_inet_ifindex(const char *name)
174 {
175         struct ifreq ifr;
176         int sk, err;
177
178         if (name == NULL)
179                 return -1;
180
181         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
182         if (sk < 0)
183                 return -1;
184
185         memset(&ifr, 0, sizeof(ifr));
186         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
187
188         err = ioctl(sk, SIOCGIFINDEX, &ifr);
189
190         close(sk);
191
192         if (err < 0)
193                 return -1;
194
195         return ifr.ifr_ifindex;
196 }
197
198 char *connman_inet_ifname(int index)
199 {
200         struct ifreq ifr;
201         int sk, err;
202
203         if (index < 0)
204                 return NULL;
205
206         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
207         if (sk < 0)
208                 return NULL;
209
210         memset(&ifr, 0, sizeof(ifr));
211         ifr.ifr_ifindex = index;
212
213         err = ioctl(sk, SIOCGIFNAME, &ifr);
214
215         close(sk);
216
217         if (err < 0)
218                 return NULL;
219
220         return strdup(ifr.ifr_name);
221 }
222
223 short int connman_inet_ifflags(int index)
224 {
225         struct ifreq ifr;
226         int sk, err;
227
228         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
229         if (sk < 0)
230                 return -errno;
231
232         memset(&ifr, 0, sizeof(ifr));
233         ifr.ifr_ifindex = index;
234
235         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
236                 err = -errno;
237                 goto done;
238         }
239
240         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
241                 err = -errno;
242                 goto done;
243         }
244
245         err = ifr.ifr_flags;
246
247 done:
248         close(sk);
249
250         return err;
251 }
252
253 int connman_inet_ifup(int index)
254 {
255         struct ifreq ifr;
256         int sk, err;
257
258         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
259         if (sk < 0)
260                 return -errno;
261
262         memset(&ifr, 0, sizeof(ifr));
263         ifr.ifr_ifindex = index;
264
265         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
266                 err = -errno;
267                 goto done;
268         }
269
270         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
271                 err = -errno;
272                 goto done;
273         }
274
275         if (ifr.ifr_flags & IFF_UP) {
276                 err = -EALREADY;
277                 goto done;
278         }
279
280         ifr.ifr_flags |= IFF_UP;
281
282         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
283                 err = -errno;
284                 goto done;
285         }
286
287         err = 0;
288
289 done:
290         close(sk);
291
292         return err;
293 }
294
295 int connman_inet_ifdown(int index)
296 {
297         struct ifreq ifr;
298         int sk, err;
299
300         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
301         if (sk < 0)
302                 return -errno;
303
304         memset(&ifr, 0, sizeof(ifr));
305         ifr.ifr_ifindex = index;
306
307         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
308                 err = -errno;
309                 goto done;
310         }
311
312         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
313                 err = -errno;
314                 goto done;
315         }
316
317         if (!(ifr.ifr_flags & IFF_UP)) {
318                 err = -EALREADY;
319                 goto done;
320         }
321
322         ifr.ifr_flags &= ~IFF_UP;
323
324         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
325                 err = -errno;
326         else
327                 err = 0;
328
329 done:
330         close(sk);
331
332         return err;
333 }
334
335 static char *index2addr(int index)
336 {
337         struct ifreq ifr;
338         struct ether_addr eth;
339         char *str;
340         int sk, err;
341
342         if (index < 0)
343                 return NULL;
344
345         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
346         if (sk < 0)
347                 return NULL;
348
349         memset(&ifr, 0, sizeof(ifr));
350         ifr.ifr_ifindex = index;
351
352         err = ioctl(sk, SIOCGIFNAME, &ifr);
353
354         if (err == 0)
355                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
356
357         close(sk);
358
359         if (err < 0)
360                 return NULL;
361
362         str = malloc(18);
363         if (!str)
364                 return NULL;
365
366         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
367         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
368                                                 eth.ether_addr_octet[0],
369                                                 eth.ether_addr_octet[1],
370                                                 eth.ether_addr_octet[2],
371                                                 eth.ether_addr_octet[3],
372                                                 eth.ether_addr_octet[4],
373                                                 eth.ether_addr_octet[5]);
374
375         return str;
376 }
377
378 static char *index2ident(int index, const char *prefix)
379 {
380         struct ifreq ifr;
381         struct ether_addr eth;
382         char *str;
383         int sk, err, len;
384
385         if (index < 0)
386                 return NULL;
387
388         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
389         if (sk < 0)
390                 return NULL;
391
392         memset(&ifr, 0, sizeof(ifr));
393         ifr.ifr_ifindex = index;
394
395         err = ioctl(sk, SIOCGIFNAME, &ifr);
396
397         if (err == 0)
398                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
399
400         close(sk);
401
402         if (err < 0)
403                 return NULL;
404
405         len = prefix ? strlen(prefix) + 18 : 18;
406
407         str = malloc(len);
408         if (!str)
409                 return NULL;
410
411         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
412         snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
413                                                 prefix ? prefix : "",
414                                                 eth.ether_addr_octet[0],
415                                                 eth.ether_addr_octet[1],
416                                                 eth.ether_addr_octet[2],
417                                                 eth.ether_addr_octet[3],
418                                                 eth.ether_addr_octet[4],
419                                                 eth.ether_addr_octet[5]);
420
421         return str;
422 }
423
424 connman_bool_t connman_inet_is_cfg80211(int index)
425 {
426         connman_bool_t result = FALSE;
427         char phy80211_path[PATH_MAX];
428         struct stat st;
429         struct ifreq ifr;
430         int sk;
431
432         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
433         if (sk < 0)
434                 return FALSE;
435
436         memset(&ifr, 0, sizeof(ifr));
437         ifr.ifr_ifindex = index;
438
439         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
440                 goto done;
441
442         snprintf(phy80211_path, PATH_MAX,
443                                 "/sys/class/net/%s/phy80211", ifr.ifr_name);
444
445         if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
446                 result = TRUE;
447
448 done:
449         close(sk);
450
451         return result;
452 }
453
454 struct connman_device *connman_inet_create_device(int index)
455 {
456         enum connman_device_type type;
457         struct connman_device *device;
458         char *devname, *ident = NULL;
459         char *addr = NULL, *name = NULL;
460
461         if (index < 0)
462                 return NULL;
463
464         devname = connman_inet_ifname(index);
465         if (devname == NULL)
466                 return NULL;
467
468         if (__connman_device_isfiltered(devname) == TRUE) {
469                 connman_info("Ignoring interface %s (filtered)", devname);
470                 free(devname);
471                 return NULL;
472         }
473
474         type = __connman_rtnl_get_device_type(index);
475
476         switch (type) {
477         case CONNMAN_DEVICE_TYPE_UNKNOWN:
478                 connman_info("Ignoring interface %s (type unknown)", devname);
479                 free(devname);
480                 return NULL;
481         case CONNMAN_DEVICE_TYPE_ETHERNET:
482         case CONNMAN_DEVICE_TYPE_GADGET:
483         case CONNMAN_DEVICE_TYPE_WIFI:
484         case CONNMAN_DEVICE_TYPE_WIMAX:
485                 name = index2ident(index, "");
486                 addr = index2addr(index);
487                 break;
488         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
489         case CONNMAN_DEVICE_TYPE_CELLULAR:
490         case CONNMAN_DEVICE_TYPE_GPS:
491         case CONNMAN_DEVICE_TYPE_VENDOR:
492                 name = strdup(devname);
493                 break;
494         }
495
496         device = connman_device_create(name, type);
497         if (device == NULL)
498                 goto done;
499
500         switch (type) {
501         case CONNMAN_DEVICE_TYPE_UNKNOWN:
502         case CONNMAN_DEVICE_TYPE_VENDOR:
503         case CONNMAN_DEVICE_TYPE_GPS:
504                 break;
505         case CONNMAN_DEVICE_TYPE_ETHERNET:
506         case CONNMAN_DEVICE_TYPE_GADGET:
507                 ident = index2ident(index, NULL);
508                 break;
509         case CONNMAN_DEVICE_TYPE_WIFI:
510         case CONNMAN_DEVICE_TYPE_WIMAX:
511                 ident = index2ident(index, NULL);
512                 break;
513         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
514                 break;
515         case CONNMAN_DEVICE_TYPE_CELLULAR:
516                 ident = index2ident(index, NULL);
517                 break;
518         }
519
520         connman_device_set_index(device, index);
521         connman_device_set_interface(device, devname);
522
523         if (ident != NULL) {
524                 connman_device_set_ident(device, ident);
525                 free(ident);
526         }
527
528         connman_device_set_string(device, "Address", addr);
529
530 done:
531         free(devname);
532         free(name);
533         free(addr);
534
535         return device;
536 }
537
538 struct in6_ifreq {
539         struct in6_addr ifr6_addr;
540         __u32 ifr6_prefixlen;
541         unsigned int ifr6_ifindex;
542 };
543
544 int connman_inet_set_ipv6_address(int index,
545                 struct connman_ipaddress *ipaddress)
546 {
547         int err;
548         unsigned char prefix_len;
549         const char *address;
550
551         if (ipaddress->local == NULL)
552                 return 0;
553
554         prefix_len = ipaddress->prefixlen;
555         address = ipaddress->local;
556
557         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
558
559         err = __connman_inet_modify_address(RTM_NEWADDR,
560                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
561                                 address, NULL, prefix_len, NULL);
562         if (err < 0) {
563                 connman_error("%s: %s", __func__, strerror(-err));
564                 return err;
565         }
566
567         return 0;
568 }
569
570 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
571 {
572         int err;
573         unsigned char prefix_len;
574         const char *address, *broadcast, *peer;
575
576         if (ipaddress->local == NULL)
577                 return -1;
578
579         prefix_len = ipaddress->prefixlen;
580         address = ipaddress->local;
581         broadcast = ipaddress->broadcast;
582         peer = ipaddress->peer;
583
584         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
585
586         err = __connman_inet_modify_address(RTM_NEWADDR,
587                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
588                                 address, peer, prefix_len, broadcast);
589         if (err < 0) {
590                 connman_error("%s: %s", __func__, strerror(-err));
591                 return err;
592         }
593
594         return 0;
595 }
596
597 int connman_inet_clear_ipv6_address(int index, const char *address,
598                                                         int prefix_len)
599 {
600         int err;
601
602         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
603
604         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
605                                 address, NULL, prefix_len, NULL);
606         if (err < 0) {
607                 connman_error("%s: %s", __func__, strerror(-err));
608                 return err;
609         }
610
611         return 0;
612 }
613
614 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
615 {
616         int err;
617         unsigned char prefix_len;
618         const char *address, *broadcast, *peer;
619
620         prefix_len = ipaddress->prefixlen;
621         address = ipaddress->local;
622         broadcast = ipaddress->broadcast;
623         peer = ipaddress->peer;
624
625         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
626
627         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
628                                 address, peer, prefix_len, broadcast);
629         if (err < 0) {
630                 connman_error("%s: %s", __func__, strerror(-err));
631                 return err;
632         }
633
634         return 0;
635 }
636
637 int connman_inet_add_host_route(int index, const char *host,
638                                 const char *gateway)
639 {
640         return connman_inet_add_network_route(index, host, gateway, NULL);
641 }
642
643 int connman_inet_del_host_route(int index, const char *host)
644 {
645         return connman_inet_del_network_route(index, host);
646 }
647
648 int connman_inet_add_network_route(int index, const char *host,
649                                         const char *gateway,
650                                         const char *netmask)
651 {
652         struct ifreq ifr;
653         struct rtentry rt;
654         struct sockaddr_in addr;
655         int sk, err;
656
657         DBG("index %d host %s gateway %s netmask %s", index,
658                 host, gateway, netmask);
659
660         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
661         if (sk < 0)
662                 return -1;
663
664         memset(&ifr, 0, sizeof(ifr));
665         ifr.ifr_ifindex = index;
666
667         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
668                 close(sk);
669                 return -1;
670         }
671
672         DBG("ifname %s", ifr.ifr_name);
673
674         memset(&rt, 0, sizeof(rt));
675         rt.rt_flags = RTF_UP;
676         if (gateway != NULL)
677                 rt.rt_flags |= RTF_GATEWAY;
678         if (netmask == NULL)
679                 rt.rt_flags |= RTF_HOST;
680
681         memset(&addr, 0, sizeof(addr));
682         addr.sin_family = AF_INET;
683         addr.sin_addr.s_addr = inet_addr(host);
684         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
685
686         memset(&addr, 0, sizeof(addr));
687         addr.sin_family = AF_INET;
688         if (gateway != NULL)
689                 addr.sin_addr.s_addr = inet_addr(gateway);
690         else
691                 addr.sin_addr.s_addr = INADDR_ANY;
692         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
693
694         memset(&addr, 0, sizeof(addr));
695         addr.sin_family = AF_INET;
696         addr.sin_addr.s_addr = INADDR_ANY;
697         if (netmask != NULL)
698                 addr.sin_addr.s_addr = inet_addr(netmask);
699         else
700                 addr.sin_addr.s_addr = INADDR_ANY;
701         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
702
703         rt.rt_dev = ifr.ifr_name;
704
705         err = ioctl(sk, SIOCADDRT, &rt);
706         if (err < 0)
707                 connman_error("Adding host route failed (%s)",
708                                                         strerror(errno));
709
710         close(sk);
711
712         return err;
713 }
714
715 int connman_inet_del_network_route(int index, const char *host)
716 {
717         struct ifreq ifr;
718         struct rtentry rt;
719         struct sockaddr_in addr;
720         int sk, err;
721
722         DBG("index %d host %s", index, host);
723
724         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
725         if (sk < 0)
726                 return -1;
727
728         memset(&ifr, 0, sizeof(ifr));
729         ifr.ifr_ifindex = index;
730
731         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
732                 close(sk);
733                 return -1;
734         }
735
736         DBG("ifname %s", ifr.ifr_name);
737
738         memset(&rt, 0, sizeof(rt));
739         rt.rt_flags = RTF_UP | RTF_HOST;
740
741         memset(&addr, 0, sizeof(addr));
742         addr.sin_family = AF_INET;
743         addr.sin_addr.s_addr = inet_addr(host);
744         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
745
746         rt.rt_dev = ifr.ifr_name;
747
748         err = ioctl(sk, SIOCDELRT, &rt);
749         if (err < 0)
750                 connman_error("Deleting host route failed (%s)",
751                                                         strerror(errno));
752
753         close(sk);
754
755         return err;
756 }
757
758 int connman_inet_del_ipv6_network_route(int index, const char *host,
759                                                 unsigned char prefix_len)
760 {
761         struct in6_rtmsg rt;
762         int sk, err;
763
764         DBG("index %d host %s", index, host);
765
766         if (host == NULL)
767                 return -EINVAL;
768
769         memset(&rt, 0, sizeof(rt));
770
771         rt.rtmsg_dst_len = prefix_len;
772
773         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
774         if (err < 0)
775                 goto out;
776
777         rt.rtmsg_flags = RTF_UP | RTF_HOST;
778
779         rt.rtmsg_metric = 1;
780         rt.rtmsg_ifindex = index;
781
782         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
783         if (sk < 0) {
784                 err = -1;
785                 goto out;
786         }
787
788         err = ioctl(sk, SIOCDELRT, &rt);
789         close(sk);
790 out:
791         if (err < 0)
792                 connman_error("Del IPv6 host route error (%s)",
793                                                 strerror(errno));
794
795         return err;
796 }
797
798 int connman_inet_del_ipv6_host_route(int index, const char *host)
799 {
800         return connman_inet_del_ipv6_network_route(index, host, 128);
801 }
802
803 int connman_inet_add_ipv6_network_route(int index, const char *host,
804                                         const char *gateway,
805                                         unsigned char prefix_len)
806 {
807         struct in6_rtmsg rt;
808         int sk, err;
809
810         DBG("index %d host %s gateway %s", index, host, gateway);
811
812         if (host == NULL)
813                 return -EINVAL;
814
815         memset(&rt, 0, sizeof(rt));
816
817         rt.rtmsg_dst_len = prefix_len;
818
819         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
820         if (err < 0)
821                 goto out;
822
823         rt.rtmsg_flags = RTF_UP | RTF_HOST;
824
825         if (gateway != NULL) {
826                 rt.rtmsg_flags |= RTF_GATEWAY;
827                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
828         }
829
830         rt.rtmsg_metric = 1;
831         rt.rtmsg_ifindex = index;
832
833         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
834         if (sk < 0) {
835                 err = -1;
836                 goto out;
837         }
838
839         err = ioctl(sk, SIOCADDRT, &rt);
840         close(sk);
841 out:
842         if (err < 0)
843                 connman_error("Set IPv6 host route error (%s)",
844                                                 strerror(errno));
845
846         return err;
847 }
848
849 int connman_inet_add_ipv6_host_route(int index, const char *host,
850                                         const char *gateway)
851 {
852         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
853 }
854
855 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
856 {
857         struct in6_rtmsg rt;
858         int sk, err;
859
860         DBG("index %d gateway %s", index, gateway);
861
862         if (gateway == NULL)
863                 return -EINVAL;
864
865         memset(&rt, 0, sizeof(rt));
866
867         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
868         if (err < 0)
869                 goto out;
870
871         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
872         rt.rtmsg_metric = 1;
873         rt.rtmsg_dst_len = 0;
874         rt.rtmsg_ifindex = index;
875
876         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
877         if (sk < 0) {
878                 err = -1;
879                 goto out;
880         }
881
882         err = ioctl(sk, SIOCADDRT, &rt);
883         close(sk);
884 out:
885         if (err < 0)
886                 connman_error("Set default IPv6 gateway error (%s)",
887                                                 strerror(errno));
888
889         return err;
890 }
891
892 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
893 {
894         struct in6_rtmsg rt;
895         int sk, err;
896
897         DBG("index %d gateway %s", index, gateway);
898
899         if (gateway == NULL)
900                 return -EINVAL;
901
902         memset(&rt, 0, sizeof(rt));
903
904         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
905         if (err < 0)
906                 goto out;
907
908         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
909         rt.rtmsg_metric = 1;
910         rt.rtmsg_dst_len = 0;
911         rt.rtmsg_ifindex = index;
912
913         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
914         if (sk < 0) {
915                 err = -1;
916                 goto out;
917         }
918
919         err = ioctl(sk, SIOCDELRT, &rt);
920         close(sk);
921 out:
922         if (err < 0)
923                 connman_error("Clear default IPv6 gateway error (%s)",
924                                                 strerror(errno));
925
926         return err;
927 }
928
929 int connman_inet_set_gateway_address(int index, const char *gateway)
930 {
931         struct ifreq ifr;
932         struct rtentry rt;
933         struct sockaddr_in addr;
934         int sk, err;
935
936         DBG("index %d gateway %s", index, gateway);
937
938         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
939         if (sk < 0)
940                 return -1;
941
942         memset(&ifr, 0, sizeof(ifr));
943         ifr.ifr_ifindex = index;
944
945         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
946                 close(sk);
947                 return -1;
948         }
949
950         DBG("ifname %s", ifr.ifr_name);
951
952         memset(&rt, 0, sizeof(rt));
953         rt.rt_flags = RTF_UP | RTF_GATEWAY;
954
955         memset(&addr, 0, sizeof(addr));
956         addr.sin_family = AF_INET;
957         addr.sin_addr.s_addr = INADDR_ANY;
958         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
959
960         memset(&addr, 0, sizeof(addr));
961         addr.sin_family = AF_INET;
962         addr.sin_addr.s_addr = inet_addr(gateway);
963         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
964
965         memset(&addr, 0, sizeof(addr));
966         addr.sin_family = AF_INET;
967         addr.sin_addr.s_addr = INADDR_ANY;
968         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
969
970         err = ioctl(sk, SIOCADDRT, &rt);
971         if (err < 0)
972                 connman_error("Setting default gateway route failed (%s)",
973                                                         strerror(errno));
974
975         close(sk);
976
977         return err;
978 }
979
980 int connman_inet_set_gateway_interface(int index)
981 {
982         struct ifreq ifr;
983         struct rtentry rt;
984         struct sockaddr_in addr;
985         int sk, err;
986
987         DBG("index %d", index);
988
989         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
990         if (sk < 0)
991                 return -1;
992
993         memset(&ifr, 0, sizeof(ifr));
994         ifr.ifr_ifindex = index;
995
996         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
997                 close(sk);
998                 return -1;
999         }
1000
1001         DBG("ifname %s", ifr.ifr_name);
1002
1003         memset(&rt, 0, sizeof(rt));
1004         rt.rt_flags = RTF_UP;
1005
1006         memset(&addr, 0, sizeof(addr));
1007         addr.sin_family = AF_INET;
1008         addr.sin_addr.s_addr = INADDR_ANY;
1009
1010         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1011         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1012         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1013
1014         rt.rt_dev = ifr.ifr_name;
1015
1016         err = ioctl(sk, SIOCADDRT, &rt);
1017         if (err < 0)
1018                 connman_error("Setting default interface route failed (%s)",
1019                                                         strerror(errno));
1020         close(sk);
1021
1022         return err;
1023 }
1024
1025 int connman_inet_set_ipv6_gateway_interface(int index)
1026 {
1027         struct ifreq ifr;
1028         struct rtentry rt;
1029         struct sockaddr_in6 addr;
1030         const struct in6_addr any = IN6ADDR_ANY_INIT;
1031         int sk, err;
1032
1033         DBG("index %d", index);
1034
1035         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1036         if (sk < 0)
1037                 return -1;
1038
1039         memset(&ifr, 0, sizeof(ifr));
1040         ifr.ifr_ifindex = index;
1041
1042         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1043                 close(sk);
1044                 return -1;
1045         }
1046
1047         DBG("ifname %s", ifr.ifr_name);
1048
1049         memset(&rt, 0, sizeof(rt));
1050         rt.rt_flags = RTF_UP;
1051
1052         memset(&addr, 0, sizeof(addr));
1053         addr.sin6_family = AF_INET6;
1054         addr.sin6_addr = any;
1055
1056         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1057         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1058         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1059
1060         rt.rt_dev = ifr.ifr_name;
1061
1062         err = ioctl(sk, SIOCADDRT, &rt);
1063         if (err < 0)
1064                 connman_error("Setting default interface route failed (%s)",
1065                                                         strerror(errno));
1066         close(sk);
1067
1068         return err;
1069 }
1070
1071 int connman_inet_clear_gateway_address(int index, const char *gateway)
1072 {
1073         struct ifreq ifr;
1074         struct rtentry rt;
1075         struct sockaddr_in addr;
1076         int sk, err;
1077
1078         DBG("index %d gateway %s", index, gateway);
1079
1080         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1081         if (sk < 0)
1082                 return -1;
1083
1084         memset(&ifr, 0, sizeof(ifr));
1085         ifr.ifr_ifindex = index;
1086
1087         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1088                 close(sk);
1089                 return -1;
1090         }
1091
1092         DBG("ifname %s", ifr.ifr_name);
1093
1094         memset(&rt, 0, sizeof(rt));
1095         rt.rt_flags = RTF_UP | RTF_GATEWAY;
1096
1097         memset(&addr, 0, sizeof(addr));
1098         addr.sin_family = AF_INET;
1099         addr.sin_addr.s_addr = INADDR_ANY;
1100         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1101
1102         memset(&addr, 0, sizeof(addr));
1103         addr.sin_family = AF_INET;
1104         addr.sin_addr.s_addr = inet_addr(gateway);
1105         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1106
1107         memset(&addr, 0, sizeof(addr));
1108         addr.sin_family = AF_INET;
1109         addr.sin_addr.s_addr = INADDR_ANY;
1110         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1111
1112         err = ioctl(sk, SIOCDELRT, &rt);
1113         if (err < 0)
1114                 connman_error("Removing default gateway route failed (%s)",
1115                                                         strerror(errno));
1116
1117         close(sk);
1118
1119         return err;
1120 }
1121
1122 int connman_inet_clear_gateway_interface(int index)
1123 {
1124         struct ifreq ifr;
1125         struct rtentry rt;
1126         struct sockaddr_in addr;
1127         int sk, err;
1128
1129         DBG("index %d", index);
1130
1131         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1132         if (sk < 0)
1133                 return -1;
1134
1135         memset(&ifr, 0, sizeof(ifr));
1136         ifr.ifr_ifindex = index;
1137
1138         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1139                 close(sk);
1140                 return -1;
1141         }
1142
1143         DBG("ifname %s", ifr.ifr_name);
1144
1145         memset(&rt, 0, sizeof(rt));
1146         rt.rt_flags = RTF_UP;
1147
1148         memset(&addr, 0, sizeof(addr));
1149         addr.sin_family = AF_INET;
1150         addr.sin_addr.s_addr = INADDR_ANY;
1151
1152         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1153         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1154         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1155
1156         rt.rt_dev = ifr.ifr_name;
1157
1158         err = ioctl(sk, SIOCDELRT, &rt);
1159         if (err < 0)
1160                 connman_error("Removing default interface route failed (%s)",
1161                                                         strerror(errno));
1162         close(sk);
1163
1164         return err;
1165 }
1166
1167 int connman_inet_clear_ipv6_gateway_interface(int index)
1168 {
1169         struct ifreq ifr;
1170         struct rtentry rt;
1171         struct sockaddr_in6 addr;
1172         const struct in6_addr any = IN6ADDR_ANY_INIT;
1173         int sk, err;
1174
1175         DBG("index %d", index);
1176
1177         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1178         if (sk < 0)
1179                 return -1;
1180
1181         memset(&ifr, 0, sizeof(ifr));
1182         ifr.ifr_ifindex = index;
1183
1184         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1185                 close(sk);
1186                 return -1;
1187         }
1188
1189         DBG("ifname %s", ifr.ifr_name);
1190
1191         memset(&rt, 0, sizeof(rt));
1192         rt.rt_flags = RTF_UP;
1193
1194         memset(&addr, 0, sizeof(addr));
1195         addr.sin6_family = AF_INET6;
1196         addr.sin6_addr = any;
1197
1198         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1199         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1200         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1201
1202         rt.rt_dev = ifr.ifr_name;
1203
1204         err = ioctl(sk, SIOCDELRT, &rt);
1205         if (err < 0)
1206                 connman_error("Removing default interface route failed (%s)",
1207                                                         strerror(errno));
1208         close(sk);
1209
1210         return err;
1211 }
1212
1213 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1214 {
1215         struct ifreq ifr;
1216         struct in_addr _host_addr;
1217         in_addr_t host_addr, netmask_addr, if_addr;
1218         struct sockaddr_in *netmask, *addr;
1219         int sk;
1220
1221         DBG("host %s", host);
1222
1223         if (host == NULL)
1224                 return FALSE;
1225
1226         if (inet_aton(host, &_host_addr) == 0)
1227                 return -1;
1228         host_addr = _host_addr.s_addr;
1229
1230         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1231         if (sk < 0)
1232                 return FALSE;
1233
1234         memset(&ifr, 0, sizeof(ifr));
1235         ifr.ifr_ifindex = index;
1236
1237         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1238                 close(sk);
1239                 return FALSE;
1240         }
1241
1242         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1243                 close(sk);
1244                 return FALSE;
1245         }
1246
1247         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1248         netmask_addr = netmask->sin_addr.s_addr;
1249
1250         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1251                 close(sk);
1252                 return FALSE;
1253         }
1254
1255         close(sk);
1256
1257         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1258         if_addr = addr->sin_addr.s_addr;
1259
1260         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1261 }
1262
1263 int connman_inet_remove_from_bridge(int index, const char *bridge)
1264 {
1265         struct ifreq ifr;
1266         int sk, err;
1267
1268         if (bridge == NULL)
1269                 return -EINVAL;
1270
1271         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1272         if (sk < 0)
1273                 return sk;
1274
1275         memset(&ifr, 0, sizeof(ifr));
1276         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1277         ifr.ifr_ifindex = index;
1278
1279         err = ioctl(sk, SIOCBRDELIF, &ifr);
1280
1281         close(sk);
1282
1283         if (err < 0) {
1284                 connman_error("Remove interface from bridge error %s",
1285                                                         strerror(errno));
1286                 return err;
1287         }
1288
1289         return 0;
1290 }
1291
1292 int connman_inet_add_to_bridge(int index, const char *bridge)
1293 {
1294         struct ifreq ifr;
1295         int sk, err;
1296
1297         if (bridge == NULL)
1298                 return -EINVAL;
1299
1300         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1301         if (sk < 0)
1302                 return sk;
1303
1304         memset(&ifr, 0, sizeof(ifr));
1305         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1306         ifr.ifr_ifindex = index;
1307
1308         err = ioctl(sk, SIOCBRADDIF, &ifr);
1309
1310         close(sk);
1311
1312         if (err < 0) {
1313                 connman_error("Add interface to bridge error %s",
1314                                                         strerror(errno));
1315                 return err;
1316         }
1317
1318         return 0;
1319 }
1320
1321 int connman_inet_set_mtu(int index, int mtu)
1322 {
1323         struct ifreq ifr;
1324         int sk, err;
1325
1326         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1327         if (sk < 0)
1328                 return sk;
1329
1330         memset(&ifr, 0, sizeof(ifr));
1331         ifr.ifr_ifindex = index;
1332
1333         err = ioctl(sk, SIOCGIFNAME, &ifr);
1334         if (err == 0) {
1335                 ifr.ifr_mtu = mtu;
1336                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1337         }
1338
1339         close(sk);
1340         return err;
1341 }
1342
1343 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1344 {
1345         struct ifreq ifr;
1346         int sk, err, index;
1347         __u32 mask;
1348         __u32 flags;
1349
1350         if (tunnel == NULL)
1351                 return -EINVAL;
1352
1353         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1354         if (sk < 0)
1355                 return sk;
1356
1357         index = if_nametoindex(tunnel);
1358
1359         err = connman_inet_set_mtu(index, mtu);
1360         if (err < 0)
1361                 return err;
1362         else if (err)
1363                 goto done;
1364
1365         memset(&ifr, 0, sizeof(ifr));
1366         strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1367         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1368         if (err)
1369                 goto done;
1370
1371         mask = IFF_UP;
1372         flags = IFF_UP;
1373
1374         if ((ifr.ifr_flags ^ flags) & mask) {
1375                 ifr.ifr_flags &= ~mask;
1376                 ifr.ifr_flags |= mask & flags;
1377                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1378                 if (err)
1379                         connman_error("SIOCSIFFLAGS failed: %s",
1380                                                         strerror(errno));
1381         }
1382
1383 done:
1384         close(sk);
1385         return err;
1386 }
1387
1388 int connman_inet_create_tunnel(char **iface)
1389 {
1390         struct ifreq ifr;
1391         int i, fd;
1392
1393         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1394         if (fd < 0) {
1395                 i = -errno;
1396                 connman_error("Failed to open /dev/net/tun: %s",
1397                                 strerror(errno));
1398                 return i;
1399         }
1400
1401         memset(&ifr, 0, sizeof(ifr));
1402         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1403
1404         for (i = 0; i < 256; i++) {
1405                 sprintf(ifr.ifr_name, "tun%d", i);
1406
1407                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1408                         break;
1409         }
1410
1411         if (i == 256) {
1412                 connman_error("Failed to find available tun device");
1413                 close(fd);
1414                 return -ENODEV;
1415         }
1416
1417         *iface = g_strdup(ifr.ifr_name);
1418
1419         return fd;
1420 }
1421
1422 struct rs_cb_data {
1423         GIOChannel *channel;
1424         __connman_inet_rs_cb_t callback;
1425         struct sockaddr_in6 addr;
1426         guint rs_timeout;
1427         guint watch_id;
1428         void *user_data;
1429 };
1430
1431 #define CMSG_BUF_LEN 512
1432 #define IN6ADDR_ALL_NODES_MC_INIT \
1433         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1434 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1435         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1436
1437 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1438 static const struct in6_addr in6addr_all_routers_mc =
1439                                                 IN6ADDR_ALL_ROUTERS_MC_INIT;
1440
1441 static void rs_cleanup(struct rs_cb_data *data)
1442 {
1443         if (data->channel != NULL) {
1444                 g_io_channel_shutdown(data->channel, TRUE, NULL);
1445                 g_io_channel_unref(data->channel);
1446                 data->channel = NULL;
1447         }
1448
1449         if (data->rs_timeout > 0)
1450                 g_source_remove(data->rs_timeout);
1451
1452         if (data->watch_id > 0)
1453                 g_source_remove(data->watch_id);
1454
1455         g_free(data);
1456 }
1457
1458 static gboolean rs_timeout_cb(gpointer user_data)
1459 {
1460         struct rs_cb_data *data = user_data;
1461
1462         DBG("user data %p", user_data);
1463
1464         if (data == NULL)
1465                 return FALSE;
1466
1467         if (data->callback != NULL)
1468                 data->callback(NULL, 0, data->user_data);
1469
1470         data->rs_timeout = 0;
1471         rs_cleanup(data);
1472         return FALSE;
1473 }
1474
1475 static int icmpv6_recv(int fd, gpointer user_data)
1476 {
1477         struct msghdr mhdr;
1478         struct iovec iov;
1479         unsigned char chdr[CMSG_BUF_LEN];
1480         unsigned char buf[1540];
1481         struct rs_cb_data *data = user_data;
1482         struct nd_router_advert *hdr;
1483         struct sockaddr_in6 saddr;
1484         ssize_t len;
1485
1486         DBG("");
1487
1488         iov.iov_len = sizeof(buf);
1489         iov.iov_base = buf;
1490
1491         mhdr.msg_name = (void *)&saddr;
1492         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1493         mhdr.msg_iov = &iov;
1494         mhdr.msg_iovlen = 1;
1495         mhdr.msg_control = (void *)chdr;
1496         mhdr.msg_controllen = CMSG_BUF_LEN;
1497
1498         len = recvmsg(fd, &mhdr, 0);
1499         if (len < 0) {
1500                 data->callback(NULL, 0, data->user_data);
1501                 rs_cleanup(data);
1502                 return -errno;
1503         }
1504
1505         hdr = (struct nd_router_advert *)buf;
1506         DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1507                                 sizeof(struct nd_router_advert));
1508         if (hdr->nd_ra_code != 0)
1509                 return 0;
1510
1511         data->callback(hdr, len, data->user_data);
1512         rs_cleanup(data);
1513
1514         return len;
1515 }
1516
1517 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1518                                                                 gpointer data)
1519 {
1520         int fd, ret;
1521
1522         DBG("");
1523
1524         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1525                 return FALSE;
1526
1527         fd = g_io_channel_unix_get_fd(chan);
1528         ret = icmpv6_recv(fd, data);
1529         if (ret == 0)
1530                 return TRUE;
1531
1532         return FALSE;
1533 }
1534
1535 /* Adapted from RFC 1071 "C" Implementation Example */
1536 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1537 {
1538         register unsigned long sum = 0;
1539         socklen_t count;
1540         uint16_t *addr;
1541         int i;
1542
1543         /* caller must make sure datalen is even */
1544
1545         addr = (uint16_t *)phdr;
1546         for (i = 0; i < 20; i++)
1547                 sum += *addr++;
1548
1549         count = datalen;
1550         addr = (uint16_t *)data;
1551
1552         while (count > 1) {
1553                 sum += *(addr++);
1554                 count -= 2;
1555         }
1556
1557         while (sum >> 16)
1558                 sum = (sum & 0xffff) + (sum >> 16);
1559
1560         return (uint16_t)~sum;
1561 }
1562
1563 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1564 {
1565         struct _phdr {
1566                 struct in6_addr src;
1567                 struct in6_addr dst;
1568                 uint32_t plen;
1569                 uint8_t reserved[3];
1570                 uint8_t nxt;
1571         } phdr;
1572
1573         struct {
1574                 struct ip6_hdr ip;
1575                 union {
1576                         struct icmp6_hdr icmp;
1577                         struct nd_neighbor_solicit ns;
1578                         struct nd_router_solicit rs;
1579                 } i;
1580         } frame;
1581
1582         struct msghdr msgh;
1583         struct cmsghdr *cmsg;
1584         struct in6_pktinfo *pinfo;
1585         struct sockaddr_in6 dst;
1586         char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1587         struct iovec iov;
1588         int fd, datalen, ret;
1589
1590         DBG("");
1591
1592         fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1593         if (fd < 0)
1594                 return -errno;
1595
1596         memset(&frame, 0, sizeof(frame));
1597         memset(&dst, 0, sizeof(dst));
1598
1599         datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1600         dst.sin6_addr = *dest;
1601
1602         /* Fill in the IPv6 header */
1603         frame.ip.ip6_vfc = 0x60;
1604         frame.ip.ip6_plen = htons(datalen);
1605         frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1606         frame.ip.ip6_hlim = 255;
1607         frame.ip.ip6_dst = dst.sin6_addr;
1608         /* all other fields are already set to zero */
1609
1610         /* Prepare pseudo header for csum */
1611         memset(&phdr, 0, sizeof(phdr));
1612         phdr.dst = dst.sin6_addr;
1613         phdr.plen = htonl(datalen);
1614         phdr.nxt = IPPROTO_ICMPV6;
1615
1616         /* Fill in remaining ICMP header fields */
1617         frame.i.icmp.icmp6_type = type;
1618         frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1619
1620         iov.iov_base = &frame;
1621         iov.iov_len = sizeof(frame.ip) + datalen;
1622
1623         dst.sin6_family = AF_INET6;
1624         msgh.msg_name = &dst;
1625         msgh.msg_namelen = sizeof(dst);
1626         msgh.msg_iov = &iov;
1627         msgh.msg_iovlen = 1;
1628         msgh.msg_flags = 0;
1629
1630         memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1631         cmsg = (struct cmsghdr *)cbuf;
1632         pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1633         pinfo->ipi6_ifindex = oif;
1634
1635         cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1636         cmsg->cmsg_level = IPPROTO_IPV6;
1637         cmsg->cmsg_type = IPV6_PKTINFO;
1638         msgh.msg_control = cmsg;
1639         msgh.msg_controllen = cmsg->cmsg_len;
1640
1641         ret = sendmsg(fd, &msgh, 0);
1642
1643         close(fd);
1644         return ret;
1645 }
1646
1647 static inline void ipv6_addr_set(struct in6_addr *addr,
1648                                 uint32_t w1, uint32_t w2,
1649                                 uint32_t w3, uint32_t w4)
1650 {
1651         addr->s6_addr32[0] = w1;
1652         addr->s6_addr32[1] = w2;
1653         addr->s6_addr32[2] = w3;
1654         addr->s6_addr32[3] = w4;
1655 }
1656
1657 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1658                                         struct in6_addr *solicited)
1659 {
1660         ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1661                         htonl(0xFF000000) | addr->s6_addr32[3]);
1662 }
1663
1664 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1665                                                                 int cmd)
1666 {
1667         unsigned int val = 0;
1668         struct ipv6_mreq mreq;
1669         int ret;
1670
1671         memset(&mreq, 0, sizeof(mreq));
1672         mreq.ipv6mr_interface = ifindex;
1673         mreq.ipv6mr_multiaddr = *mc_addr;
1674
1675         ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1676                         &val, sizeof(int));
1677
1678         if (ret < 0)
1679                 return ret;
1680
1681         return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1682 }
1683
1684 int __connman_inet_ipv6_send_rs(int index, int timeout,
1685                         __connman_inet_rs_cb_t callback, void *user_data)
1686 {
1687         struct rs_cb_data *data;
1688         struct icmp6_filter filter;
1689         struct in6_addr solicit;
1690         struct in6_addr dst = in6addr_all_routers_mc;
1691         int sk;
1692
1693         DBG("");
1694
1695         if (timeout <= 0)
1696                 return -EINVAL;
1697
1698         data = g_try_malloc0(sizeof(struct rs_cb_data));
1699         if (data == NULL)
1700                 return -ENOMEM;
1701
1702         data->callback = callback;
1703         data->user_data = user_data;
1704         data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1705
1706         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1707         if (sk < 0)
1708                 return -errno;
1709
1710         ICMP6_FILTER_SETBLOCKALL(&filter);
1711         ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1712
1713         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1714                                                 sizeof(struct icmp6_filter));
1715
1716         ipv6_addr_solict_mult(&dst, &solicit);
1717         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1718         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1719
1720         data->channel = g_io_channel_unix_new(sk);
1721         g_io_channel_set_close_on_unref(data->channel, TRUE);
1722
1723         g_io_channel_set_encoding(data->channel, NULL, NULL);
1724         g_io_channel_set_buffered(data->channel, FALSE);
1725
1726         data->watch_id = g_io_add_watch(data->channel,
1727                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1728                         icmpv6_event, data);
1729
1730         ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
1731
1732         return 0;
1733 }
1734
1735 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
1736                                         unsigned int length)
1737 {
1738         GSList *prefixes = NULL;
1739         uint8_t *pos;
1740         int len;
1741
1742         if (length <= sizeof(struct nd_router_advert))
1743                 return NULL;
1744
1745         len = length - sizeof(struct nd_router_advert);
1746         pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
1747
1748         while (len > 0) {
1749                 struct nd_opt_prefix_info *pinfo;
1750                 char prefix_str[INET6_ADDRSTRLEN+1], *str;
1751                 const char *prefix;
1752                 int optlen;
1753
1754                 if (len < 2)
1755                         break;
1756
1757                 optlen = pos[1] << 3;
1758                 if (optlen == 0 || optlen > len)
1759                         break;
1760
1761                 switch (pos[0]) {
1762                 case ND_OPT_PREFIX_INFORMATION:
1763                         pinfo = (struct nd_opt_prefix_info *)pos;
1764                         prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
1765                                         prefix_str, INET6_ADDRSTRLEN);
1766                         if (prefix == NULL)
1767                                 break;
1768
1769                         str = g_strdup_printf("%s/%d", prefix,
1770                                                 pinfo->nd_opt_pi_prefix_len);
1771                         prefixes = g_slist_append(prefixes, str);
1772
1773                         DBG("prefix %s", str);
1774
1775                         break;
1776                 }
1777
1778                 len -= optlen;
1779                 pos += optlen;
1780         }
1781
1782         return prefixes;
1783 }