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