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