Added logic to get country code of APs
[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_VENDOR:
360         case CONNMAN_DEVICE_TYPE_GPS:
361                 break;
362         case CONNMAN_DEVICE_TYPE_ETHERNET:
363         case CONNMAN_DEVICE_TYPE_GADGET:
364                 ident = index2ident(index, NULL);
365                 break;
366         case CONNMAN_DEVICE_TYPE_WIFI:
367                 ident = index2ident(index, NULL);
368                 break;
369         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
370                 break;
371         case CONNMAN_DEVICE_TYPE_CELLULAR:
372                 ident = index2ident(index, NULL);
373                 break;
374         }
375
376         if (ident != NULL) {
377                 connman_device_set_ident(device, ident);
378                 g_free(ident);
379         }
380
381         if (addr != NULL) {
382                 connman_device_set_string(device, "Address", addr);
383                 g_free(addr);
384         }
385 }
386 #endif
387
388 struct in6_ifreq {
389         struct in6_addr ifr6_addr;
390         __u32 ifr6_prefixlen;
391         unsigned int ifr6_ifindex;
392 };
393
394 int connman_inet_set_ipv6_address(int index,
395                 struct connman_ipaddress *ipaddress)
396 {
397         int err;
398         unsigned char prefix_len;
399         const char *address;
400
401         if (!ipaddress->local)
402                 return 0;
403
404         prefix_len = ipaddress->prefixlen;
405         address = ipaddress->local;
406
407         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
408
409         err = __connman_inet_modify_address(RTM_NEWADDR,
410                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
411                                 address, NULL, prefix_len, NULL);
412         if (err < 0) {
413                 connman_error("%s: %s", __func__, strerror(-err));
414                 return err;
415         }
416
417         return 0;
418 }
419
420 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
421 {
422         int err;
423         unsigned char prefix_len;
424         const char *address, *broadcast, *peer;
425
426         if (!ipaddress->local)
427                 return -1;
428
429         prefix_len = ipaddress->prefixlen;
430         address = ipaddress->local;
431         broadcast = ipaddress->broadcast;
432         peer = ipaddress->peer;
433
434         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
435
436         err = __connman_inet_modify_address(RTM_NEWADDR,
437                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
438                                 address, peer, prefix_len, broadcast);
439         if (err < 0) {
440                 connman_error("%s: %s", __func__, strerror(-err));
441                 return err;
442         }
443
444         return 0;
445 }
446
447 int connman_inet_clear_ipv6_address(int index, const char *address,
448                                                         int prefix_len)
449 {
450         int err;
451
452         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
453
454         if (!address)
455                 return -EINVAL;
456
457         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
458                                 address, NULL, prefix_len, NULL);
459         if (err < 0) {
460                 connman_error("%s: %s", __func__, strerror(-err));
461                 return err;
462         }
463
464         return 0;
465 }
466
467 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
468 {
469         int err;
470         unsigned char prefix_len;
471         const char *address, *broadcast, *peer;
472
473         prefix_len = ipaddress->prefixlen;
474         address = ipaddress->local;
475         broadcast = ipaddress->broadcast;
476         peer = ipaddress->peer;
477
478         DBG("index %d address %s prefix_len %d peer %s broadcast %s", index,
479                 address, prefix_len, peer, broadcast);
480
481         if (!address)
482                 return -EINVAL;
483
484         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
485                                 address, peer, prefix_len, broadcast);
486         if (err < 0) {
487                 connman_error("%s: %s", __func__, strerror(-err));
488                 return err;
489         }
490
491         return 0;
492 }
493
494 int connman_inet_add_host_route(int index, const char *host,
495                                 const char *gateway)
496 {
497         return connman_inet_add_network_route(index, host, gateway, NULL);
498 }
499
500 int connman_inet_del_host_route(int index, const char *host)
501 {
502         return connman_inet_del_network_route(index, host);
503 }
504
505 int connman_inet_add_network_route(int index, const char *host,
506                                         const char *gateway,
507                                         const char *netmask)
508 {
509         struct ifreq ifr;
510         struct rtentry rt;
511         struct sockaddr_in addr;
512         int sk, err = 0;
513
514         DBG("index %d host %s gateway %s netmask %s", index,
515                 host, gateway, netmask);
516
517         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
518         if (sk < 0) {
519                 err = -errno;
520                 goto out;
521         }
522
523         memset(&ifr, 0, sizeof(ifr));
524         ifr.ifr_ifindex = index;
525
526         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
527                 err = -errno;
528                 close(sk);
529                 goto out;
530         }
531
532         DBG("ifname %s", ifr.ifr_name);
533
534         memset(&rt, 0, sizeof(rt));
535         rt.rt_flags = RTF_UP;
536         if (gateway)
537                 rt.rt_flags |= RTF_GATEWAY;
538         if (!netmask)
539                 rt.rt_flags |= RTF_HOST;
540
541         memset(&addr, 0, sizeof(addr));
542         addr.sin_family = AF_INET;
543         addr.sin_addr.s_addr = inet_addr(host);
544         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
545
546         memset(&addr, 0, sizeof(addr));
547         addr.sin_family = AF_INET;
548         if (gateway)
549                 addr.sin_addr.s_addr = inet_addr(gateway);
550         else
551                 addr.sin_addr.s_addr = INADDR_ANY;
552         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
553
554         memset(&addr, 0, sizeof(addr));
555         addr.sin_family = AF_INET;
556         addr.sin_addr.s_addr = INADDR_ANY;
557         if (netmask)
558                 addr.sin_addr.s_addr = inet_addr(netmask);
559         else
560                 addr.sin_addr.s_addr = INADDR_ANY;
561         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
562
563         rt.rt_dev = ifr.ifr_name;
564
565         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
566                 err = -errno;
567
568         close(sk);
569
570 out:
571         if (err < 0)
572                 connman_error("Adding host route failed (%s)",
573                                                         strerror(-err));
574
575         return err;
576 }
577
578 int connman_inet_del_network_route(int index, const char *host)
579 {
580         struct ifreq ifr;
581         struct rtentry rt;
582         struct sockaddr_in addr;
583         int sk, err = 0;
584
585         DBG("index %d host %s", index, host);
586
587         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
588         if (sk < 0) {
589                 err = -errno;
590                 goto out;
591         }
592
593         memset(&ifr, 0, sizeof(ifr));
594         ifr.ifr_ifindex = index;
595
596         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
597                 err = -errno;
598                 close(sk);
599                 goto out;
600         }
601
602         DBG("ifname %s", ifr.ifr_name);
603
604         memset(&rt, 0, sizeof(rt));
605         rt.rt_flags = RTF_UP | RTF_HOST;
606
607         memset(&addr, 0, sizeof(addr));
608         addr.sin_family = AF_INET;
609         addr.sin_addr.s_addr = inet_addr(host);
610         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
611
612         rt.rt_dev = ifr.ifr_name;
613
614         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
615                 err = -errno;
616
617         close(sk);
618
619 out:
620         if (err < 0)
621                 connman_error("Deleting host route failed (%s)",
622                                                         strerror(-err));
623
624         return err;
625 }
626
627 int connman_inet_del_ipv6_network_route(int index, const char *host,
628                                                 unsigned char prefix_len)
629 {
630         struct in6_rtmsg rt;
631         int sk, err = 0;
632
633         DBG("index %d host %s", index, host);
634
635         if (!host)
636                 return -EINVAL;
637
638         memset(&rt, 0, sizeof(rt));
639
640         rt.rtmsg_dst_len = prefix_len;
641
642         if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
643                 err = -errno;
644                 goto out;
645         }
646
647         rt.rtmsg_flags = RTF_UP | RTF_HOST;
648
649         rt.rtmsg_metric = 1;
650         rt.rtmsg_ifindex = index;
651
652         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
653         if (sk < 0) {
654                 err = -errno;
655                 goto out;
656         }
657
658         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
659                 err = -errno;
660
661         close(sk);
662
663 out:
664         if (err < 0)
665                 connman_error("Del IPv6 host route error (%s)",
666                                                 strerror(-err));
667
668         return err;
669 }
670
671 int connman_inet_del_ipv6_host_route(int index, const char *host)
672 {
673         return connman_inet_del_ipv6_network_route(index, host, 128);
674 }
675
676 int connman_inet_add_ipv6_network_route(int index, const char *host,
677                                         const char *gateway,
678                                         unsigned char prefix_len)
679 {
680         struct in6_rtmsg rt;
681         int sk, err = 0;
682
683         DBG("index %d host %s gateway %s", index, host, gateway);
684
685         if (!host)
686                 return -EINVAL;
687
688         memset(&rt, 0, sizeof(rt));
689
690         rt.rtmsg_dst_len = prefix_len;
691
692         if (inet_pton(AF_INET6, host, &rt.rtmsg_dst) < 0) {
693                 err = -errno;
694                 goto out;
695         }
696
697         rt.rtmsg_flags = RTF_UP | RTF_HOST;
698
699         if (gateway) {
700                 rt.rtmsg_flags |= RTF_GATEWAY;
701                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
702         }
703
704         rt.rtmsg_metric = 1;
705         rt.rtmsg_ifindex = index;
706
707         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
708         if (sk < 0) {
709                 err = -errno;
710                 goto out;
711         }
712
713         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
714                 err = -errno;
715
716         close(sk);
717
718 out:
719         if (err < 0)
720                 connman_error("Set IPv6 host route error (%s)",
721                                                 strerror(-err));
722
723         return err;
724 }
725
726 int connman_inet_add_ipv6_host_route(int index, const char *host,
727                                         const char *gateway)
728 {
729         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
730 }
731
732 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
733 {
734         struct in6_rtmsg rt;
735         int sk, err = 0;
736
737         DBG("index %d gateway %s", index, gateway);
738
739         if (!gateway)
740                 return -EINVAL;
741
742         memset(&rt, 0, sizeof(rt));
743
744         if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
745                 err = -errno;
746                 goto out;
747         }
748
749         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
750         rt.rtmsg_metric = 1;
751         rt.rtmsg_dst_len = 0;
752         rt.rtmsg_ifindex = index;
753
754         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
755         if (sk < 0) {
756                 err = -errno;
757                 goto out;
758         }
759
760         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
761                 err = -errno;
762
763         close(sk);
764
765 out:
766         if (err < 0)
767                 connman_error("Clear default IPv6 gateway error (%s)",
768                                                 strerror(-err));
769
770         return err;
771 }
772
773 int connman_inet_set_gateway_interface(int index)
774 {
775         struct ifreq ifr;
776         struct rtentry rt;
777         struct sockaddr_in addr;
778         int sk, err = 0;
779
780         DBG("index %d", index);
781
782         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
783         if (sk < 0) {
784                 err = -errno;
785                 goto out;
786         }
787
788         memset(&ifr, 0, sizeof(ifr));
789         ifr.ifr_ifindex = index;
790
791         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
792                 err = -errno;
793                 close(sk);
794                 goto out;
795         }
796
797         DBG("ifname %s", ifr.ifr_name);
798
799         memset(&rt, 0, sizeof(rt));
800         rt.rt_flags = RTF_UP;
801
802         memset(&addr, 0, sizeof(addr));
803         addr.sin_family = AF_INET;
804         addr.sin_addr.s_addr = INADDR_ANY;
805
806         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
807         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
808         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
809
810         rt.rt_dev = ifr.ifr_name;
811
812         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
813                 err = -errno;
814
815         close(sk);
816
817 out:
818         if (err < 0)
819                 connman_error("Setting default interface route failed (%s)",
820                                                         strerror(-err));
821
822         return err;
823 }
824
825 int connman_inet_set_ipv6_gateway_interface(int index)
826 {
827         struct ifreq ifr;
828         struct rtentry rt;
829         struct sockaddr_in6 addr;
830         const struct in6_addr any = IN6ADDR_ANY_INIT;
831         int sk, err = 0;
832
833         DBG("index %d", index);
834
835         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
836         if (sk < 0) {
837                 err = -errno;
838                 goto out;
839         }
840
841         memset(&ifr, 0, sizeof(ifr));
842         ifr.ifr_ifindex = index;
843
844         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
845                 err = -errno;
846                 close(sk);
847                 goto out;
848         }
849
850         DBG("ifname %s", ifr.ifr_name);
851
852         memset(&rt, 0, sizeof(rt));
853         rt.rt_flags = RTF_UP;
854
855         memset(&addr, 0, sizeof(addr));
856         addr.sin6_family = AF_INET6;
857         addr.sin6_addr = any;
858
859         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
860         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
861         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
862
863         rt.rt_dev = ifr.ifr_name;
864
865         if (ioctl(sk, SIOCADDRT, &rt) < 0 && errno != EEXIST)
866                 err = -errno;
867
868         close(sk);
869
870 out:
871         if (err < 0)
872                 connman_error("Setting default interface route failed (%s)",
873                                                         strerror(-err));
874
875         return err;
876 }
877
878 int connman_inet_clear_gateway_address(int index, const char *gateway)
879 {
880         struct ifreq ifr;
881         struct rtentry rt;
882         struct sockaddr_in addr;
883         int sk, err = 0;
884
885         DBG("index %d gateway %s", index, gateway);
886
887         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
888         if (sk < 0) {
889                 err = -errno;
890                 goto out;
891         }
892
893         memset(&ifr, 0, sizeof(ifr));
894         ifr.ifr_ifindex = index;
895
896         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
897                 err = -errno;
898                 close(sk);
899                 goto out;
900         }
901
902         DBG("ifname %s", ifr.ifr_name);
903
904         memset(&rt, 0, sizeof(rt));
905         rt.rt_flags = RTF_UP | RTF_GATEWAY;
906
907         memset(&addr, 0, sizeof(addr));
908         addr.sin_family = AF_INET;
909         addr.sin_addr.s_addr = INADDR_ANY;
910         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
911
912         memset(&addr, 0, sizeof(addr));
913         addr.sin_family = AF_INET;
914         addr.sin_addr.s_addr = inet_addr(gateway);
915         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
916
917         memset(&addr, 0, sizeof(addr));
918         addr.sin_family = AF_INET;
919         addr.sin_addr.s_addr = INADDR_ANY;
920         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
921
922         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
923                 err = -errno;
924
925         close(sk);
926
927 out:
928         if (err < 0)
929                 connman_error("Removing default gateway route failed (%s)",
930                                                         strerror(-err));
931
932         return err;
933 }
934
935 int connman_inet_clear_gateway_interface(int index)
936 {
937         struct ifreq ifr;
938         struct rtentry rt;
939         struct sockaddr_in addr;
940         int sk, err = 0;
941
942         DBG("index %d", index);
943
944         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
945         if (sk < 0) {
946                 err = -errno;
947                 goto out;
948         }
949
950         memset(&ifr, 0, sizeof(ifr));
951         ifr.ifr_ifindex = index;
952
953         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
954                 err = -errno;
955                 close(sk);
956                 goto out;
957         }
958
959         DBG("ifname %s", ifr.ifr_name);
960
961         memset(&rt, 0, sizeof(rt));
962         rt.rt_flags = RTF_UP;
963
964         memset(&addr, 0, sizeof(addr));
965         addr.sin_family = AF_INET;
966         addr.sin_addr.s_addr = INADDR_ANY;
967
968         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
969         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
970         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
971
972         rt.rt_dev = ifr.ifr_name;
973
974         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
975                 err = -errno;
976
977         close(sk);
978
979 out:
980         if (err < 0)
981                 connman_error("Removing default interface route failed (%s)",
982                                                         strerror(-err));
983
984         return err;
985 }
986
987 int connman_inet_clear_ipv6_gateway_interface(int index)
988 {
989         struct ifreq ifr;
990         struct rtentry rt;
991         struct sockaddr_in6 addr;
992         const struct in6_addr any = IN6ADDR_ANY_INIT;
993         int sk, err = 0;
994
995         DBG("index %d", index);
996
997         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
998         if (sk < 0) {
999                 err = -errno;
1000                 goto out;
1001         }
1002
1003         memset(&ifr, 0, sizeof(ifr));
1004         ifr.ifr_ifindex = index;
1005
1006         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1007                 err = -errno;
1008                 close(sk);
1009                 goto out;
1010         }
1011
1012         DBG("ifname %s", ifr.ifr_name);
1013
1014         memset(&rt, 0, sizeof(rt));
1015         rt.rt_flags = RTF_UP;
1016
1017         memset(&addr, 0, sizeof(addr));
1018         addr.sin6_family = AF_INET6;
1019         addr.sin6_addr = any;
1020
1021         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1022         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1023         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1024
1025         rt.rt_dev = ifr.ifr_name;
1026
1027         if (ioctl(sk, SIOCDELRT, &rt) < 0 && errno != ESRCH)
1028                 err = -errno;
1029
1030         close(sk);
1031
1032 out:
1033         if (err < 0)
1034                 connman_error("Removing default interface route failed (%s)",
1035                                                         strerror(-err));
1036
1037         return err;
1038 }
1039
1040 bool connman_inet_compare_subnet(int index, const char *host)
1041 {
1042         struct ifreq ifr;
1043         struct in_addr _host_addr;
1044         in_addr_t host_addr, netmask_addr, if_addr;
1045         struct sockaddr_in *netmask, *addr;
1046         int sk;
1047
1048         DBG("host %s", host);
1049
1050         if (!host)
1051                 return false;
1052
1053         if (inet_aton(host, &_host_addr) == 0)
1054                 return -1;
1055         host_addr = _host_addr.s_addr;
1056
1057         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1058         if (sk < 0)
1059                 return false;
1060
1061         memset(&ifr, 0, sizeof(ifr));
1062         ifr.ifr_ifindex = index;
1063
1064         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1065                 close(sk);
1066                 return false;
1067         }
1068
1069         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1070                 close(sk);
1071                 return false;
1072         }
1073
1074         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1075         netmask_addr = netmask->sin_addr.s_addr;
1076
1077         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1078                 close(sk);
1079                 return false;
1080         }
1081
1082         close(sk);
1083
1084         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1085         if_addr = addr->sin_addr.s_addr;
1086
1087         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1088 }
1089
1090 int connman_inet_remove_from_bridge(int index, const char *bridge)
1091 {
1092         struct ifreq ifr;
1093         int sk, err = 0;
1094
1095         if (!bridge)
1096                 return -EINVAL;
1097
1098         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1099         if (sk < 0) {
1100                 err = -errno;
1101                 goto out;
1102         }
1103
1104         memset(&ifr, 0, sizeof(ifr));
1105         strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1106         ifr.ifr_ifindex = index;
1107
1108         if (ioctl(sk, SIOCBRDELIF, &ifr) < 0)
1109                 err = -errno;
1110
1111         close(sk);
1112
1113 out:
1114         if (err < 0)
1115                 connman_error("Remove interface from bridge error %s",
1116                                                         strerror(-err));
1117
1118         return err;
1119 }
1120
1121 int connman_inet_add_to_bridge(int index, const char *bridge)
1122 {
1123         struct ifreq ifr;
1124         int sk, err = 0;
1125
1126         if (!bridge)
1127                 return -EINVAL;
1128
1129         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1130         if (sk < 0) {
1131                 err = -errno;
1132                 goto out;
1133         }
1134
1135         memset(&ifr, 0, sizeof(ifr));
1136         strncpy(ifr.ifr_name, bridge, sizeof(ifr.ifr_name) - 1);
1137         ifr.ifr_ifindex = index;
1138
1139         if (ioctl(sk, SIOCBRADDIF, &ifr) < 0)
1140                 err = -errno;
1141
1142         close(sk);
1143
1144 out:
1145         if (err < 0)
1146                 connman_error("Add interface to bridge error %s",
1147                                                         strerror(-err));
1148
1149         return err;
1150 }
1151
1152 int connman_inet_set_mtu(int index, int mtu)
1153 {
1154         struct ifreq ifr;
1155         int sk, err;
1156
1157         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1158         if (sk < 0)
1159                 return sk;
1160
1161         memset(&ifr, 0, sizeof(ifr));
1162         ifr.ifr_ifindex = index;
1163
1164         err = ioctl(sk, SIOCGIFNAME, &ifr);
1165         if (err == 0) {
1166                 ifr.ifr_mtu = mtu;
1167                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1168         }
1169
1170         close(sk);
1171         return err;
1172 }
1173
1174 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1175 {
1176         struct ifreq ifr;
1177         int sk, err, index;
1178         __u32 mask;
1179         __u32 flags;
1180
1181         if (!tunnel)
1182                 return -EINVAL;
1183
1184         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1185         if (sk < 0)
1186                 return sk;
1187
1188         index = if_nametoindex(tunnel);
1189
1190         err = connman_inet_set_mtu(index, mtu);
1191         if (err != 0)
1192                 goto done;
1193
1194         memset(&ifr, 0, sizeof(ifr));
1195         strncpy(ifr.ifr_name, tunnel, sizeof(ifr.ifr_name) - 1);
1196         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1197         if (err)
1198                 goto done;
1199
1200         mask = IFF_UP;
1201         flags = IFF_UP;
1202
1203         if ((ifr.ifr_flags ^ flags) & mask) {
1204                 ifr.ifr_flags &= ~mask;
1205                 ifr.ifr_flags |= mask & flags;
1206                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1207                 if (err)
1208                         connman_error("SIOCSIFFLAGS failed: %s",
1209                                                         strerror(errno));
1210         }
1211
1212 done:
1213         close(sk);
1214         return err;
1215 }
1216
1217 int connman_inet_create_tunnel(char **iface)
1218 {
1219         struct ifreq ifr;
1220         int i, fd;
1221
1222         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1223         if (fd < 0) {
1224                 i = -errno;
1225                 connman_error("Failed to open /dev/net/tun: %s",
1226                                 strerror(errno));
1227                 return i;
1228         }
1229
1230         memset(&ifr, 0, sizeof(ifr));
1231         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1232
1233         for (i = 0; i < 256; i++) {
1234                 sprintf(ifr.ifr_name, "tun%d", i);
1235
1236                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1237                         break;
1238         }
1239
1240         if (i == 256) {
1241                 connman_error("Failed to find available tun device");
1242                 close(fd);
1243                 return -ENODEV;
1244         }
1245
1246         *iface = g_strdup(ifr.ifr_name);
1247
1248         return fd;
1249 }
1250
1251 /*
1252  * This callback struct is used when sending router and neighbor
1253  * solicitation and advertisement messages.
1254  */
1255 struct xs_cb_data {
1256         GIOChannel *channel;
1257         void *callback;
1258         struct sockaddr_in6 addr;
1259         guint timeout;
1260         guint watch_id;
1261         void *user_data;
1262 };
1263
1264 #define CMSG_BUF_LEN 512
1265 #define IN6ADDR_ALL_NODES_MC_INIT \
1266         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1267 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1268         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1269
1270 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1271 static const struct in6_addr in6addr_all_routers_mc =
1272                                                 IN6ADDR_ALL_ROUTERS_MC_INIT;
1273
1274 static void xs_cleanup(struct xs_cb_data *data)
1275 {
1276         if (data->channel) {
1277                 g_io_channel_shutdown(data->channel, TRUE, NULL);
1278                 g_io_channel_unref(data->channel);
1279                 data->channel = NULL;
1280         }
1281
1282         if (data->timeout > 0)
1283                 g_source_remove(data->timeout);
1284
1285         if (data->watch_id > 0)
1286                 g_source_remove(data->watch_id);
1287
1288         g_free(data);
1289 }
1290
1291 static gboolean rs_timeout_cb(gpointer user_data)
1292 {
1293         struct xs_cb_data *data = user_data;
1294
1295         DBG("user data %p", user_data);
1296
1297         if (!data)
1298                 return FALSE;
1299
1300         if (data->callback) {
1301                 __connman_inet_rs_cb_t cb = data->callback;
1302                 cb(NULL, 0, data->user_data);
1303         }
1304
1305         data->timeout = 0;
1306         xs_cleanup(data);
1307         return FALSE;
1308 }
1309
1310 static int icmpv6_recv(int fd, struct xs_cb_data *data)
1311 {
1312         struct msghdr mhdr;
1313         struct iovec iov;
1314         unsigned char chdr[CMSG_BUF_LEN];
1315         unsigned char buf[1540];
1316         struct nd_router_advert *hdr;
1317         struct sockaddr_in6 saddr;
1318         ssize_t len;
1319         __connman_inet_rs_cb_t cb = data->callback;
1320
1321         DBG("");
1322
1323         iov.iov_len = sizeof(buf);
1324         iov.iov_base = buf;
1325
1326         mhdr.msg_name = (void *)&saddr;
1327         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1328         mhdr.msg_flags = 0;
1329         mhdr.msg_iov = &iov;
1330         mhdr.msg_iovlen = 1;
1331         mhdr.msg_control = (void *)chdr;
1332         mhdr.msg_controllen = CMSG_BUF_LEN;
1333
1334         len = recvmsg(fd, &mhdr, 0);
1335         if (len < 0) {
1336                 cb(NULL, 0, data->user_data);
1337                 return -errno;
1338         }
1339
1340 #if defined TIZEN_EXT
1341         /* Set Received Source Address from router as IPv6 Gateway Address */
1342         char src_addr[INET6_ADDRSTRLEN];
1343         if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
1344                         == NULL) {
1345                 xs_cleanup(data);
1346                 return -errno;
1347         }
1348         DBG("Received Source Address %s from router", src_addr);
1349
1350         /* icmpv6_recv() function can be called in two scenarios :
1351          * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
1352          * 2. When __connman_inet_ipv6_send_rs() is called from
1353          * __connman_6to4_probe()
1354          * In the second case it is not  required to set DHCPv6 Gateway  Address
1355          * as DHCPv6 was not started and  network structure was not passed as
1356          * user_data. If it is tried  to add Source Address as  Gateway Address
1357          * then it will lead to  crash because of  user_data being ip_address
1358          * instead of network structure. So Adding Gateway Address in case 1st
1359          * case only.
1360          */
1361         char *address = data->user_data;
1362         int err = 0;
1363         unsigned char buffer[sizeof(struct in6_addr)] = {0, };
1364         /* Checking if user_data is an ip_address */
1365         err = inet_pton(AF_INET, address, buffer);
1366         /* Setting Received Source Address from
1367          * router as Gateway Address */
1368         if(err <= 0)
1369                 __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
1370 #endif
1371         hdr = (struct nd_router_advert *)buf;
1372         DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1373                                 sizeof(struct nd_router_advert));
1374         if (hdr->nd_ra_code != 0)
1375                 return 0;
1376
1377         cb(hdr, len, data->user_data);
1378
1379         return len;
1380 }
1381
1382 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1383 {
1384         int fd, ret;
1385         struct xs_cb_data *xs_data = data;
1386
1387         DBG("");
1388
1389         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1390                 goto cleanup;
1391
1392         fd = g_io_channel_unix_get_fd(chan);
1393         ret = icmpv6_recv(fd, xs_data);
1394         if (ret == 0)
1395                 return TRUE;
1396
1397 cleanup:
1398         xs_cleanup(xs_data);
1399         return TRUE;
1400 }
1401
1402 /* Adapted from RFC 1071 "C" Implementation Example */
1403 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen,
1404                 const void *extra_data, socklen_t extra_datalen)
1405 {
1406         register unsigned long sum = 0;
1407         socklen_t count;
1408         uint16_t *addr;
1409         int i;
1410
1411         /* caller must make sure datalen is even */
1412
1413         addr = (uint16_t *)phdr;
1414         for (i = 0; i < 20; i++)
1415                 sum += *addr++;
1416
1417         count = datalen;
1418         addr = (uint16_t *)data;
1419
1420         while (count > 1) {
1421                 sum += *(addr++);
1422                 count -= 2;
1423         }
1424
1425         if (extra_data) {
1426                 count = extra_datalen;
1427                 addr = (uint16_t *)extra_data;
1428
1429                 while (count > 1) {
1430                         sum += *(addr++);
1431                         count -= 2;
1432                 }
1433         }
1434
1435         while (sum >> 16)
1436                 sum = (sum & 0xffff) + (sum >> 16);
1437
1438         return (uint16_t)~sum;
1439 }
1440
1441 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
1442                         const struct in6_addr *source,
1443                         unsigned char *buf, size_t len, uint16_t lifetime)
1444 {
1445         struct _phdr {
1446                 struct in6_addr src;
1447                 struct in6_addr dst;
1448                 uint32_t plen;
1449                 uint8_t reserved[3];
1450                 uint8_t nxt;
1451         } phdr;
1452
1453         struct {
1454                 struct ip6_hdr ip;
1455                 union {
1456                         struct icmp6_hdr icmp;
1457                         struct nd_neighbor_solicit ns;
1458                         struct nd_router_solicit rs;
1459                         struct nd_router_advert ra;
1460                 } i;
1461         } frame;
1462
1463         struct msghdr msgh;
1464         struct cmsghdr *cmsg;
1465         struct in6_pktinfo *pinfo;
1466         struct sockaddr_in6 dst, src;
1467         char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1468         struct iovec iov[2];
1469         int fd, datalen, ret, iovlen = 1;
1470 #if defined TIZEN_EXT
1471         char ebuf[256];
1472 #endif
1473
1474         DBG("");
1475
1476         fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1477         if (fd < 0)
1478                 return -errno;
1479
1480         memset(&frame, 0, sizeof(frame));
1481         memset(&dst, 0, sizeof(dst));
1482
1483         if (type == ND_ROUTER_SOLICIT)
1484                 datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1485         else if (type == ND_ROUTER_ADVERT) {
1486                 datalen = sizeof(frame.i.ra); /* 16, csum() safe */
1487                 frame.i.ra.nd_ra_router_lifetime = htons(lifetime);
1488         } else if (type == ND_NEIGHBOR_SOLICIT) {
1489                 datalen = sizeof(frame.i.ns); /* 24, csum() safe */
1490                 memcpy(&frame.i.ns.nd_ns_target, buf, sizeof(struct in6_addr));
1491         } else {
1492                 close(fd);
1493                 return -EINVAL;
1494         }
1495
1496         dst.sin6_addr = *dest;
1497
1498         if (source)
1499                 src.sin6_addr = *source;
1500         else
1501                 src.sin6_addr = in6addr_any;
1502
1503         /* Fill in the IPv6 header */
1504         frame.ip.ip6_vfc = 0x60;
1505         frame.ip.ip6_plen = htons(datalen + len);
1506         frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1507         frame.ip.ip6_hlim = 255;
1508         frame.ip.ip6_dst = dst.sin6_addr;
1509         frame.ip.ip6_src = src.sin6_addr;
1510         /* all other fields are already set to zero */
1511
1512         /* Prepare pseudo header for csum */
1513         memset(&phdr, 0, sizeof(phdr));
1514         phdr.dst = dst.sin6_addr;
1515         phdr.src = src.sin6_addr;
1516         phdr.plen = htonl(datalen + len);
1517         phdr.nxt = IPPROTO_ICMPV6;
1518
1519         /* Fill in remaining ICMP header fields */
1520         frame.i.icmp.icmp6_type = type;
1521         frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen, buf, len);
1522
1523         iov[0].iov_base = &frame;
1524         iov[0].iov_len = sizeof(frame.ip) + datalen;
1525
1526         if (buf) {
1527                 iov[1].iov_base = buf;
1528                 iov[1].iov_len = len;
1529                 iovlen = 2;
1530         }
1531
1532         dst.sin6_family = AF_INET6;
1533         msgh.msg_name = &dst;
1534         msgh.msg_namelen = sizeof(dst);
1535         msgh.msg_iov = iov;
1536         msgh.msg_iovlen = iovlen;
1537         msgh.msg_flags = 0;
1538
1539         memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1540         cmsg = (struct cmsghdr *)cbuf;
1541         pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1542         pinfo->ipi6_ifindex = oif;
1543
1544         cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1545         cmsg->cmsg_level = IPPROTO_IPV6;
1546         cmsg->cmsg_type = IPV6_PKTINFO;
1547         msgh.msg_control = cmsg;
1548         msgh.msg_controllen = cmsg->cmsg_len;
1549
1550         ret = sendmsg(fd, &msgh, 0);
1551 #if defined TIZEN_EXT
1552         DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
1553 #endif
1554
1555         close(fd);
1556         return ret;
1557 }
1558
1559 static inline void ipv6_addr_set(struct in6_addr *addr,
1560                                 uint32_t w1, uint32_t w2,
1561                                 uint32_t w3, uint32_t w4)
1562 {
1563         addr->s6_addr32[0] = w1;
1564         addr->s6_addr32[1] = w2;
1565         addr->s6_addr32[2] = w3;
1566         addr->s6_addr32[3] = w4;
1567 }
1568
1569 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1570                                         struct in6_addr *solicited)
1571 {
1572         ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1573                         htonl(0xFF000000) | addr->s6_addr32[3]);
1574 }
1575
1576 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1577                                                                 int cmd)
1578 {
1579         unsigned int val = 0;
1580         struct ipv6_mreq mreq;
1581         int ret;
1582
1583         memset(&mreq, 0, sizeof(mreq));
1584         mreq.ipv6mr_interface = ifindex;
1585         mreq.ipv6mr_multiaddr = *mc_addr;
1586
1587         ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1588                         &val, sizeof(int));
1589         if (ret < 0) {
1590                 ret = -errno;
1591                 DBG("Cannot set IPV6_MULTICAST_LOOP %d/%s", ret,
1592                         strerror(-ret));
1593                 return ret;
1594         }
1595
1596         ret = setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1597         if (ret < 0) {
1598                 ret = -errno;
1599                 DBG("Cannot set option %d %d/%s", cmd, ret, strerror(-ret));
1600                 return ret;
1601         }
1602
1603         return 0;
1604 }
1605
1606 int __connman_inet_ipv6_send_rs(int index, int timeout,
1607                         __connman_inet_rs_cb_t callback, void *user_data)
1608 {
1609         struct xs_cb_data *data;
1610         struct icmp6_filter filter;
1611         struct in6_addr solicit;
1612         struct in6_addr dst = in6addr_all_routers_mc;
1613         int sk;
1614
1615         if (timeout <= 0)
1616                 return -EINVAL;
1617
1618         data = g_try_malloc0(sizeof(struct xs_cb_data));
1619         if (!data)
1620                 return -ENOMEM;
1621
1622         data->callback = callback;
1623         data->user_data = user_data;
1624         data->timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1625
1626         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1627         if (sk < 0)
1628                 return -errno;
1629
1630         DBG("sock %d", sk);
1631
1632         ICMP6_FILTER_SETBLOCKALL(&filter);
1633         ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1634
1635         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1636                                                 sizeof(struct icmp6_filter));
1637
1638         ipv6_addr_solict_mult(&dst, &solicit);
1639         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1640         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1641
1642         data->channel = g_io_channel_unix_new(sk);
1643         g_io_channel_set_close_on_unref(data->channel, TRUE);
1644
1645         g_io_channel_set_encoding(data->channel, NULL, NULL);
1646         g_io_channel_set_buffered(data->channel, FALSE);
1647
1648         data->watch_id = g_io_add_watch(data->channel,
1649                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1650                         icmpv6_event, data);
1651
1652         ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst, NULL, NULL, 0, 0);
1653
1654         return 0;
1655 }
1656
1657 static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
1658                                         struct in6_addr *advert)
1659 {
1660         ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
1661                         htonl(0xFF000000) | addr->s6_addr32[3]);
1662 }
1663
1664 #define MSG_SIZE_SEND 1452
1665
1666 static int inc_len(int len, int inc)
1667 {
1668         if (len > MSG_SIZE_SEND)
1669                 return -EINVAL;
1670
1671         len += inc;
1672         return len;
1673 }
1674
1675 int __connman_inet_ipv6_send_ra(int index, struct in6_addr *src_addr,
1676                                 GSList *prefixes, int router_lifetime)
1677 {
1678         GSList *list;
1679         struct in6_addr src, *source;
1680         struct in6_addr dst = in6addr_all_nodes_mc;
1681         GDHCPIAPrefix *prefix;
1682         unsigned char buf[MSG_SIZE_SEND];
1683         char addr_str[INET6_ADDRSTRLEN];
1684         int sk, err = 0;
1685         int len, count = 0;
1686
1687         if (!prefixes)
1688                 return -EINVAL;
1689
1690         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1691         if (sk < 0)
1692                 return -errno;
1693
1694         if (!src_addr) {
1695                 __connman_inet_get_interface_ll_address(index, AF_INET6, &src);
1696                 source = &src;
1697         } else
1698                 source = src_addr;
1699
1700         DBG("sock %d index %d prefixes %p src %s lifetime %d", sk, index,
1701                 prefixes, inet_ntop(AF_INET6, source, addr_str,
1702                                 INET6_ADDRSTRLEN),
1703                 router_lifetime);
1704
1705         memset(buf, 0, MSG_SIZE_SEND);
1706         len = 0;
1707
1708         for (list = prefixes; list; list = list->next) {
1709                 struct nd_opt_prefix_info *pinfo;
1710
1711                 prefix = list->data;
1712                 pinfo = (struct nd_opt_prefix_info *)(buf + len);
1713
1714                 len = inc_len(len, sizeof(*pinfo));
1715                 if (len < 0) {
1716                         err = len;
1717                         goto out;
1718                 }
1719
1720                 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
1721                 pinfo->nd_opt_pi_len = 4;
1722                 pinfo->nd_opt_pi_prefix_len = prefix->prefixlen;
1723                 pinfo->nd_opt_pi_flags_reserved = ND_OPT_PI_FLAG_ONLINK;
1724                 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
1725                 if (router_lifetime > 0) {
1726                         pinfo->nd_opt_pi_valid_time = htonl(prefix->valid);
1727                         pinfo->nd_opt_pi_preferred_time =
1728                                                 htonl(prefix->preferred);
1729                 }
1730                 pinfo->nd_opt_pi_reserved2 = 0;
1731
1732                 memcpy(&pinfo->nd_opt_pi_prefix, &prefix->prefix,
1733                                                 sizeof(struct in6_addr));
1734
1735                 DBG("[%d] index %d prefix %s/%d", count, index,
1736                         inet_ntop(AF_INET6, &prefix->prefix, addr_str,
1737                                 INET6_ADDRSTRLEN), prefix->prefixlen);
1738
1739                 count++;
1740         }
1741
1742         if (count > 0) {
1743                 err = ndisc_send_unspec(ND_ROUTER_ADVERT, index, &dst, source,
1744                                         buf, len, router_lifetime);
1745                 if (err < 0)
1746                         DBG("cannot send RA %d/%s", err, strerror(-err));
1747         }
1748
1749 out:
1750         close(sk);
1751         return err;
1752 }
1753
1754 void __connman_inet_ipv6_stop_recv_rs(void *context)
1755 {
1756         if (!context)
1757                 return;
1758
1759         xs_cleanup(context);
1760 }
1761
1762 static int icmpv6_rs_recv(int fd, struct xs_cb_data *data)
1763 {
1764         struct msghdr mhdr;
1765         struct iovec iov;
1766         unsigned char chdr[CMSG_BUF_LEN];
1767         unsigned char buf[1540];
1768         struct nd_router_solicit *hdr;
1769         struct sockaddr_in6 saddr;
1770         ssize_t len;
1771         __connman_inet_recv_rs_cb_t cb = data->callback;
1772
1773         DBG("");
1774
1775         iov.iov_len = sizeof(buf);
1776         iov.iov_base = buf;
1777
1778         mhdr.msg_name = (void *)&saddr;
1779         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1780         mhdr.msg_flags = 0;
1781         mhdr.msg_iov = &iov;
1782         mhdr.msg_iovlen = 1;
1783         mhdr.msg_control = (void *)chdr;
1784         mhdr.msg_controllen = CMSG_BUF_LEN;
1785
1786         len = recvmsg(fd, &mhdr, 0);
1787         if (len < 0) {
1788                 cb(NULL, 0, data->user_data);
1789                 return -errno;
1790         }
1791
1792         hdr = (struct nd_router_solicit *)buf;
1793         DBG("code %d len %zd hdr %zd", hdr->nd_rs_code, len,
1794                                 sizeof(struct nd_router_solicit));
1795         if (hdr->nd_rs_code != 0)
1796                 return 0;
1797
1798         cb(hdr, len, data->user_data);
1799         return len;
1800 }
1801
1802 static gboolean icmpv6_rs_event(GIOChannel *chan, GIOCondition cond,
1803                                                                 gpointer data)
1804 {
1805         int fd, ret;
1806         struct xs_cb_data *xs_data = data;
1807
1808         DBG("");
1809
1810         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1811                 goto cleanup;
1812
1813         fd = g_io_channel_unix_get_fd(chan);
1814         ret = icmpv6_rs_recv(fd, xs_data);
1815         if (ret == 0)
1816                 return TRUE;
1817
1818 cleanup:
1819         xs_data->watch_id = 0;
1820         return FALSE;
1821 }
1822
1823 int __connman_inet_ipv6_start_recv_rs(int index,
1824                                         __connman_inet_recv_rs_cb_t callback,
1825                                         void *user_data,
1826                                         void **context)
1827 {
1828         struct xs_cb_data *data;
1829         struct icmp6_filter filter;
1830         char addr_str[INET6_ADDRSTRLEN];
1831         int sk, err;
1832
1833         data = g_try_malloc0(sizeof(struct xs_cb_data));
1834         if (!data)
1835                 return -ENOMEM;
1836
1837         data->callback = callback;
1838         data->user_data = user_data;
1839
1840         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1841         if (sk < 0) {
1842                 g_free(data);
1843                 return -errno;
1844         }
1845
1846         DBG("sock %d", sk);
1847
1848         ICMP6_FILTER_SETBLOCKALL(&filter);
1849         ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
1850
1851         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1852                                                 sizeof(struct icmp6_filter));
1853
1854         err = if_mc_group(sk, index, &in6addr_all_routers_mc, IPV6_JOIN_GROUP);
1855         if (err < 0)
1856                 DBG("Cannot join mc %s %d/%s", inet_ntop(AF_INET6,
1857                         &in6addr_all_routers_mc, addr_str, INET6_ADDRSTRLEN),
1858                         err, strerror(-err));
1859
1860         data->channel = g_io_channel_unix_new(sk);
1861         g_io_channel_set_close_on_unref(data->channel, TRUE);
1862
1863         g_io_channel_set_encoding(data->channel, NULL, NULL);
1864         g_io_channel_set_buffered(data->channel, FALSE);
1865
1866         data->watch_id = g_io_add_watch(data->channel,
1867                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1868                         icmpv6_rs_event, data);
1869
1870         *context = data;
1871
1872         return 0;
1873 }
1874
1875 static gboolean ns_timeout_cb(gpointer user_data)
1876 {
1877         struct xs_cb_data *data = user_data;
1878
1879         DBG("user data %p", user_data);
1880
1881         if (!data)
1882                 return FALSE;
1883
1884         if (data->callback) {
1885                 __connman_inet_ns_cb_t cb = data->callback;
1886                 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1887         }
1888
1889         data->timeout = 0;
1890         xs_cleanup(data);
1891         return FALSE;
1892 }
1893
1894 static int icmpv6_nd_recv(int fd, struct xs_cb_data *data)
1895 {
1896         struct msghdr mhdr;
1897         struct iovec iov;
1898         unsigned char chdr[CMSG_BUF_LEN];
1899         unsigned char buf[1540];
1900         struct nd_neighbor_advert *hdr;
1901         struct sockaddr_in6 saddr;
1902         ssize_t len;
1903         __connman_inet_ns_cb_t cb = data->callback;
1904
1905         DBG("");
1906
1907         iov.iov_len = sizeof(buf);
1908         iov.iov_base = buf;
1909
1910         mhdr.msg_name = (void *)&saddr;
1911         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1912         mhdr.msg_flags = 0;
1913         mhdr.msg_iov = &iov;
1914         mhdr.msg_iovlen = 1;
1915         mhdr.msg_control = (void *)chdr;
1916         mhdr.msg_controllen = CMSG_BUF_LEN;
1917
1918         len = recvmsg(fd, &mhdr, 0);
1919         if (len < 0) {
1920                 cb(NULL, 0, &data->addr.sin6_addr, data->user_data);
1921                 return -errno;
1922         }
1923
1924         hdr = (struct nd_neighbor_advert *)buf;
1925         DBG("code %d len %zd hdr %zd", hdr->nd_na_code, len,
1926                                 sizeof(struct nd_neighbor_advert));
1927         if (hdr->nd_na_code != 0)
1928                 return 0;
1929
1930         /*
1931          * We can receive any neighbor advertisement so we need to check if the
1932          * packet was meant for us and ignore the packet otherwise.
1933          */
1934         if (memcmp(&data->addr.sin6_addr, &hdr->nd_na_target,
1935                         sizeof(struct in6_addr)))
1936                 return 0;
1937
1938         cb(hdr, len, &data->addr.sin6_addr, data->user_data);
1939
1940         return len;
1941 }
1942
1943 static gboolean icmpv6_nd_event(GIOChannel *chan, GIOCondition cond,
1944                                                                 gpointer data)
1945 {
1946         int fd, ret;
1947         struct xs_cb_data *xs_data = data;
1948
1949         DBG("");
1950
1951         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1952                 goto cleanup;
1953
1954         fd = g_io_channel_unix_get_fd(chan);
1955         ret = icmpv6_nd_recv(fd, xs_data);
1956         if (ret == 0)
1957                 return TRUE;
1958
1959 cleanup:
1960         xs_cleanup(xs_data);
1961         return TRUE;
1962 }
1963
1964 int __connman_inet_ipv6_do_dad(int index, int timeout_ms,
1965                                 struct in6_addr *addr,
1966                                 __connman_inet_ns_cb_t callback,
1967                                 void *user_data)
1968 {
1969         struct xs_cb_data *data;
1970         struct icmp6_filter filter;
1971         struct in6_addr solicit;
1972         int sk, err, val = 1;
1973
1974         if (timeout_ms <= 0)
1975                 return -EINVAL;
1976
1977         data = g_try_malloc0(sizeof(struct xs_cb_data));
1978         if (!data)
1979                 return -ENOMEM;
1980
1981         data->callback = callback;
1982         data->user_data = user_data;
1983         data->timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
1984                                         (guint)timeout_ms,
1985                                         ns_timeout_cb,
1986                                         data,
1987                                         NULL);
1988         memcpy(&data->addr.sin6_addr, addr, sizeof(struct in6_addr));
1989
1990         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1991         if (sk < 0)
1992                 return -errno;
1993
1994         DBG("sock %d", sk);
1995
1996         ICMP6_FILTER_SETBLOCKALL(&filter);
1997         ICMP6_FILTER_SETPASS(ND_NEIGHBOR_ADVERT, &filter);
1998
1999         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
2000                                                 sizeof(struct icmp6_filter));
2001
2002         if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVPKTINFO,
2003                                                 &val, sizeof(val)) < 0) {
2004                 err = -errno;
2005                 DBG("Cannot set IPV6_RECVPKTINFO %d/%s", err,
2006                                                         strerror(-err));
2007                 close(sk);
2008                 return err;
2009         }
2010
2011         if (setsockopt(sk, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
2012                                                 &val, sizeof(val)) < 0) {
2013                 err = -errno;
2014                 DBG("Cannot set IPV6_RECVHOPLIMIT %d/%s", err,
2015                                                         strerror(-err));
2016                 close(sk);
2017                 return err;
2018         }
2019
2020         val = 0;
2021         setsockopt(sk, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &val, sizeof(val));
2022
2023         ipv6_addr_solict_mult(addr, &solicit);
2024         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
2025         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
2026
2027         data->channel = g_io_channel_unix_new(sk);
2028         g_io_channel_set_close_on_unref(data->channel, TRUE);
2029
2030         g_io_channel_set_encoding(data->channel, NULL, NULL);
2031         g_io_channel_set_buffered(data->channel, FALSE);
2032
2033         data->watch_id = g_io_add_watch(data->channel,
2034                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2035                         icmpv6_nd_event, data);
2036
2037         err = ndisc_send_unspec(ND_NEIGHBOR_SOLICIT, index, &solicit, NULL,
2038                         (unsigned char *)addr, 0, 0);
2039         if (err < 0) {
2040                 DBG("Cannot send NS %d/%s", err, strerror(-err));
2041                 xs_cleanup(data);
2042         }
2043
2044         return err;
2045 }
2046
2047 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
2048                                         unsigned int length)
2049 {
2050         GSList *prefixes = NULL;
2051         uint8_t *pos;
2052         int len;
2053
2054         if (length <= sizeof(struct nd_router_advert))
2055                 return NULL;
2056
2057         len = length - sizeof(struct nd_router_advert);
2058         pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
2059
2060         while (len > 0) {
2061                 struct nd_opt_prefix_info *pinfo;
2062                 char prefix_str[INET6_ADDRSTRLEN+1], *str;
2063                 const char *prefix;
2064                 int optlen;
2065
2066                 if (len < 2)
2067                         break;
2068
2069                 optlen = pos[1] << 3;
2070                 if (optlen == 0 || optlen > len)
2071                         break;
2072
2073                 switch (pos[0]) {
2074                 case ND_OPT_PREFIX_INFORMATION:
2075                         pinfo = (struct nd_opt_prefix_info *)pos;
2076                         prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
2077                                         prefix_str, INET6_ADDRSTRLEN);
2078                         if (!prefix)
2079                                 break;
2080
2081                         str = g_strdup_printf("%s/%d", prefix,
2082                                                 pinfo->nd_opt_pi_prefix_len);
2083                         prefixes = g_slist_prepend(prefixes, str);
2084
2085                         DBG("prefix %s", str);
2086
2087                         break;
2088                 }
2089
2090                 len -= optlen;
2091                 pos += optlen;
2092         }
2093
2094         return prefixes;
2095 }
2096
2097 static int get_dest_addr(int family, int index, char *buf, int len)
2098 {
2099         struct ifreq ifr;
2100         void *addr;
2101         int sk;
2102
2103         sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2104         if (sk < 0)
2105                 return -errno;
2106
2107         memset(&ifr, 0, sizeof(ifr));
2108         ifr.ifr_ifindex = index;
2109
2110         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
2111                 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
2112                 close(sk);
2113                 return -errno;
2114         }
2115
2116         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
2117                 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
2118                 close(sk);
2119                 return -errno;
2120         }
2121
2122         if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
2123                 close(sk);
2124                 errno = EINVAL;
2125                 return -errno;
2126         }
2127
2128         DBG("index %d %s", index, ifr.ifr_name);
2129
2130         if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
2131                 connman_error("Get destination address failed (%s)",
2132                                                         strerror(errno));
2133                 close(sk);
2134                 return -errno;
2135         }
2136
2137         close(sk);
2138
2139         switch (family) {
2140         case AF_INET:
2141                 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
2142                 break;
2143         case AF_INET6:
2144                 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
2145                 break;
2146         default:
2147                 errno = EINVAL;
2148                 return -errno;
2149         }
2150
2151         if (!inet_ntop(family, addr, buf, len)) {
2152                 DBG("error %d/%s", errno, strerror(errno));
2153                 return -errno;
2154         }
2155
2156         return 0;
2157 }
2158
2159 int connman_inet_get_dest_addr(int index, char **dest)
2160 {
2161         char addr[INET_ADDRSTRLEN];
2162         int ret;
2163
2164         ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
2165         if (ret < 0)
2166                 return ret;
2167
2168         *dest = g_strdup(addr);
2169
2170         DBG("destination %s", *dest);
2171
2172         return 0;
2173 }
2174
2175 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
2176 {
2177         char addr[INET6_ADDRSTRLEN];
2178         int ret;
2179
2180         ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
2181         if (ret < 0)
2182                 return ret;
2183
2184         *dest = g_strdup(addr);
2185
2186         DBG("destination %s", *dest);
2187
2188         return 0;
2189 }
2190
2191 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
2192 {
2193         int sndbuf = 1024;
2194         int rcvbuf = 1024 * 4;
2195
2196         rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
2197         if (rth->fd < 0) {
2198                 connman_error("Can not open netlink socket: %s",
2199                                                 strerror(errno));
2200                 return -errno;
2201         }
2202
2203         if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
2204                         sizeof(sndbuf)) < 0) {
2205                 connman_error("SO_SNDBUF: %s", strerror(errno));
2206                 return -errno;
2207         }
2208
2209         if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
2210                         sizeof(rcvbuf)) < 0) {
2211                 connman_error("SO_RCVBUF: %s", strerror(errno));
2212                 return -errno;
2213         }
2214
2215         memset(&rth->local, 0, sizeof(rth->local));
2216         rth->local.nl_family = AF_NETLINK;
2217         rth->local.nl_groups = 0;
2218
2219         if (bind(rth->fd, (struct sockaddr *)&rth->local,
2220                                                 sizeof(rth->local)) < 0) {
2221                 connman_error("Can not bind netlink socket: %s",
2222                                                         strerror(errno));
2223                 return -errno;
2224         }
2225
2226         rth->seq = time(NULL);
2227
2228         DBG("fd %d", rth->fd);
2229
2230         return 0;
2231 }
2232
2233 struct inet_rtnl_cb_data {
2234         GIOChannel *channel;
2235         __connman_inet_rtnl_cb_t callback;
2236         guint rtnl_timeout;
2237         guint watch_id;
2238         struct __connman_inet_rtnl_handle *rtnl;
2239         void *user_data;
2240 };
2241
2242 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
2243 {
2244         struct __connman_inet_rtnl_handle *rth = data->rtnl;
2245
2246         if (data->channel) {
2247                 g_io_channel_shutdown(data->channel, TRUE, NULL);
2248                 g_io_channel_unref(data->channel);
2249                 data->channel = NULL;
2250         }
2251
2252         DBG("data %p", data);
2253
2254         if (data->rtnl_timeout > 0)
2255                 g_source_remove(data->rtnl_timeout);
2256
2257         if (data->watch_id > 0)
2258                 g_source_remove(data->watch_id);
2259
2260         if (rth) {
2261                 __connman_inet_rtnl_close(rth);
2262                 g_free(rth);
2263         }
2264
2265         g_free(data);
2266 }
2267
2268 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
2269 {
2270         struct inet_rtnl_cb_data *data = user_data;
2271
2272         DBG("user data %p", user_data);
2273
2274         if (!data)
2275                 return FALSE;
2276
2277         if (data->callback)
2278                 data->callback(NULL, data->user_data);
2279
2280         data->rtnl_timeout = 0;
2281         inet_rtnl_cleanup(data);
2282         return FALSE;
2283 }
2284
2285 static int inet_rtnl_recv(GIOChannel *chan, struct inet_rtnl_cb_data *rtnl_data)
2286 {
2287         struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
2288         struct nlmsghdr *h = NULL;
2289         struct sockaddr_nl nladdr;
2290         socklen_t addr_len = sizeof(nladdr);
2291         unsigned char buf[4096];
2292         void *ptr = buf;
2293         gsize len;
2294         int status, fd;
2295
2296         memset(buf, 0, sizeof(buf));
2297         memset(&nladdr, 0, sizeof(nladdr));
2298
2299         fd = g_io_channel_unix_get_fd(chan);
2300
2301         status = recvfrom(fd, buf, sizeof(buf), 0,
2302                        (struct sockaddr *) &nladdr, &addr_len);
2303         if (status < 0) {
2304                 if (errno == EINTR || errno == EAGAIN)
2305                         return 0;
2306
2307                 return -1;
2308         }
2309
2310         if (status == 0)
2311                 return -1;
2312
2313         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
2314                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
2315                 return 0;
2316         }
2317
2318         len = status;
2319
2320         while (len > 0) {
2321                 struct nlmsgerr *err;
2322
2323                 h = ptr;
2324
2325                 if (!NLMSG_OK(h, len))
2326                         return -1;
2327
2328                 if (h->nlmsg_seq != rth->seq) {
2329                         /* Skip this msg */
2330                         DBG("skip %d/%d len %d", rth->seq,
2331                                 h->nlmsg_seq, h->nlmsg_len);
2332
2333                         len -= h->nlmsg_len;
2334                         ptr += h->nlmsg_len;
2335                         continue;
2336                 }
2337
2338                 switch (h->nlmsg_type) {
2339                 case NLMSG_NOOP:
2340                 case NLMSG_OVERRUN:
2341                         return -1;
2342
2343                 case NLMSG_ERROR:
2344                         err = (struct nlmsgerr *)NLMSG_DATA(h);
2345                         connman_error("RTNETLINK answers %s (%d)",
2346                                 strerror(-err->error), -err->error);
2347                         return err->error;
2348                 }
2349
2350                 break;
2351         }
2352
2353         if (h->nlmsg_seq == rth->seq) {
2354                 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
2355
2356                 rtnl_data->callback(h, rtnl_data->user_data);
2357
2358                 inet_rtnl_cleanup(rtnl_data);
2359         }
2360
2361         return 0;
2362 }
2363
2364 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
2365                                                         gpointer user_data)
2366 {
2367         int ret;
2368         struct inet_rtnl_cb_data *rtnl_data = user_data;
2369
2370         DBG("");
2371
2372         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
2373                 goto cleanup;
2374
2375         ret = inet_rtnl_recv(chan, rtnl_data);
2376         if (ret == 0)
2377                 return TRUE;
2378
2379 cleanup:
2380         inet_rtnl_cleanup(rtnl_data);
2381         return TRUE;
2382 }
2383
2384 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
2385                         struct nlmsghdr *n, int timeout,
2386                         __connman_inet_rtnl_cb_t callback, void *user_data)
2387 {
2388         struct sockaddr_nl nladdr;
2389         struct inet_rtnl_cb_data *data;
2390         int err;
2391
2392         memset(&nladdr, 0, sizeof(nladdr));
2393         nladdr.nl_family = AF_NETLINK;
2394
2395         n->nlmsg_seq = ++rtnl->seq;
2396
2397         if (callback) {
2398                 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
2399                 if (!data)
2400                         return -ENOMEM;
2401
2402                 data->callback = callback;
2403                 data->user_data = user_data;
2404                 data->rtnl = rtnl;
2405                 data->rtnl_timeout = g_timeout_add_seconds(timeout,
2406                                                 inet_rtnl_timeout_cb, data);
2407
2408                 data->channel = g_io_channel_unix_new(rtnl->fd);
2409
2410                 g_io_channel_set_encoding(data->channel, NULL, NULL);
2411                 g_io_channel_set_buffered(data->channel, FALSE);
2412
2413                 data->watch_id = g_io_add_watch(data->channel,
2414                                 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
2415                                                 inet_rtnl_event, data);
2416         } else
2417                 n->nlmsg_flags |= NLM_F_ACK;
2418
2419         err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
2420                 (struct sockaddr *) &nladdr, sizeof(nladdr));
2421         DBG("handle %p len %d", rtnl, rtnl->req.n.nlmsg_len);
2422         if (err < 0) {
2423                 connman_error("Can not talk to rtnetlink err %d %s",
2424                         -errno, strerror(errno));
2425                 return -errno;
2426         }
2427
2428         if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
2429                 connman_error("Sent %d bytes, msg truncated", err);
2430                 return -EINVAL;
2431         }
2432
2433         return 0;
2434 }
2435
2436 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
2437 {
2438         DBG("handle %p", rth);
2439
2440         if (rth->fd >= 0) {
2441                 close(rth->fd);
2442                 rth->fd = -1;
2443         }
2444 }
2445
2446 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
2447                                 __u32 data)
2448 {
2449         int len = RTA_LENGTH(4);
2450         struct rtattr *rta;
2451
2452         if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
2453                 DBG("Error! max allowed bound %zd exceeded", maxlen);
2454                 return -1;
2455         }
2456         rta = NLMSG_TAIL(n);
2457         rta->rta_type = type;
2458         rta->rta_len = len;
2459         memcpy(RTA_DATA(rta), &data, 4);
2460         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2461
2462         return 0;
2463 }
2464
2465 static int parse_rtattr(struct rtattr *tb[], int max,
2466                         struct rtattr *rta, int len)
2467 {
2468         memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2469         while (RTA_OK(rta, len)) {
2470                 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2471                         tb[rta->rta_type] = rta;
2472                 rta = RTA_NEXT(rta, len);
2473         }
2474         if (len)
2475                 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2476
2477         return 0;
2478 }
2479
2480 struct get_route_cb_data {
2481         connman_inet_addr_cb_t callback;
2482         void *user_data;
2483 };
2484
2485 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2486 {
2487         struct get_route_cb_data *data = user_data;
2488         struct rtattr *tb[RTA_MAX+1];
2489         struct rtmsg *r = NLMSG_DATA(answer);
2490         int len, index = -1;
2491         char abuf[256];
2492         const char *addr = NULL;
2493
2494         DBG("answer %p data %p", answer, user_data);
2495
2496         if (!answer)
2497                 goto out;
2498
2499         len = answer->nlmsg_len;
2500
2501         if (answer->nlmsg_type != RTM_NEWROUTE &&
2502                                 answer->nlmsg_type != RTM_DELROUTE) {
2503                 connman_error("Not a route: %08x %08x %08x",
2504                         answer->nlmsg_len, answer->nlmsg_type,
2505                         answer->nlmsg_flags);
2506                 goto out;
2507         }
2508
2509         len -= NLMSG_LENGTH(sizeof(*r));
2510         if (len < 0) {
2511                 connman_error("BUG: wrong nlmsg len %d", len);
2512                 goto out;
2513         }
2514
2515         parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2516
2517         if (tb[RTA_OIF])
2518                 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2519
2520         if (tb[RTA_GATEWAY])
2521                 addr = inet_ntop(r->rtm_family,
2522                                 RTA_DATA(tb[RTA_GATEWAY]),
2523                                 abuf, sizeof(abuf));
2524
2525         DBG("addr %s index %d user %p", addr, index, data->user_data);
2526
2527 out:
2528         if (data && data->callback)
2529                 data->callback(addr, index, data->user_data);
2530
2531         g_free(data);
2532
2533         return;
2534 }
2535
2536 /*
2537  * Return the interface index that contains route to host.
2538  */
2539 int __connman_inet_get_route(const char *dest_address,
2540                         connman_inet_addr_cb_t callback, void *user_data)
2541 {
2542         struct get_route_cb_data *data;
2543         struct addrinfo hints, *rp;
2544         struct __connman_inet_rtnl_handle *rth;
2545         int err;
2546
2547         DBG("dest %s", dest_address);
2548
2549         if (!dest_address)
2550                 return -EINVAL;
2551
2552         memset(&hints, 0, sizeof(hints));
2553         hints.ai_family = AF_UNSPEC;
2554         hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2555
2556         err = getaddrinfo(dest_address, NULL, &hints, &rp);
2557         if (err)
2558                 return -EINVAL;
2559
2560         rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2561         if (!rth) {
2562                 freeaddrinfo(rp);
2563                 return -ENOMEM;
2564         }
2565
2566         rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2567         rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2568         rth->req.n.nlmsg_type = RTM_GETROUTE;
2569         rth->req.u.r.rt.rtm_family = rp->ai_family;
2570         rth->req.u.r.rt.rtm_table = 0;
2571         rth->req.u.r.rt.rtm_protocol = 0;
2572         rth->req.u.r.rt.rtm_scope = 0;
2573         rth->req.u.r.rt.rtm_type = 0;
2574         rth->req.u.r.rt.rtm_src_len = 0;
2575         rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2576         rth->req.u.r.rt.rtm_tos = 0;
2577
2578         __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2579                                 &rp->ai_addr, rp->ai_addrlen);
2580
2581         freeaddrinfo(rp);
2582
2583         err = __connman_inet_rtnl_open(rth);
2584         if (err < 0)
2585                 goto fail;
2586
2587         data = g_try_malloc(sizeof(struct get_route_cb_data));
2588         if (!data) {
2589                 err = -ENOMEM;
2590                 goto done;
2591         }
2592
2593         data->callback = callback;
2594         data->user_data = user_data;
2595
2596 #define GET_ROUTE_TIMEOUT 2
2597         err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2598                                 get_route_cb, data);
2599         if (err < 0) {
2600                 g_free(data);
2601                 goto done;
2602         }
2603
2604         return 0;
2605
2606 done:
2607         __connman_inet_rtnl_close(rth);
2608
2609 fail:
2610         g_free(rth);
2611         return err;
2612 }
2613
2614 int connman_inet_check_ipaddress(const char *host)
2615 {
2616         struct addrinfo hints;
2617         struct addrinfo *addr;
2618         int result;
2619
2620         memset(&hints, 0, sizeof(struct addrinfo));
2621         hints.ai_flags = AI_NUMERICHOST;
2622         addr = NULL;
2623
2624         result = getaddrinfo(host, NULL, &hints, &addr);
2625         if (result == 0)
2626                 result = addr->ai_family;
2627         freeaddrinfo(addr);
2628
2629         return result;
2630 }
2631
2632 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2633 bool connman_inet_check_hostname(const char *ptr, size_t len)
2634 {
2635         const char *p;
2636
2637         /*
2638          * Not empty or complete length not over 255 characters.
2639          */
2640         if ((len == 0) || (len > 256))
2641                 return false;
2642
2643         /*
2644          * Consists of [[:alnum:]-]+ labels separated by [.]
2645          * a [_] is against RFC but seems to be "widely used"
2646          */
2647         for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2648
2649                 if ((*p == '-') || (*p == '_')) {
2650                         /*
2651                          * Not allowed at begin or end of a label.
2652                          */
2653                         if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2654                                 return false;
2655
2656                 } else if (*p == '.') {
2657                         /*
2658                          * Each label has to be 1-63 characters;
2659                          * we allow [.] at the end ('foo.bar.')
2660                          */
2661                         size_t d = p - ptr;
2662
2663                         if ((d <= 0) || (d >= 64))
2664                                 return false;
2665
2666                         ptr = p + 1; /* Jump to the next label */
2667
2668                 } else if (isalnum((unsigned char)*p) == 0) {
2669                         /*
2670                          * Also numbers at the begin are fine
2671                          */
2672                         return false;
2673                 }
2674         }
2675
2676         return true;
2677 }
2678
2679 char **__connman_inet_get_running_interfaces(void)
2680 {
2681         char **result;
2682         struct ifconf ifc;
2683         struct ifreq *ifr = NULL;
2684         int sk, i, numif, count = 0;
2685
2686         memset(&ifc, 0, sizeof(ifc));
2687
2688         sk = socket(AF_INET, SOCK_DGRAM, 0);
2689         if (sk < 0)
2690                 return NULL;
2691
2692         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2693                 goto error;
2694
2695         /*
2696          * Allocate some extra bytes just in case there will
2697          * be new interfaces added between two SIOCGIFCONF
2698          * calls.
2699          */
2700         ifr = g_try_malloc0(ifc.ifc_len * 2);
2701         if (!ifr)
2702                 goto error;
2703
2704         ifc.ifc_req = ifr;
2705
2706         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2707                 goto error;
2708
2709         numif = ifc.ifc_len / sizeof(struct ifreq);
2710
2711         result = g_try_malloc0((numif + 1) * sizeof(char *));
2712         if (!result)
2713                 goto error;
2714
2715         close(sk);
2716
2717         for (i = 0; i < numif; i++) {
2718                 struct ifreq *r = &ifr[i];
2719                 struct in6_addr *addr6;
2720                 in_addr_t addr4;
2721
2722                 /*
2723                  * Note that we do not return loopback interfaces here as they
2724                  * are not needed for our purposes.
2725                  */
2726                 switch (r->ifr_addr.sa_family) {
2727                 case AF_INET:
2728                         addr4 = ntohl(((struct sockaddr_in *)
2729                                                 &r->ifr_addr)->sin_addr.s_addr);
2730                         if (((addr4 & 0xff000000) >> 24) == 127)
2731                                 continue;
2732                         break;
2733                 case AF_INET6:
2734                         addr6 = &((struct sockaddr_in6 *)
2735                                                 &r->ifr_addr)->sin6_addr;
2736                         if (IN6_IS_ADDR_LINKLOCAL(addr6))
2737                                 continue;
2738                         break;
2739                 }
2740
2741                 result[count++] = g_strdup(r->ifr_name);
2742         }
2743
2744         g_free(ifr);
2745
2746         if (count < numif)
2747         {
2748                 char **prev_result = result;
2749                 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2750                 if (!result) {
2751                         g_free(prev_result);
2752                         return NULL;
2753                 }
2754         }
2755
2756         return result;
2757
2758 error:
2759         close(sk);
2760         g_free(ifr);
2761         return NULL;
2762 }
2763
2764 bool connman_inet_is_ipv6_supported()
2765 {
2766         int sk;
2767
2768         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2769         if (sk < 0)
2770                 return false;
2771
2772         close(sk);
2773         return true;
2774 }
2775
2776 int __connman_inet_get_interface_address(int index, int family, void *address)
2777 {
2778         struct ifaddrs *ifaddr, *ifa;
2779         int err = -ENOENT;
2780         char name[IF_NAMESIZE];
2781
2782         if (!if_indextoname(index, name))
2783                 return -EINVAL;
2784
2785         DBG("index %d interface %s", index, name);
2786
2787         if (getifaddrs(&ifaddr) < 0) {
2788                 err = -errno;
2789                 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2790                 return err;
2791         }
2792
2793         for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2794                 if (!ifa->ifa_addr)
2795                         continue;
2796
2797                 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2798                                         ifa->ifa_addr->sa_family == family) {
2799                         if (family == AF_INET) {
2800                                 struct sockaddr_in *in4 = (struct sockaddr_in *)
2801                                         ifa->ifa_addr;
2802                                 if (in4->sin_addr.s_addr == INADDR_ANY)
2803                                         continue;
2804                                 memcpy(address, &in4->sin_addr,
2805                                                         sizeof(struct in_addr));
2806                         } else if (family == AF_INET6) {
2807                                 struct sockaddr_in6 *in6 =
2808                                         (struct sockaddr_in6 *)ifa->ifa_addr;
2809                                 if (memcmp(&in6->sin6_addr, &in6addr_any,
2810                                                 sizeof(struct in6_addr)) == 0)
2811                                         continue;
2812                                 memcpy(address, &in6->sin6_addr,
2813                                                 sizeof(struct in6_addr));
2814
2815                         } else {
2816                                 err = -EINVAL;
2817                                 goto out;
2818                         }
2819
2820                         err = 0;
2821                         break;
2822                 }
2823         }
2824
2825 out:
2826         freeifaddrs(ifaddr);
2827         return err;
2828 }
2829
2830 static int iprule_modify(int cmd, int family, uint32_t table_id,
2831                         uint32_t fwmark)
2832 {
2833         struct __connman_inet_rtnl_handle rth;
2834         int ret;
2835
2836         memset(&rth, 0, sizeof(rth));
2837
2838         rth.req.n.nlmsg_type = cmd;
2839         rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2840         rth.req.n.nlmsg_flags = NLM_F_REQUEST;
2841         rth.req.u.r.rt.rtm_family = family;
2842         rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2843         rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2844         rth.req.u.r.rt.rtm_table = table_id;
2845         rth.req.u.r.rt.rtm_type = RTN_UNSPEC;
2846         rth.req.u.r.rt.rtm_flags = 0;
2847
2848         if (cmd == RTM_NEWRULE) {
2849                 rth.req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
2850                 rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2851         }
2852
2853         __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2854                                                         FRA_FWMARK, fwmark);
2855
2856         if (table_id < 256) {
2857                 rth.req.u.r.rt.rtm_table = table_id;
2858         } else {
2859                 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2860                 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2861                                                 FRA_TABLE, table_id);
2862         }
2863
2864         if (rth.req.u.r.rt.rtm_family == AF_UNSPEC)
2865                 rth.req.u.r.rt.rtm_family = AF_INET;
2866
2867         ret = __connman_inet_rtnl_open(&rth);
2868         if (ret < 0)
2869                 goto done;
2870
2871         ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2872
2873 done:
2874         __connman_inet_rtnl_close(&rth);
2875
2876         return ret;
2877 }
2878
2879 int __connman_inet_add_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2880 {
2881         /* ip rule add fwmark 9876 table 1234 */
2882
2883         return iprule_modify(RTM_NEWRULE, family, table_id, fwmark);
2884 }
2885
2886 int __connman_inet_del_fwmark_rule(uint32_t table_id, int family, uint32_t fwmark)
2887 {
2888         return iprule_modify(RTM_DELRULE, family, table_id, fwmark);
2889 }
2890
2891 static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
2892                         const char *gateway)
2893 {
2894         struct __connman_inet_rtnl_handle rth;
2895         unsigned char buf[sizeof(struct in6_addr)];
2896         int ret, len;
2897         int family = connman_inet_check_ipaddress(gateway);
2898
2899         switch (family) {
2900         case AF_INET:
2901                 len = 4;
2902                 break;
2903         case AF_INET6:
2904                 len = 16;
2905                 break;
2906         default:
2907                 return -EINVAL;
2908         }
2909
2910         ret = inet_pton(family, gateway, buf);
2911         if (ret <= 0)
2912                 return -EINVAL;
2913
2914         memset(&rth, 0, sizeof(rth));
2915
2916         rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2917         rth.req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
2918         rth.req.n.nlmsg_type = cmd;
2919         rth.req.u.r.rt.rtm_family = family;
2920         rth.req.u.r.rt.rtm_table = RT_TABLE_MAIN;
2921         rth.req.u.r.rt.rtm_scope = RT_SCOPE_NOWHERE;
2922         rth.req.u.r.rt.rtm_protocol = RTPROT_BOOT;
2923         rth.req.u.r.rt.rtm_scope = RT_SCOPE_UNIVERSE;
2924         rth.req.u.r.rt.rtm_type = RTN_UNICAST;
2925
2926         __connman_inet_rtnl_addattr_l(&rth.req.n, sizeof(rth.req), RTA_GATEWAY,
2927                                                                 buf, len);
2928         if (table_id < 256) {
2929                 rth.req.u.r.rt.rtm_table = table_id;
2930         } else {
2931                 rth.req.u.r.rt.rtm_table = RT_TABLE_UNSPEC;
2932                 __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2933                                                         RTA_TABLE, table_id);
2934         }
2935
2936         __connman_inet_rtnl_addattr32(&rth.req.n, sizeof(rth.req),
2937                                                         RTA_OIF, ifindex);
2938
2939         ret = __connman_inet_rtnl_open(&rth);
2940         if (ret < 0)
2941                 goto done;
2942
2943         ret = __connman_inet_rtnl_send(&rth, &rth.req.n);
2944
2945 done:
2946         __connman_inet_rtnl_close(&rth);
2947
2948         return ret;
2949 }
2950
2951 int __connman_inet_add_default_to_table(uint32_t table_id, int ifindex,
2952                                                 const char *gateway)
2953 {
2954         /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
2955
2956         return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway);
2957 }
2958
2959 int __connman_inet_del_default_from_table(uint32_t table_id, int ifindex,
2960                                                 const char *gateway)
2961 {
2962         /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
2963
2964         return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway);
2965 }
2966
2967 int __connman_inet_get_interface_ll_address(int index, int family,
2968                                                                 void *address)
2969 {
2970         struct ifaddrs *ifaddr, *ifa;
2971         int err = -ENOENT;
2972         char name[IF_NAMESIZE];
2973
2974         if (!if_indextoname(index, name))
2975                 return -EINVAL;
2976
2977         DBG("index %d interface %s", index, name);
2978
2979         if (getifaddrs(&ifaddr) < 0) {
2980                 err = -errno;
2981                 DBG("Cannot get addresses err %d/%s", err, strerror(-err));
2982                 return err;
2983         }
2984
2985         for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
2986                 if (!ifa->ifa_addr)
2987                         continue;
2988
2989                 if (strncmp(ifa->ifa_name, name, IF_NAMESIZE) == 0 &&
2990                                         ifa->ifa_addr->sa_family == family) {
2991                         if (family == AF_INET) {
2992                                 struct sockaddr_in *in4 = (struct sockaddr_in *)
2993                                         ifa->ifa_addr;
2994                                 if (in4->sin_addr.s_addr == INADDR_ANY)
2995                                         continue;
2996                                 if ((in4->sin_addr.s_addr & IN_CLASSB_NET) !=
2997                                                 ((in_addr_t) 0xa9fe0000))
2998                                         continue;
2999                                 memcpy(address, &in4->sin_addr,
3000                                                         sizeof(struct in_addr));
3001                         } else if (family == AF_INET6) {
3002                                 struct sockaddr_in6 *in6 =
3003                                         (struct sockaddr_in6 *)ifa->ifa_addr;
3004                                 if (memcmp(&in6->sin6_addr, &in6addr_any,
3005                                                 sizeof(struct in6_addr)) == 0)
3006                                         continue;
3007                                 if (!IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr))
3008                                         continue;
3009
3010                                 memcpy(address, &in6->sin6_addr,
3011                                                 sizeof(struct in6_addr));
3012                         } else {
3013                                 err = -EINVAL;
3014                                 goto out;
3015                         }
3016
3017                         err = 0;
3018                         break;
3019                 }
3020         }
3021
3022 out:
3023         freeifaddrs(ifaddr);
3024         return err;
3025 }
3026
3027 int __connman_inet_get_address_netmask(int ifindex,
3028                                         struct sockaddr_in *address,
3029                                         struct sockaddr_in *netmask)
3030 {
3031         int sk, ret = -EINVAL;
3032         struct ifreq ifr;
3033
3034         DBG("index %d", ifindex);
3035
3036         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
3037         if (sk < 0)
3038                 return -EINVAL;
3039
3040         memset(&ifr, 0, sizeof(ifr));
3041         ifr.ifr_ifindex = ifindex;
3042
3043         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
3044                 goto out;
3045
3046         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0)
3047                 goto out;
3048
3049         memcpy(netmask, (struct sockaddr_in *)&ifr.ifr_netmask,
3050                                                 sizeof(struct sockaddr_in));
3051
3052         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0)
3053                 goto out;
3054
3055         memcpy(address, (struct sockaddr_in *)&ifr.ifr_addr,
3056                                                 sizeof(struct sockaddr_in));
3057         ret = 0;
3058
3059 out:
3060         close(sk);
3061         return ret;
3062 }
3063
3064 static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
3065                                 struct in_addr *addr)
3066 {
3067         char *s, *nfsargs;
3068         size_t len;
3069         char addrstr[INET_ADDRSTRLEN];
3070         struct in_addr taddr;
3071         GError *error = NULL;
3072         char *cmdline = NULL;
3073         char *pnp = NULL;
3074         char **args = NULL;
3075         char **pnpent = NULL;
3076         char **pp = NULL;
3077         int err = -1;
3078
3079         if (!cmdline_file)
3080                 cmdline_file = "/proc/cmdline";
3081         if (!pnp_file)
3082                 pnp_file = "/proc/net/pnp";
3083         if (!addr)
3084                 addr = &taddr;
3085         addr->s_addr = INADDR_NONE;
3086
3087         if (!g_file_get_contents(cmdline_file, &cmdline, NULL, &error)) {
3088                 connman_error("%s: Cannot read %s %s\n", __func__,
3089                                 cmdline_file, error->message);
3090                 goto out;
3091         }
3092
3093         if (g_file_test(pnp_file, G_FILE_TEST_EXISTS)) {
3094                 if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3095                         connman_error("%s: Cannot read %s %s\n", __func__,
3096                                                   pnp_file, error->message);
3097                         goto out;
3098                 }
3099         } else {
3100                 connman_error("%s: File %s doesn't exist\n", __func__, pnp_file);
3101                 goto out;
3102         }
3103
3104         len = strlen(cmdline);
3105         if (len <= 1) {
3106                 /* too short */
3107                 goto out;
3108         }
3109         /* remove newline */
3110         if (cmdline[len - 1] == '\n')
3111                 cmdline[--len] = '\0';
3112
3113         /* split in arguments (seperated by space) */
3114         args = g_strsplit(cmdline, " ", 0);
3115         if (!args) {
3116                 connman_error("%s: Cannot split cmdline \"%s\"\n", __func__,
3117                                 cmdline);
3118                 goto out;
3119         }
3120
3121         /* split in entries (by newlines) */
3122         pnpent = g_strsplit(pnp, "\n", 0);
3123         if (!pnpent) {
3124                 connman_error("%s: Cannot split pnp at file \"%s\"\n", __func__,
3125                                 pnp_file);
3126                 goto out;
3127         }
3128
3129         /* first find root argument */
3130         for (pp = args; *pp; pp++) {
3131                 if (!strcmp(*pp, "root=/dev/nfs"))
3132                         break;
3133         }
3134         /* no rootnfs found */
3135         if (!*pp)
3136                 goto out;
3137
3138         /* locate nfsroot argument */
3139         for (pp = args; *pp; pp++) {
3140                 if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
3141                         break;
3142         }
3143         /* no nfsroot argument found */
3144         if (!*pp)
3145                 goto out;
3146
3147         /* determine if nfsroot server is provided */
3148         nfsargs = strchr(*pp, '=');
3149         if (!nfsargs)
3150                 goto out;
3151         nfsargs++;
3152
3153         /* find whether serverip is present */
3154         s = strchr(nfsargs, ':');
3155         if (s) {
3156                 len = s - nfsargs;
3157                 s = nfsargs;
3158         } else {
3159                 /* no serverip, use bootserver */
3160                 for (pp = pnpent; *pp; pp++) {
3161                         if (!strncmp(*pp, "bootserver ", strlen("bootserver ")))
3162                                 break;
3163                 }
3164                 /* no bootserver found */
3165                 if (!*pp)
3166                         goto out;
3167                 s = *pp + strlen("bootserver ");
3168                 len = strlen(s);
3169         }
3170
3171         /* copy to addr string buffer */
3172         if (len >= sizeof(addrstr)) {
3173                 connman_error("%s: Bad server\n", __func__);
3174                 goto out;
3175         }
3176         memcpy(addrstr, s, len);
3177         addrstr[len] = '\0';
3178
3179         err = inet_pton(AF_INET, addrstr, addr);
3180         if (err <= 0) {
3181                 connman_error("%s: Cannot convert to numeric addr \"%s\"\n",
3182                                 __func__, addrstr);
3183                 err = -1;
3184                 goto out;
3185         }
3186
3187         /* all done */
3188         err = 0;
3189 out:
3190         g_strfreev(pnpent);
3191         g_strfreev(args);
3192         if (error)
3193                 g_error_free(error);
3194         g_free(pnp);
3195         g_free(cmdline);
3196
3197         return err;
3198 }
3199
3200 /* get interface out of which peer is reachable (IPv4 only) */
3201 static int get_peer_iface(struct in_addr *addr, char *ifname)
3202 {
3203         struct ifaddrs *ifaddr, *ifa;
3204         struct sockaddr_in saddr, *ifsaddr;
3205         socklen_t socklen;
3206         int s;
3207         int err = -1;
3208
3209         /* Obtain address(es) matching host/port */
3210         err = getifaddrs(&ifaddr);
3211         if (err < 0) {
3212                 connman_error("%s: getifaddrs() failed %d (%s)\n",
3213                                 __func__, errno, strerror(errno));
3214                 return -1;
3215         }
3216
3217         s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3218         if (s < 0) {
3219                 connman_error("%s: socket() failed %d (%s)\n",
3220                                 __func__, errno, strerror(errno));
3221                 return -1;
3222         }
3223
3224         memset(&saddr, 0, sizeof(saddr));
3225         saddr.sin_family = AF_INET;
3226         saddr.sin_port = 0;     /* any port */
3227         saddr.sin_addr = *addr;
3228
3229         /* no need to bind, connect will select iface */
3230         err = connect(s, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
3231         if (err < 0) {
3232                 connman_error("%s: connect() failed: %d (%s)\n",
3233                                 __func__, errno, strerror(errno));
3234                 goto out;
3235         }
3236
3237         socklen = sizeof(saddr);
3238         err = getsockname(s, (struct sockaddr *)&saddr, &socklen);
3239         if (err < 0) {
3240                 connman_error("%s: getsockname() failed: %d (%s)\n",
3241                                 __func__, errno, strerror(errno));
3242                 goto out;
3243         }
3244
3245         err = -1;
3246         for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
3247                 if (!ifa->ifa_addr)
3248                         continue;
3249
3250                 /* only IPv4 address */
3251                 if (ifa->ifa_addr->sa_family != AF_INET)
3252                         continue;
3253
3254                 ifsaddr = (struct sockaddr_in *)ifa->ifa_addr;
3255
3256                 /* match address? */
3257                 if (ifsaddr->sin_addr.s_addr == saddr.sin_addr.s_addr)
3258                         break;
3259         }
3260
3261         if (ifa) {
3262                 err = 0;
3263                 if (ifname)
3264                         strcpy(ifname, ifa->ifa_name);
3265         }
3266
3267 out:
3268         close(s);
3269
3270         freeifaddrs(ifaddr);
3271
3272         return err;
3273 }
3274
3275 bool __connman_inet_isrootnfs_device(const char *devname)
3276 {
3277         struct in_addr addr;
3278         char ifname[IFNAMSIZ];
3279
3280         return get_nfs_server_ip(NULL, NULL, &addr) == 0 &&
3281                get_peer_iface(&addr, ifname) == 0 &&
3282                strcmp(devname, ifname) == 0;
3283 }
3284
3285 char **__connman_inet_get_pnp_nameservers(const char *pnp_file)
3286 {
3287         char **pp;
3288         char *s;
3289         int pass, count;
3290         GError *error = NULL;
3291         char *pnp = NULL;
3292         char **pnpent = NULL;
3293         char **nameservers = NULL;
3294
3295         if (!pnp_file)
3296                 pnp_file = "/proc/net/pnp";
3297
3298         if (!g_file_get_contents(pnp_file, &pnp, NULL, &error)) {
3299                 connman_error("%s: Cannot read %s %s\n", __func__,
3300                                 pnp_file, error->message);
3301                 goto out;
3302         }
3303
3304         /* split in entries (by newlines) */
3305         pnpent = g_strsplit(pnp, "\n", 0);
3306         if (!pnpent) {
3307                 connman_error("%s: Cannot split pnp \"%s\"\n", __func__,
3308                                 pnp_file);
3309                 goto out;
3310         }
3311
3312         /*
3313          * Perform two passes to retreive a char ** array of
3314          * nameservers that are not 0.0.0.0
3315          *
3316          * The first pass counts them, the second fills in the
3317          * array.
3318          */
3319         count = 0;
3320         nameservers = NULL;
3321         for (pass = 1; pass <= 2; pass++) {
3322
3323                 /* at the start of the second pass allocate */
3324                 if (pass == 2)
3325                         nameservers = g_new(char *, count + 1);
3326
3327                 count = 0;
3328                 for (pp = pnpent; *pp; pp++) {
3329                         /* match 'nameserver ' at the start of each line */
3330                         if (strncmp(*pp, "nameserver ", strlen("nameserver ")))
3331                                 continue;
3332
3333                         /* compare it against 0.0.0.0 */
3334                         s = *pp + strlen("nameserver ");
3335                         if (!strcmp(s, "0.0.0.0"))
3336                                 continue;
3337
3338                         /* on second pass fill in array */
3339                         if (pass == 2)
3340                                 nameservers[count] = g_strdup(s);
3341                         count++;
3342                 }
3343
3344                 /* no nameservers? */
3345                 if (count == 0)
3346                         goto out;
3347
3348                 /* and terminate char ** array with NULL */
3349                 if (pass == 2)
3350                         nameservers[count] = NULL;
3351
3352         }
3353
3354 out:
3355         g_strfreev(pnpent);
3356         g_free(pnp);
3357         if (error)
3358                 g_error_free(error);
3359
3360         return nameservers;
3361 }