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