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