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