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