core: Fix compilation in MeeGo
[platform/upstream/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         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
658         if (sk < 0)
659                 return -1;
660
661         memset(&ifr, 0, sizeof(ifr));
662         ifr.ifr_ifindex = index;
663
664         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
665                 close(sk);
666                 return -1;
667         }
668
669         DBG("ifname %s", ifr.ifr_name);
670
671         memset(&rt, 0, sizeof(rt));
672         rt.rt_flags = RTF_UP;
673         if (gateway != NULL)
674                 rt.rt_flags |= RTF_GATEWAY;
675         if (netmask == NULL)
676                 rt.rt_flags |= RTF_HOST;
677
678         memset(&addr, 0, sizeof(addr));
679         addr.sin_family = AF_INET;
680         addr.sin_addr.s_addr = inet_addr(host);
681         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
682
683         memset(&addr, 0, sizeof(addr));
684         addr.sin_family = AF_INET;
685         if (gateway != NULL)
686                 addr.sin_addr.s_addr = inet_addr(gateway);
687         else
688                 addr.sin_addr.s_addr = INADDR_ANY;
689         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
690
691         memset(&addr, 0, sizeof(addr));
692         addr.sin_family = AF_INET;
693         addr.sin_addr.s_addr = INADDR_ANY;
694         if (netmask != NULL)
695                 addr.sin_addr.s_addr = inet_addr(netmask);
696         else
697                 addr.sin_addr.s_addr = INADDR_ANY;
698         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
699
700         rt.rt_dev = ifr.ifr_name;
701
702         err = ioctl(sk, SIOCADDRT, &rt);
703         if (err < 0)
704                 connman_error("Adding host route failed (%s)",
705                                                         strerror(errno));
706
707         close(sk);
708
709         return err;
710 }
711
712 int connman_inet_del_network_route(int index, const char *host)
713 {
714         struct ifreq ifr;
715         struct rtentry rt;
716         struct sockaddr_in addr;
717         int sk, err;
718
719         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
720         if (sk < 0)
721                 return -1;
722
723         memset(&ifr, 0, sizeof(ifr));
724         ifr.ifr_ifindex = index;
725
726         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
727                 close(sk);
728                 return -1;
729         }
730
731         DBG("ifname %s", ifr.ifr_name);
732
733         memset(&rt, 0, sizeof(rt));
734         rt.rt_flags = RTF_UP | RTF_HOST;
735
736         memset(&addr, 0, sizeof(addr));
737         addr.sin_family = AF_INET;
738         addr.sin_addr.s_addr = inet_addr(host);
739         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
740
741         rt.rt_dev = ifr.ifr_name;
742
743         err = ioctl(sk, SIOCDELRT, &rt);
744         if (err < 0)
745                 connman_error("Deleting host route failed (%s)",
746                                                         strerror(errno));
747
748         close(sk);
749
750         return err;
751 }
752
753 int connman_inet_del_ipv6_network_route(int index, const char *host,
754                                                 unsigned char prefix_len)
755 {
756         struct in6_rtmsg rt;
757         int sk, err;
758
759         DBG("index %d host %s", index, host);
760
761         if (host == NULL)
762                 return -EINVAL;
763
764         memset(&rt, 0, sizeof(rt));
765
766         rt.rtmsg_dst_len = prefix_len;
767
768         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
769         if (err < 0)
770                 goto out;
771
772         rt.rtmsg_flags = RTF_UP | RTF_HOST;
773
774         rt.rtmsg_metric = 1;
775         rt.rtmsg_ifindex = index;
776
777         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
778         if (sk < 0) {
779                 err = -1;
780                 goto out;
781         }
782
783         err = ioctl(sk, SIOCDELRT, &rt);
784         close(sk);
785 out:
786         if (err < 0)
787                 connman_error("Del IPv6 host route error (%s)",
788                                                 strerror(errno));
789
790         return err;
791 }
792
793 int connman_inet_del_ipv6_host_route(int index, const char *host)
794 {
795         return connman_inet_del_ipv6_network_route(index, host, 128);
796 }
797
798 int connman_inet_add_ipv6_network_route(int index, const char *host,
799                                         const char *gateway,
800                                         unsigned char prefix_len)
801 {
802         struct in6_rtmsg rt;
803         int sk, err;
804
805         DBG("index %d host %s gateway %s", index, host, gateway);
806
807         if (host == NULL)
808                 return -EINVAL;
809
810         memset(&rt, 0, sizeof(rt));
811
812         rt.rtmsg_dst_len = prefix_len;
813
814         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
815         if (err < 0)
816                 goto out;
817
818         rt.rtmsg_flags = RTF_UP | RTF_HOST;
819
820         if (gateway != NULL) {
821                 rt.rtmsg_flags |= RTF_GATEWAY;
822                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
823         }
824
825         rt.rtmsg_metric = 1;
826         rt.rtmsg_ifindex = index;
827
828         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
829         if (sk < 0) {
830                 err = -1;
831                 goto out;
832         }
833
834         err = ioctl(sk, SIOCADDRT, &rt);
835         close(sk);
836 out:
837         if (err < 0)
838                 connman_error("Set IPv6 host route error (%s)",
839                                                 strerror(errno));
840
841         return err;
842 }
843
844 int connman_inet_add_ipv6_host_route(int index, const char *host,
845                                         const char *gateway)
846 {
847         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
848 }
849
850 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
851 {
852         struct in6_rtmsg rt;
853         int sk, err;
854
855         DBG("index %d, gateway %s", index, gateway);
856
857         if (gateway == NULL)
858                 return -EINVAL;
859
860         memset(&rt, 0, sizeof(rt));
861
862         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
863         if (err < 0)
864                 goto out;
865
866         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
867         rt.rtmsg_metric = 1;
868         rt.rtmsg_dst_len = 0;
869         rt.rtmsg_ifindex = index;
870
871         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
872         if (sk < 0) {
873                 err = -1;
874                 goto out;
875         }
876
877         err = ioctl(sk, SIOCADDRT, &rt);
878         close(sk);
879 out:
880         if (err < 0)
881                 connman_error("Set default IPv6 gateway error (%s)",
882                                                 strerror(errno));
883
884         return err;
885 }
886
887 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
888 {
889         struct in6_rtmsg rt;
890         int sk, err;
891
892         DBG("index %d, gateway %s", index, gateway);
893
894         if (gateway == NULL)
895                 return -EINVAL;
896
897         memset(&rt, 0, sizeof(rt));
898
899         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
900         if (err < 0)
901                 goto out;
902
903         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
904         rt.rtmsg_metric = 1;
905         rt.rtmsg_dst_len = 0;
906         rt.rtmsg_ifindex = index;
907
908         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
909         if (sk < 0) {
910                 err = -1;
911                 goto out;
912         }
913
914         err = ioctl(sk, SIOCDELRT, &rt);
915         close(sk);
916 out:
917         if (err < 0)
918                 connman_error("Clear default IPv6 gateway error (%s)",
919                                                 strerror(errno));
920
921         return err;
922 }
923
924 int connman_inet_set_gateway_address(int index, const char *gateway)
925 {
926         struct ifreq ifr;
927         struct rtentry rt;
928         struct sockaddr_in addr;
929         int sk, err;
930
931         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
932         if (sk < 0)
933                 return -1;
934
935         memset(&ifr, 0, sizeof(ifr));
936         ifr.ifr_ifindex = index;
937
938         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
939                 close(sk);
940                 return -1;
941         }
942
943         DBG("ifname %s", ifr.ifr_name);
944
945         memset(&rt, 0, sizeof(rt));
946         rt.rt_flags = RTF_UP | RTF_GATEWAY;
947
948         memset(&addr, 0, sizeof(addr));
949         addr.sin_family = AF_INET;
950         addr.sin_addr.s_addr = INADDR_ANY;
951         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
952
953         memset(&addr, 0, sizeof(addr));
954         addr.sin_family = AF_INET;
955         addr.sin_addr.s_addr = inet_addr(gateway);
956         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
957
958         memset(&addr, 0, sizeof(addr));
959         addr.sin_family = AF_INET;
960         addr.sin_addr.s_addr = INADDR_ANY;
961         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
962
963         err = ioctl(sk, SIOCADDRT, &rt);
964         if (err < 0)
965                 connman_error("Setting default gateway route failed (%s)",
966                                                         strerror(errno));
967
968         close(sk);
969
970         return err;
971 }
972
973 int connman_inet_set_gateway_interface(int index)
974 {
975         struct ifreq ifr;
976         struct rtentry rt;
977         struct sockaddr_in addr;
978         int sk, err;
979
980         DBG("");
981
982         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
983         if (sk < 0)
984                 return -1;
985
986         memset(&ifr, 0, sizeof(ifr));
987         ifr.ifr_ifindex = index;
988
989         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
990                 close(sk);
991                 return -1;
992         }
993
994         DBG("ifname %s", ifr.ifr_name);
995
996         memset(&rt, 0, sizeof(rt));
997         rt.rt_flags = RTF_UP;
998
999         memset(&addr, 0, sizeof(addr));
1000         addr.sin_family = AF_INET;
1001         addr.sin_addr.s_addr = INADDR_ANY;
1002
1003         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1004         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1005         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1006
1007         rt.rt_dev = ifr.ifr_name;
1008
1009         err = ioctl(sk, SIOCADDRT, &rt);
1010         if (err < 0)
1011                 connman_error("Setting default interface route failed (%s)",
1012                                                         strerror(errno));
1013         close(sk);
1014
1015         return err;
1016 }
1017
1018 int connman_inet_set_ipv6_gateway_interface(int index)
1019 {
1020         struct ifreq ifr;
1021         struct rtentry rt;
1022         struct sockaddr_in6 addr;
1023         const struct in6_addr any = IN6ADDR_ANY_INIT;
1024         int sk, err;
1025
1026         DBG("");
1027
1028         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1029         if (sk < 0)
1030                 return -1;
1031
1032         memset(&ifr, 0, sizeof(ifr));
1033         ifr.ifr_ifindex = index;
1034
1035         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1036                 close(sk);
1037                 return -1;
1038         }
1039
1040         DBG("ifname %s", ifr.ifr_name);
1041
1042         memset(&rt, 0, sizeof(rt));
1043         rt.rt_flags = RTF_UP;
1044
1045         memset(&addr, 0, sizeof(addr));
1046         addr.sin6_family = AF_INET6;
1047         addr.sin6_addr = any;
1048
1049         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1050         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1051         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1052
1053         rt.rt_dev = ifr.ifr_name;
1054
1055         err = ioctl(sk, SIOCADDRT, &rt);
1056         if (err < 0)
1057                 connman_error("Setting default interface route failed (%s)",
1058                                                         strerror(errno));
1059         close(sk);
1060
1061         return err;
1062 }
1063
1064 int connman_inet_clear_gateway_address(int index, const char *gateway)
1065 {
1066         struct ifreq ifr;
1067         struct rtentry rt;
1068         struct sockaddr_in addr;
1069         int sk, err;
1070
1071         DBG("");
1072
1073         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1074         if (sk < 0)
1075                 return -1;
1076
1077         memset(&ifr, 0, sizeof(ifr));
1078         ifr.ifr_ifindex = index;
1079
1080         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1081                 close(sk);
1082                 return -1;
1083         }
1084
1085         DBG("ifname %s", ifr.ifr_name);
1086
1087         memset(&rt, 0, sizeof(rt));
1088         rt.rt_flags = RTF_UP | RTF_GATEWAY;
1089
1090         memset(&addr, 0, sizeof(addr));
1091         addr.sin_family = AF_INET;
1092         addr.sin_addr.s_addr = INADDR_ANY;
1093         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1094
1095         memset(&addr, 0, sizeof(addr));
1096         addr.sin_family = AF_INET;
1097         addr.sin_addr.s_addr = inet_addr(gateway);
1098         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1099
1100         memset(&addr, 0, sizeof(addr));
1101         addr.sin_family = AF_INET;
1102         addr.sin_addr.s_addr = INADDR_ANY;
1103         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1104
1105         err = ioctl(sk, SIOCDELRT, &rt);
1106         if (err < 0)
1107                 connman_error("Removing default gateway route failed (%s)",
1108                                                         strerror(errno));
1109
1110         close(sk);
1111
1112         return err;
1113 }
1114
1115 int connman_inet_clear_gateway_interface(int index)
1116 {
1117         struct ifreq ifr;
1118         struct rtentry rt;
1119         struct sockaddr_in addr;
1120         int sk, err;
1121
1122         DBG("");
1123
1124         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1125         if (sk < 0)
1126                 return -1;
1127
1128         memset(&ifr, 0, sizeof(ifr));
1129         ifr.ifr_ifindex = index;
1130
1131         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1132                 close(sk);
1133                 return -1;
1134         }
1135
1136         DBG("ifname %s", ifr.ifr_name);
1137
1138         memset(&rt, 0, sizeof(rt));
1139         rt.rt_flags = RTF_UP;
1140
1141         memset(&addr, 0, sizeof(addr));
1142         addr.sin_family = AF_INET;
1143         addr.sin_addr.s_addr = INADDR_ANY;
1144
1145         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1146         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1147         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1148
1149         rt.rt_dev = ifr.ifr_name;
1150
1151         err = ioctl(sk, SIOCDELRT, &rt);
1152         if (err < 0)
1153                 connman_error("Removing default interface route failed (%s)",
1154                                                         strerror(errno));
1155         close(sk);
1156
1157         return err;
1158 }
1159
1160 int connman_inet_clear_ipv6_gateway_interface(int index)
1161 {
1162         struct ifreq ifr;
1163         struct rtentry rt;
1164         struct sockaddr_in6 addr;
1165         const struct in6_addr any = IN6ADDR_ANY_INIT;
1166         int sk, err;
1167
1168         DBG("");
1169
1170         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1171         if (sk < 0)
1172                 return -1;
1173
1174         memset(&ifr, 0, sizeof(ifr));
1175         ifr.ifr_ifindex = index;
1176
1177         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1178                 close(sk);
1179                 return -1;
1180         }
1181
1182         DBG("ifname %s", ifr.ifr_name);
1183
1184         memset(&rt, 0, sizeof(rt));
1185         rt.rt_flags = RTF_UP;
1186
1187         memset(&addr, 0, sizeof(addr));
1188         addr.sin6_family = AF_INET6;
1189         addr.sin6_addr = any;
1190
1191         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1192         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1193         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1194
1195         rt.rt_dev = ifr.ifr_name;
1196
1197         err = ioctl(sk, SIOCDELRT, &rt);
1198         if (err < 0)
1199                 connman_error("Removing default interface route failed (%s)",
1200                                                         strerror(errno));
1201         close(sk);
1202
1203         return err;
1204 }
1205
1206 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1207 {
1208         struct ifreq ifr;
1209         struct in_addr _host_addr;
1210         in_addr_t host_addr, netmask_addr, if_addr;
1211         struct sockaddr_in *netmask, *addr;
1212         int sk;
1213
1214         DBG("host %s", host);
1215
1216         if (host == NULL)
1217                 return FALSE;
1218
1219         if (inet_aton(host, &_host_addr) == 0)
1220                 return -1;
1221         host_addr = _host_addr.s_addr;
1222
1223         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1224         if (sk < 0)
1225                 return FALSE;
1226
1227         memset(&ifr, 0, sizeof(ifr));
1228         ifr.ifr_ifindex = index;
1229
1230         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1231                 close(sk);
1232                 return FALSE;
1233         }
1234
1235         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1236                 close(sk);
1237                 return FALSE;
1238         }
1239
1240         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1241         netmask_addr = netmask->sin_addr.s_addr;
1242
1243         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1244                 close(sk);
1245                 return FALSE;
1246         }
1247         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1248         if_addr = addr->sin_addr.s_addr;
1249
1250         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1251 }
1252
1253 int connman_inet_remove_from_bridge(int index, const char *bridge)
1254 {
1255         struct ifreq ifr;
1256         int sk, err;
1257
1258         if (bridge == NULL)
1259                 return -EINVAL;
1260
1261         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1262         if (sk < 0)
1263                 return sk;
1264
1265         memset(&ifr, 0, sizeof(ifr));
1266         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1267         ifr.ifr_ifindex = index;
1268
1269         err = ioctl(sk, SIOCBRDELIF, &ifr);
1270
1271         close(sk);
1272
1273         if (err < 0) {
1274                 connman_error("Remove interface from bridge error %s",
1275                                                         strerror(errno));
1276                 return err;
1277         }
1278
1279         return 0;
1280 }
1281
1282 int connman_inet_add_to_bridge(int index, const char *bridge)
1283 {
1284         struct ifreq ifr;
1285         int sk, err;
1286
1287         if (bridge == NULL)
1288                 return -EINVAL;
1289
1290         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1291         if (sk < 0)
1292                 return sk;
1293
1294         memset(&ifr, 0, sizeof(ifr));
1295         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1296         ifr.ifr_ifindex = index;
1297
1298         err = ioctl(sk, SIOCBRADDIF, &ifr);
1299
1300         close(sk);
1301
1302         if (err < 0) {
1303                 connman_error("Add interface to bridge error %s",
1304                                                         strerror(errno));
1305                 return err;
1306         }
1307
1308         return 0;
1309 }
1310
1311 int connman_inet_set_mtu(int index, int mtu)
1312 {
1313         struct ifreq ifr;
1314         int sk, err;
1315
1316         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1317         if (sk < 0)
1318                 return sk;
1319
1320         memset(&ifr, 0, sizeof(ifr));
1321         ifr.ifr_ifindex = index;
1322
1323         err = ioctl(sk, SIOCGIFNAME, &ifr);
1324         if (err == 0) {
1325                 ifr.ifr_mtu = mtu;
1326                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1327         }
1328
1329         close(sk);
1330         return err;
1331 }
1332
1333 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1334 {
1335         struct ifreq ifr;
1336         int sk, err, index;
1337         __u32 mask;
1338         __u32 flags;
1339
1340         if (tunnel == NULL)
1341                 return -EINVAL;
1342
1343         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1344         if (sk < 0)
1345                 return sk;
1346
1347         index = if_nametoindex(tunnel);
1348
1349         err = connman_inet_set_mtu(index, mtu);
1350         if (err < 0)
1351                 return err;
1352         else if (err)
1353                 goto done;
1354
1355         memset(&ifr, 0, sizeof(ifr));
1356         strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1357         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1358         if (err)
1359                 goto done;
1360
1361         mask = IFF_UP;
1362         flags = IFF_UP;
1363
1364         if ((ifr.ifr_flags ^ flags) & mask) {
1365                 ifr.ifr_flags &= ~mask;
1366                 ifr.ifr_flags |= mask & flags;
1367                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1368                 if (err)
1369                         connman_error("SIOCSIFFLAGS failed: %s",
1370                                                         strerror(errno));
1371         }
1372
1373 done:
1374         close(sk);
1375         return err;
1376 }
1377
1378 int connman_inet_create_tunnel(char **iface)
1379 {
1380         struct ifreq ifr;
1381         int i, fd;
1382
1383         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1384         if (fd < 0) {
1385                 i = -errno;
1386                 connman_error("Failed to open /dev/net/tun: %s",
1387                                 strerror(errno));
1388                 return i;
1389         }
1390
1391         memset(&ifr, 0, sizeof(ifr));
1392         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1393
1394         for (i = 0; i < 256; i++) {
1395                 sprintf(ifr.ifr_name, "tun%d", i);
1396
1397                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1398                         break;
1399         }
1400
1401         if (i == 256) {
1402                 connman_error("Failed to find available tun device");
1403                 close(fd);
1404                 return -ENODEV;
1405         }
1406
1407         *iface = g_strdup(ifr.ifr_name);
1408
1409         return fd;
1410 }
1411
1412 struct rs_cb_data {
1413         GIOChannel *channel;
1414         __connman_inet_rs_cb_t callback;
1415         struct sockaddr_in6 addr;
1416         guint rs_timeout;
1417         void *user_data;
1418 };
1419
1420 #define CMSG_BUF_LEN 512
1421 #define IN6ADDR_ALL_NODES_MC_INIT \
1422         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1423 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1424         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1425
1426 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1427 static const struct in6_addr in6addr_all_routers_mc =
1428                                                 IN6ADDR_ALL_ROUTERS_MC_INIT;
1429
1430 static void rs_cleanup(struct rs_cb_data *data)
1431 {
1432         g_io_channel_shutdown(data->channel, TRUE, NULL);
1433         g_io_channel_unref(data->channel);
1434         data->channel = 0;
1435
1436         if (data->rs_timeout > 0)
1437                 g_source_remove(data->rs_timeout);
1438
1439         g_free(data);
1440 }
1441
1442 static gboolean rs_timeout_cb(gpointer user_data)
1443 {
1444         struct rs_cb_data *data = user_data;
1445
1446         DBG("user data %p", user_data);
1447
1448         if (data == NULL)
1449                 return FALSE;
1450
1451         if (data->callback != NULL)
1452                 data->callback(NULL, data->user_data);
1453
1454         data->rs_timeout = 0;
1455         rs_cleanup(data);
1456         return FALSE;
1457 }
1458
1459 static int icmpv6_recv(int fd, gpointer user_data)
1460 {
1461         struct msghdr mhdr;
1462         struct iovec iov;
1463         unsigned char chdr[CMSG_BUF_LEN];
1464         unsigned char buf[1540];
1465         struct rs_cb_data *data = user_data;
1466         struct nd_router_advert *hdr;
1467         struct sockaddr_in6 saddr;
1468         ssize_t len;
1469
1470         DBG("");
1471
1472         iov.iov_len = sizeof(buf);
1473         iov.iov_base = buf;
1474
1475         mhdr.msg_name = (void *)&saddr;
1476         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1477         mhdr.msg_iov = &iov;
1478         mhdr.msg_iovlen = 1;
1479         mhdr.msg_control = (void *)chdr;
1480         mhdr.msg_controllen = CMSG_BUF_LEN;
1481
1482         len = recvmsg(fd, &mhdr, 0);
1483         if (len < 0) {
1484                 data->callback(NULL, data->user_data);
1485                 rs_cleanup(data);
1486                 return -errno;
1487         }
1488
1489         hdr = (struct nd_router_advert *)buf;
1490         if (hdr->nd_ra_code != 0)
1491                 return 0;
1492
1493         data->callback(hdr, data->user_data);
1494         rs_cleanup(data);
1495
1496         return len;
1497 }
1498
1499 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1500                                                                 gpointer data)
1501 {
1502         int fd, ret;
1503
1504         DBG("");
1505
1506         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1507                 return FALSE;
1508
1509         fd = g_io_channel_unix_get_fd(chan);
1510         ret = icmpv6_recv(fd, data);
1511         if (ret == 0)
1512                 return TRUE;
1513
1514         return FALSE;
1515 }
1516
1517 /* Adapted from RFC 1071 "C" Implementation Example */
1518 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1519 {
1520         register unsigned long sum = 0;
1521         socklen_t count;
1522         uint16_t *addr;
1523         int i;
1524
1525         /* caller must make sure datalen is even */
1526
1527         addr = (uint16_t *)phdr;
1528         for (i = 0; i < 20; i++)
1529                 sum += *addr++;
1530
1531         count = datalen;
1532         addr = (uint16_t *)data;
1533
1534         while (count > 1) {
1535                 sum += *(addr++);
1536                 count -= 2;
1537         }
1538
1539         while (sum >> 16)
1540                 sum = (sum & 0xffff) + (sum >> 16);
1541
1542         return (uint16_t)~sum;
1543 }
1544
1545 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1546 {
1547         struct _phdr {
1548                 struct in6_addr src;
1549                 struct in6_addr dst;
1550                 uint32_t plen;
1551                 uint8_t reserved[3];
1552                 uint8_t nxt;
1553         } phdr;
1554
1555         struct {
1556                 struct ip6_hdr ip;
1557                 union {
1558                         struct icmp6_hdr icmp;
1559                         struct nd_neighbor_solicit ns;
1560                         struct nd_router_solicit rs;
1561                 } i;
1562         } frame;
1563
1564         struct msghdr msgh;
1565         struct cmsghdr *cmsg;
1566         struct in6_pktinfo *pinfo;
1567         struct sockaddr_in6 dst;
1568         char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1569         struct iovec iov;
1570         int fd, datalen, ret;
1571
1572         DBG("");
1573
1574         fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1575         if (fd < 0)
1576                 return -errno;
1577
1578         memset(&frame, 0, sizeof(frame));
1579         memset(&dst, 0, sizeof(dst));
1580
1581         datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1582         dst.sin6_addr = *dest;
1583
1584         /* Fill in the IPv6 header */
1585         frame.ip.ip6_vfc = 0x60;
1586         frame.ip.ip6_plen = htons(datalen);
1587         frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1588         frame.ip.ip6_hlim = 255;
1589         frame.ip.ip6_dst = dst.sin6_addr;
1590         /* all other fields are already set to zero */
1591
1592         /* Prepare pseudo header for csum */
1593         memset(&phdr, 0, sizeof(phdr));
1594         phdr.dst = dst.sin6_addr;
1595         phdr.plen = htonl(datalen);
1596         phdr.nxt = IPPROTO_ICMPV6;
1597
1598         /* Fill in remaining ICMP header fields */
1599         frame.i.icmp.icmp6_type = type;
1600         frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1601
1602         iov.iov_base = &frame;
1603         iov.iov_len = sizeof(frame.ip) + datalen;
1604
1605         dst.sin6_family = AF_INET6;
1606         msgh.msg_name = &dst;
1607         msgh.msg_namelen = sizeof(dst);
1608         msgh.msg_iov = &iov;
1609         msgh.msg_iovlen = 1;
1610         msgh.msg_flags = 0;
1611
1612         memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1613         cmsg = (struct cmsghdr *)cbuf;
1614         pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1615         pinfo->ipi6_ifindex = oif;
1616
1617         cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1618         cmsg->cmsg_level = IPPROTO_IPV6;
1619         cmsg->cmsg_type = IPV6_PKTINFO;
1620         msgh.msg_control = cmsg;
1621         msgh.msg_controllen = cmsg->cmsg_len;
1622
1623         ret = sendmsg(fd, &msgh, 0);
1624
1625         close(fd);
1626         return ret;
1627 }
1628
1629 static inline void ipv6_addr_set(struct in6_addr *addr,
1630                                 uint32_t w1, uint32_t w2,
1631                                 uint32_t w3, uint32_t w4)
1632 {
1633         addr->s6_addr32[0] = w1;
1634         addr->s6_addr32[1] = w2;
1635         addr->s6_addr32[2] = w3;
1636         addr->s6_addr32[3] = w4;
1637 }
1638
1639 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1640                                         struct in6_addr *solicited)
1641 {
1642         ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1643                         htonl(0xFF000000) | addr->s6_addr32[3]);
1644 }
1645
1646 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1647                                                                 int cmd)
1648 {
1649         unsigned int val = 0;
1650         struct ipv6_mreq mreq;
1651         int ret;
1652
1653         memset(&mreq, 0, sizeof(mreq));
1654         mreq.ipv6mr_interface = ifindex;
1655         mreq.ipv6mr_multiaddr = *mc_addr;
1656
1657         ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1658                         &val, sizeof(int));
1659
1660         if (ret < 0)
1661                 return ret;
1662
1663         return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1664 }
1665
1666 int __connman_inet_ipv6_send_rs(int index, int timeout,
1667                         __connman_inet_rs_cb_t callback, void *user_data)
1668 {
1669         struct rs_cb_data *data;
1670         struct icmp6_filter filter;
1671         struct in6_addr solicit;
1672         struct in6_addr dst = in6addr_all_routers_mc;
1673         int sk;
1674
1675         DBG("");
1676
1677         if (timeout <= 0)
1678                 return -EINVAL;
1679
1680         data = g_try_malloc0(sizeof(struct rs_cb_data));
1681         if (data == NULL)
1682                 return -ENOMEM;
1683
1684         data->callback = callback;
1685         data->user_data = user_data;
1686         data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1687
1688         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1689         if (sk < 0)
1690                 return -errno;
1691
1692         ICMP6_FILTER_SETBLOCKALL(&filter);
1693         ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1694
1695         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1696                                                 sizeof(struct icmp6_filter));
1697
1698         ipv6_addr_solict_mult(&dst, &solicit);
1699         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1700         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1701
1702         data->channel = g_io_channel_unix_new(sk);
1703         g_io_channel_set_close_on_unref(data->channel, TRUE);
1704
1705         g_io_channel_set_encoding(data->channel, NULL, NULL);
1706         g_io_channel_set_buffered(data->channel, FALSE);
1707
1708         g_io_add_watch(data->channel,
1709                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1710                         icmpv6_event, data);
1711
1712         ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
1713
1714         return 0;
1715 }