gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
[platform/upstream/connman.git] / src / inet.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2012  Intel Corporation. All rights reserved.
6  *  Copyright (C) 2003-2005  Go-Core Project
7  *  Copyright (C) 2003-2006  Helsinki University of Technology
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2 as
11  *  published by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #define _GNU_SOURCE
29 #include <stdio.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
37 #include <linux/sockios.h>
38 #include <netdb.h>
39 #include <arpa/inet.h>
40 #include <net/route.h>
41 #include <net/ethernet.h>
42 #include <net/if.h>
43 #include <net/if_arp.h>
44 #include <netinet/icmp6.h>
45 #include <fcntl.h>
46 #include <linux/if_tun.h>
47 #include <ctype.h>
48
49 #include "connman.h"
50
51 #define NLMSG_TAIL(nmsg)                                \
52         ((struct rtattr *) (((uint8_t*) (nmsg)) +       \
53         NLMSG_ALIGN((nmsg)->nlmsg_len)))
54
55 int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
56                                 int type, const void *data, size_t data_length)
57 {
58         size_t length;
59         struct rtattr *rta;
60
61         length = RTA_LENGTH(data_length);
62
63         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
64                 return -E2BIG;
65
66         rta = NLMSG_TAIL(n);
67         rta->rta_type = type;
68         rta->rta_len = length;
69         memcpy(RTA_DATA(rta), data, data_length);
70         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
71
72         return 0;
73 }
74
75 int __connman_inet_modify_address(int cmd, int flags,
76                                 int index, int family,
77                                 const char *address,
78                                 const char *peer,
79                                 unsigned char prefixlen,
80                                 const char *broadcast)
81 {
82         uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
83                         NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
84                         RTA_LENGTH(sizeof(struct in6_addr)) +
85                         RTA_LENGTH(sizeof(struct in6_addr))];
86
87         struct nlmsghdr *header;
88         struct sockaddr_nl nl_addr;
89         struct ifaddrmsg *ifaddrmsg;
90         struct in6_addr ipv6_addr;
91         struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
92         int sk, err;
93
94         DBG("cmd %#x flags %#x index %d family %d address %s peer %s "
95                 "prefixlen %hhu broadcast %s", cmd, flags, index, family,
96                 address, peer, prefixlen, broadcast);
97
98         if (address == NULL)
99                 return -EINVAL;
100
101         if (family != AF_INET && family != AF_INET6)
102                 return -EINVAL;
103
104         memset(&request, 0, sizeof(request));
105
106         header = (struct nlmsghdr *)request;
107         header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
108         header->nlmsg_type = cmd;
109         header->nlmsg_flags = NLM_F_REQUEST | flags;
110         header->nlmsg_seq = 1;
111
112         ifaddrmsg = NLMSG_DATA(header);
113         ifaddrmsg->ifa_family = family;
114         ifaddrmsg->ifa_prefixlen = prefixlen;
115         ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
116         ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
117         ifaddrmsg->ifa_index = index;
118
119         if (family == AF_INET) {
120                 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
121                         return -1;
122
123                 if (broadcast != NULL)
124                         inet_pton(AF_INET, broadcast, &ipv4_bcast);
125                 else
126                         ipv4_bcast.s_addr = ipv4_addr.s_addr |
127                                 htonl(0xfffffffflu >> prefixlen);
128
129                 if (peer != NULL) {
130                         if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
131                                 return -1;
132
133                         err = __connman_inet_rtnl_addattr_l(header,
134                                                         sizeof(request),
135                                                         IFA_ADDRESS,
136                                                         &ipv4_dest,
137                                                         sizeof(ipv4_dest));
138                         if (err < 0)
139                                 return err;
140                 }
141
142                 err = __connman_inet_rtnl_addattr_l(header,
143                                                 sizeof(request),
144                                                 IFA_LOCAL,
145                                                 &ipv4_addr,
146                                                 sizeof(ipv4_addr));
147                 if (err < 0)
148                         return err;
149
150                 err = __connman_inet_rtnl_addattr_l(header,
151                                                 sizeof(request),
152                                                 IFA_BROADCAST,
153                                                 &ipv4_bcast,
154                                                 sizeof(ipv4_bcast));
155                 if (err < 0)
156                         return err;
157
158         } else if (family == AF_INET6) {
159                 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
160                         return -1;
161
162                 err = __connman_inet_rtnl_addattr_l(header,
163                                                 sizeof(request),
164                                                 IFA_LOCAL,
165                                                 &ipv6_addr,
166                                                 sizeof(ipv6_addr));
167                 if (err < 0)
168                         return err;
169         }
170
171         sk = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
172         if (sk < 0)
173                 return -errno;
174
175         memset(&nl_addr, 0, sizeof(nl_addr));
176         nl_addr.nl_family = AF_NETLINK;
177
178         if ((err = sendto(sk, request, header->nlmsg_len, 0,
179                         (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
180                 goto done;
181
182         err = 0;
183
184 done:
185         close(sk);
186
187         return err;
188 }
189
190 int connman_inet_ifindex(const char *name)
191 {
192         struct ifreq ifr;
193         int sk, err;
194
195         if (name == NULL)
196                 return -1;
197
198         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
199         if (sk < 0)
200                 return -1;
201
202         memset(&ifr, 0, sizeof(ifr));
203         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
204
205         err = ioctl(sk, SIOCGIFINDEX, &ifr);
206
207         close(sk);
208
209         if (err < 0)
210                 return -1;
211
212         return ifr.ifr_ifindex;
213 }
214
215 char *connman_inet_ifname(int index)
216 {
217         struct ifreq ifr;
218         int sk, err;
219
220         if (index < 0)
221                 return NULL;
222
223         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
224         if (sk < 0)
225                 return NULL;
226
227         memset(&ifr, 0, sizeof(ifr));
228         ifr.ifr_ifindex = index;
229
230         err = ioctl(sk, SIOCGIFNAME, &ifr);
231
232         close(sk);
233
234         if (err < 0)
235                 return NULL;
236
237         return strdup(ifr.ifr_name);
238 }
239
240 short int connman_inet_ifflags(int index)
241 {
242         struct ifreq ifr;
243         int sk, err;
244
245         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
246         if (sk < 0)
247                 return -errno;
248
249         memset(&ifr, 0, sizeof(ifr));
250         ifr.ifr_ifindex = index;
251
252         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
253                 err = -errno;
254                 goto done;
255         }
256
257         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
258                 err = -errno;
259                 goto done;
260         }
261
262         err = ifr.ifr_flags;
263
264 done:
265         close(sk);
266
267         return err;
268 }
269
270 int connman_inet_ifup(int index)
271 {
272         struct ifreq ifr;
273         int sk, err;
274
275         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
276         if (sk < 0)
277                 return -errno;
278
279         memset(&ifr, 0, sizeof(ifr));
280         ifr.ifr_ifindex = index;
281
282         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
283                 err = -errno;
284                 goto done;
285         }
286
287         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
288                 err = -errno;
289                 goto done;
290         }
291
292         if (ifr.ifr_flags & IFF_UP) {
293                 err = -EALREADY;
294                 goto done;
295         }
296
297         ifr.ifr_flags |= (IFF_UP|IFF_DYNAMIC);
298
299         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
300                 err = -errno;
301                 goto done;
302         }
303
304         err = 0;
305
306 done:
307         close(sk);
308
309         return err;
310 }
311
312 int connman_inet_ifdown(int index)
313 {
314         struct ifreq ifr, addr_ifr;
315         struct sockaddr_in *addr;
316         int sk, err;
317
318         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
319         if (sk < 0)
320                 return -errno;
321
322         memset(&ifr, 0, sizeof(ifr));
323         ifr.ifr_ifindex = index;
324
325         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
326                 err = -errno;
327                 goto done;
328         }
329
330         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
331                 err = -errno;
332                 goto done;
333         }
334
335         memset(&addr_ifr, 0, sizeof(addr_ifr));
336         memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name));
337         addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
338         addr->sin_family = AF_INET;
339         if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
340                 connman_warn("Could not clear IPv4 address index %d", index);
341
342         if (!(ifr.ifr_flags & IFF_UP)) {
343                 err = -EALREADY;
344                 goto done;
345         }
346
347         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
348
349         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
350                 err = -errno;
351         else
352                 err = 0;
353
354 done:
355         close(sk);
356
357         return err;
358 }
359
360 connman_bool_t connman_inet_is_cfg80211(int index)
361 {
362         connman_bool_t result = FALSE;
363         char phy80211_path[PATH_MAX];
364         struct stat st;
365         struct ifreq ifr;
366         int sk;
367
368         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
369         if (sk < 0)
370                 return FALSE;
371
372         memset(&ifr, 0, sizeof(ifr));
373         ifr.ifr_ifindex = index;
374
375         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
376                 goto done;
377
378         snprintf(phy80211_path, PATH_MAX,
379                                 "/sys/class/net/%s/phy80211", ifr.ifr_name);
380
381         if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
382                 result = TRUE;
383
384 done:
385         close(sk);
386
387         return result;
388 }
389
390 struct in6_ifreq {
391         struct in6_addr ifr6_addr;
392         __u32 ifr6_prefixlen;
393         unsigned int ifr6_ifindex;
394 };
395
396 int connman_inet_set_ipv6_address(int index,
397                 struct connman_ipaddress *ipaddress)
398 {
399         int err;
400         unsigned char prefix_len;
401         const char *address;
402
403         if (ipaddress->local == NULL)
404                 return 0;
405
406         prefix_len = ipaddress->prefixlen;
407         address = ipaddress->local;
408
409         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
410
411         err = __connman_inet_modify_address(RTM_NEWADDR,
412                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
413                                 address, NULL, prefix_len, NULL);
414         if (err < 0) {
415                 connman_error("%s: %s", __func__, strerror(-err));
416                 return err;
417         }
418
419         return 0;
420 }
421
422 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
423 {
424         int err;
425         unsigned char prefix_len;
426         const char *address, *broadcast, *peer;
427
428         if (ipaddress->local == NULL)
429                 return -1;
430
431         prefix_len = ipaddress->prefixlen;
432         address = ipaddress->local;
433         broadcast = ipaddress->broadcast;
434         peer = ipaddress->peer;
435
436         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
437
438         err = __connman_inet_modify_address(RTM_NEWADDR,
439                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
440                                 address, peer, prefix_len, broadcast);
441         if (err < 0) {
442                 connman_error("%s: %s", __func__, strerror(-err));
443                 return err;
444         }
445
446         return 0;
447 }
448
449 int connman_inet_clear_ipv6_address(int index, const char *address,
450                                                         int prefix_len)
451 {
452         int err;
453
454         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
455
456         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
457                                 address, NULL, prefix_len, NULL);
458         if (err < 0) {
459                 connman_error("%s: %s", __func__, strerror(-err));
460                 return err;
461         }
462
463         return 0;
464 }
465
466 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
467 {
468         int err;
469         unsigned char prefix_len;
470         const char *address, *broadcast, *peer;
471
472         prefix_len = ipaddress->prefixlen;
473         address = ipaddress->local;
474         broadcast = ipaddress->broadcast;
475         peer = ipaddress->peer;
476
477         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
478
479         err = __connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
480                                 address, peer, prefix_len, broadcast);
481         if (err < 0) {
482                 connman_error("%s: %s", __func__, strerror(-err));
483                 return err;
484         }
485
486         return 0;
487 }
488
489 int connman_inet_add_host_route(int index, const char *host,
490                                 const char *gateway)
491 {
492         return connman_inet_add_network_route(index, host, gateway, NULL);
493 }
494
495 int connman_inet_del_host_route(int index, const char *host)
496 {
497         return connman_inet_del_network_route(index, host);
498 }
499
500 int connman_inet_add_network_route(int index, const char *host,
501                                         const char *gateway,
502                                         const char *netmask)
503 {
504         struct ifreq ifr;
505         struct rtentry rt;
506         struct sockaddr_in addr;
507         int sk, err;
508
509         DBG("index %d host %s gateway %s netmask %s", index,
510                 host, gateway, netmask);
511
512         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
513         if (sk < 0)
514                 return -1;
515
516         memset(&ifr, 0, sizeof(ifr));
517         ifr.ifr_ifindex = index;
518
519         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
520                 close(sk);
521                 return -1;
522         }
523
524         DBG("ifname %s", ifr.ifr_name);
525
526         memset(&rt, 0, sizeof(rt));
527         rt.rt_flags = RTF_UP;
528         if (gateway != NULL)
529                 rt.rt_flags |= RTF_GATEWAY;
530         if (netmask == NULL)
531                 rt.rt_flags |= RTF_HOST;
532
533         memset(&addr, 0, sizeof(addr));
534         addr.sin_family = AF_INET;
535         addr.sin_addr.s_addr = inet_addr(host);
536         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
537
538         memset(&addr, 0, sizeof(addr));
539         addr.sin_family = AF_INET;
540         if (gateway != NULL)
541                 addr.sin_addr.s_addr = inet_addr(gateway);
542         else
543                 addr.sin_addr.s_addr = INADDR_ANY;
544         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
545
546         memset(&addr, 0, sizeof(addr));
547         addr.sin_family = AF_INET;
548         addr.sin_addr.s_addr = INADDR_ANY;
549         if (netmask != NULL)
550                 addr.sin_addr.s_addr = inet_addr(netmask);
551         else
552                 addr.sin_addr.s_addr = INADDR_ANY;
553         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
554
555         rt.rt_dev = ifr.ifr_name;
556
557         err = ioctl(sk, SIOCADDRT, &rt);
558         if (err < 0)
559                 connman_error("Adding host route failed (%s)",
560                                                         strerror(errno));
561
562         close(sk);
563
564         return err;
565 }
566
567 int connman_inet_del_network_route(int index, const char *host)
568 {
569         struct ifreq ifr;
570         struct rtentry rt;
571         struct sockaddr_in addr;
572         int sk, err;
573
574         DBG("index %d host %s", index, host);
575
576         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
577         if (sk < 0)
578                 return -1;
579
580         memset(&ifr, 0, sizeof(ifr));
581         ifr.ifr_ifindex = index;
582
583         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
584                 close(sk);
585                 return -1;
586         }
587
588         DBG("ifname %s", ifr.ifr_name);
589
590         memset(&rt, 0, sizeof(rt));
591         rt.rt_flags = RTF_UP | RTF_HOST;
592
593         memset(&addr, 0, sizeof(addr));
594         addr.sin_family = AF_INET;
595         addr.sin_addr.s_addr = inet_addr(host);
596         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
597
598         rt.rt_dev = ifr.ifr_name;
599
600         err = ioctl(sk, SIOCDELRT, &rt);
601         if (err < 0)
602                 connman_error("Deleting host route failed (%s)",
603                                                         strerror(errno));
604
605         close(sk);
606
607         return err;
608 }
609
610 int connman_inet_del_ipv6_network_route(int index, const char *host,
611                                                 unsigned char prefix_len)
612 {
613         struct in6_rtmsg rt;
614         int sk, err;
615
616         DBG("index %d host %s", index, host);
617
618         if (host == NULL)
619                 return -EINVAL;
620
621         memset(&rt, 0, sizeof(rt));
622
623         rt.rtmsg_dst_len = prefix_len;
624
625         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
626         if (err < 0)
627                 goto out;
628
629         rt.rtmsg_flags = RTF_UP | RTF_HOST;
630
631         rt.rtmsg_metric = 1;
632         rt.rtmsg_ifindex = index;
633
634         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
635         if (sk < 0) {
636                 err = -1;
637                 goto out;
638         }
639
640         err = ioctl(sk, SIOCDELRT, &rt);
641         close(sk);
642 out:
643         if (err < 0)
644                 connman_error("Del IPv6 host route error (%s)",
645                                                 strerror(errno));
646
647         return err;
648 }
649
650 int connman_inet_del_ipv6_host_route(int index, const char *host)
651 {
652         return connman_inet_del_ipv6_network_route(index, host, 128);
653 }
654
655 int connman_inet_add_ipv6_network_route(int index, const char *host,
656                                         const char *gateway,
657                                         unsigned char prefix_len)
658 {
659         struct in6_rtmsg rt;
660         int sk, err;
661
662         DBG("index %d host %s gateway %s", index, host, gateway);
663
664         if (host == NULL)
665                 return -EINVAL;
666
667         memset(&rt, 0, sizeof(rt));
668
669         rt.rtmsg_dst_len = prefix_len;
670
671         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
672         if (err < 0)
673                 goto out;
674
675         rt.rtmsg_flags = RTF_UP | RTF_HOST;
676
677         if (gateway != NULL) {
678                 rt.rtmsg_flags |= RTF_GATEWAY;
679                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
680         }
681
682         rt.rtmsg_metric = 1;
683         rt.rtmsg_ifindex = index;
684
685         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
686         if (sk < 0) {
687                 err = -1;
688                 goto out;
689         }
690
691         err = ioctl(sk, SIOCADDRT, &rt);
692         close(sk);
693 out:
694         if (err < 0)
695                 connman_error("Set IPv6 host route error (%s)",
696                                                 strerror(errno));
697
698         return err;
699 }
700
701 int connman_inet_add_ipv6_host_route(int index, const char *host,
702                                         const char *gateway)
703 {
704         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
705 }
706
707 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
708 {
709         struct in6_rtmsg rt;
710         int sk, err;
711
712         DBG("index %d gateway %s", index, gateway);
713
714         if (gateway == NULL)
715                 return -EINVAL;
716
717         memset(&rt, 0, sizeof(rt));
718
719         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
720         if (err < 0)
721                 goto out;
722
723         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
724         rt.rtmsg_metric = 1;
725         rt.rtmsg_dst_len = 0;
726         rt.rtmsg_ifindex = index;
727
728         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
729         if (sk < 0) {
730                 err = -1;
731                 goto out;
732         }
733
734         err = ioctl(sk, SIOCADDRT, &rt);
735         close(sk);
736 out:
737         if (err < 0)
738                 connman_error("Set default IPv6 gateway error (%s)",
739                                                 strerror(errno));
740
741         return err;
742 }
743
744 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
745 {
746         struct in6_rtmsg rt;
747         int sk, err;
748
749         DBG("index %d gateway %s", index, gateway);
750
751         if (gateway == NULL)
752                 return -EINVAL;
753
754         memset(&rt, 0, sizeof(rt));
755
756         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
757         if (err < 0)
758                 goto out;
759
760         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
761         rt.rtmsg_metric = 1;
762         rt.rtmsg_dst_len = 0;
763         rt.rtmsg_ifindex = index;
764
765         sk = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
766         if (sk < 0) {
767                 err = -1;
768                 goto out;
769         }
770
771         err = ioctl(sk, SIOCDELRT, &rt);
772         close(sk);
773 out:
774         if (err < 0)
775                 connman_error("Clear default IPv6 gateway error (%s)",
776                                                 strerror(errno));
777
778         return err;
779 }
780
781 int connman_inet_set_gateway_address(int index, const char *gateway)
782 {
783         struct ifreq ifr;
784         struct rtentry rt;
785         struct sockaddr_in addr;
786         int sk, err;
787
788         DBG("index %d gateway %s", index, gateway);
789
790         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
791         if (sk < 0)
792                 return -1;
793
794         memset(&ifr, 0, sizeof(ifr));
795         ifr.ifr_ifindex = index;
796
797         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
798                 close(sk);
799                 return -1;
800         }
801
802         DBG("ifname %s", ifr.ifr_name);
803
804         memset(&rt, 0, sizeof(rt));
805         rt.rt_flags = RTF_UP | RTF_GATEWAY;
806
807         memset(&addr, 0, sizeof(addr));
808         addr.sin_family = AF_INET;
809         addr.sin_addr.s_addr = INADDR_ANY;
810         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
811
812         memset(&addr, 0, sizeof(addr));
813         addr.sin_family = AF_INET;
814         addr.sin_addr.s_addr = inet_addr(gateway);
815         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
816
817         memset(&addr, 0, sizeof(addr));
818         addr.sin_family = AF_INET;
819         addr.sin_addr.s_addr = INADDR_ANY;
820         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
821
822         err = ioctl(sk, SIOCADDRT, &rt);
823         if (err < 0)
824                 connman_error("Setting default gateway route failed (%s)",
825                                                         strerror(errno));
826
827         close(sk);
828
829         return err;
830 }
831
832 int connman_inet_set_gateway_interface(int index)
833 {
834         struct ifreq ifr;
835         struct rtentry rt;
836         struct sockaddr_in addr;
837         int sk, err;
838
839         DBG("index %d", index);
840
841         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
842         if (sk < 0)
843                 return -1;
844
845         memset(&ifr, 0, sizeof(ifr));
846         ifr.ifr_ifindex = index;
847
848         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
849                 close(sk);
850                 return -1;
851         }
852
853         DBG("ifname %s", ifr.ifr_name);
854
855         memset(&rt, 0, sizeof(rt));
856         rt.rt_flags = RTF_UP;
857
858         memset(&addr, 0, sizeof(addr));
859         addr.sin_family = AF_INET;
860         addr.sin_addr.s_addr = INADDR_ANY;
861
862         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
863         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
864         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
865
866         rt.rt_dev = ifr.ifr_name;
867
868         err = ioctl(sk, SIOCADDRT, &rt);
869         if (err < 0)
870                 connman_error("Setting default interface route failed (%s)",
871                                                         strerror(errno));
872         close(sk);
873
874         return err;
875 }
876
877 int connman_inet_set_ipv6_gateway_interface(int index)
878 {
879         struct ifreq ifr;
880         struct rtentry rt;
881         struct sockaddr_in6 addr;
882         const struct in6_addr any = IN6ADDR_ANY_INIT;
883         int sk, err;
884
885         DBG("index %d", index);
886
887         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
888         if (sk < 0)
889                 return -1;
890
891         memset(&ifr, 0, sizeof(ifr));
892         ifr.ifr_ifindex = index;
893
894         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
895                 close(sk);
896                 return -1;
897         }
898
899         DBG("ifname %s", ifr.ifr_name);
900
901         memset(&rt, 0, sizeof(rt));
902         rt.rt_flags = RTF_UP;
903
904         memset(&addr, 0, sizeof(addr));
905         addr.sin6_family = AF_INET6;
906         addr.sin6_addr = any;
907
908         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
909         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
910         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
911
912         rt.rt_dev = ifr.ifr_name;
913
914         err = ioctl(sk, SIOCADDRT, &rt);
915         if (err < 0)
916                 connman_error("Setting default interface route failed (%s)",
917                                                         strerror(errno));
918         close(sk);
919
920         return err;
921 }
922
923 int connman_inet_clear_gateway_address(int index, const char *gateway)
924 {
925         struct ifreq ifr;
926         struct rtentry rt;
927         struct sockaddr_in addr;
928         int sk, err;
929
930         DBG("index %d gateway %s", index, gateway);
931
932         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
933         if (sk < 0)
934                 return -1;
935
936         memset(&ifr, 0, sizeof(ifr));
937         ifr.ifr_ifindex = index;
938
939         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
940                 close(sk);
941                 return -1;
942         }
943
944         DBG("ifname %s", ifr.ifr_name);
945
946         memset(&rt, 0, sizeof(rt));
947         rt.rt_flags = RTF_UP | RTF_GATEWAY;
948
949         memset(&addr, 0, sizeof(addr));
950         addr.sin_family = AF_INET;
951         addr.sin_addr.s_addr = INADDR_ANY;
952         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
953
954         memset(&addr, 0, sizeof(addr));
955         addr.sin_family = AF_INET;
956         addr.sin_addr.s_addr = inet_addr(gateway);
957         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
958
959         memset(&addr, 0, sizeof(addr));
960         addr.sin_family = AF_INET;
961         addr.sin_addr.s_addr = INADDR_ANY;
962         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
963
964         err = ioctl(sk, SIOCDELRT, &rt);
965         if (err < 0)
966                 connman_error("Removing default gateway route failed (%s)",
967                                                         strerror(errno));
968
969         close(sk);
970
971         return err;
972 }
973
974 int connman_inet_clear_gateway_interface(int index)
975 {
976         struct ifreq ifr;
977         struct rtentry rt;
978         struct sockaddr_in addr;
979         int sk, err;
980
981         DBG("index %d", index);
982
983         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
984         if (sk < 0)
985                 return -1;
986
987         memset(&ifr, 0, sizeof(ifr));
988         ifr.ifr_ifindex = index;
989
990         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
991                 close(sk);
992                 return -1;
993         }
994
995         DBG("ifname %s", ifr.ifr_name);
996
997         memset(&rt, 0, sizeof(rt));
998         rt.rt_flags = RTF_UP;
999
1000         memset(&addr, 0, sizeof(addr));
1001         addr.sin_family = AF_INET;
1002         addr.sin_addr.s_addr = INADDR_ANY;
1003
1004         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1005         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1006         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1007
1008         rt.rt_dev = ifr.ifr_name;
1009
1010         err = ioctl(sk, SIOCDELRT, &rt);
1011         if (err < 0)
1012                 connman_error("Removing default interface route failed (%s)",
1013                                                         strerror(errno));
1014         close(sk);
1015
1016         return err;
1017 }
1018
1019 int connman_inet_clear_ipv6_gateway_interface(int index)
1020 {
1021         struct ifreq ifr;
1022         struct rtentry rt;
1023         struct sockaddr_in6 addr;
1024         const struct in6_addr any = IN6ADDR_ANY_INIT;
1025         int sk, err;
1026
1027         DBG("index %d", index);
1028
1029         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1030         if (sk < 0)
1031                 return -1;
1032
1033         memset(&ifr, 0, sizeof(ifr));
1034         ifr.ifr_ifindex = index;
1035
1036         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1037                 close(sk);
1038                 return -1;
1039         }
1040
1041         DBG("ifname %s", ifr.ifr_name);
1042
1043         memset(&rt, 0, sizeof(rt));
1044         rt.rt_flags = RTF_UP;
1045
1046         memset(&addr, 0, sizeof(addr));
1047         addr.sin6_family = AF_INET6;
1048         addr.sin6_addr = any;
1049
1050         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1051         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1052         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1053
1054         rt.rt_dev = ifr.ifr_name;
1055
1056         err = ioctl(sk, SIOCDELRT, &rt);
1057         if (err < 0)
1058                 connman_error("Removing default interface route failed (%s)",
1059                                                         strerror(errno));
1060         close(sk);
1061
1062         return err;
1063 }
1064
1065 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1066 {
1067         struct ifreq ifr;
1068         struct in_addr _host_addr;
1069         in_addr_t host_addr, netmask_addr, if_addr;
1070         struct sockaddr_in *netmask, *addr;
1071         int sk;
1072
1073         DBG("host %s", host);
1074
1075         if (host == NULL)
1076                 return FALSE;
1077
1078         if (inet_aton(host, &_host_addr) == 0)
1079                 return -1;
1080         host_addr = _host_addr.s_addr;
1081
1082         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1083         if (sk < 0)
1084                 return FALSE;
1085
1086         memset(&ifr, 0, sizeof(ifr));
1087         ifr.ifr_ifindex = index;
1088
1089         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1090                 close(sk);
1091                 return FALSE;
1092         }
1093
1094         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1095                 close(sk);
1096                 return FALSE;
1097         }
1098
1099         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1100         netmask_addr = netmask->sin_addr.s_addr;
1101
1102         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1103                 close(sk);
1104                 return FALSE;
1105         }
1106
1107         close(sk);
1108
1109         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1110         if_addr = addr->sin_addr.s_addr;
1111
1112         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1113 }
1114
1115 int connman_inet_remove_from_bridge(int index, const char *bridge)
1116 {
1117         struct ifreq ifr;
1118         int sk, err;
1119
1120         if (bridge == NULL)
1121                 return -EINVAL;
1122
1123         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1124         if (sk < 0)
1125                 return sk;
1126
1127         memset(&ifr, 0, sizeof(ifr));
1128         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1129         ifr.ifr_ifindex = index;
1130
1131         err = ioctl(sk, SIOCBRDELIF, &ifr);
1132
1133         close(sk);
1134
1135         if (err < 0) {
1136                 connman_error("Remove interface from bridge error %s",
1137                                                         strerror(errno));
1138                 return err;
1139         }
1140
1141         return 0;
1142 }
1143
1144 int connman_inet_add_to_bridge(int index, const char *bridge)
1145 {
1146         struct ifreq ifr;
1147         int sk, err;
1148
1149         if (bridge == NULL)
1150                 return -EINVAL;
1151
1152         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
1153         if (sk < 0)
1154                 return sk;
1155
1156         memset(&ifr, 0, sizeof(ifr));
1157         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1158         ifr.ifr_ifindex = index;
1159
1160         err = ioctl(sk, SIOCBRADDIF, &ifr);
1161
1162         close(sk);
1163
1164         if (err < 0) {
1165                 connman_error("Add interface to bridge error %s",
1166                                                         strerror(errno));
1167                 return err;
1168         }
1169
1170         return 0;
1171 }
1172
1173 int connman_inet_set_mtu(int index, int mtu)
1174 {
1175         struct ifreq ifr;
1176         int sk, err;
1177
1178         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1179         if (sk < 0)
1180                 return sk;
1181
1182         memset(&ifr, 0, sizeof(ifr));
1183         ifr.ifr_ifindex = index;
1184
1185         err = ioctl(sk, SIOCGIFNAME, &ifr);
1186         if (err == 0) {
1187                 ifr.ifr_mtu = mtu;
1188                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1189         }
1190
1191         close(sk);
1192         return err;
1193 }
1194
1195 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1196 {
1197         struct ifreq ifr;
1198         int sk, err, index;
1199         __u32 mask;
1200         __u32 flags;
1201
1202         if (tunnel == NULL)
1203                 return -EINVAL;
1204
1205         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1206         if (sk < 0)
1207                 return sk;
1208
1209         index = if_nametoindex(tunnel);
1210
1211         err = connman_inet_set_mtu(index, mtu);
1212         if (err != 0)
1213                 goto done;
1214
1215         memset(&ifr, 0, sizeof(ifr));
1216         strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1217         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1218         if (err)
1219                 goto done;
1220
1221         mask = IFF_UP;
1222         flags = IFF_UP;
1223
1224         if ((ifr.ifr_flags ^ flags) & mask) {
1225                 ifr.ifr_flags &= ~mask;
1226                 ifr.ifr_flags |= mask & flags;
1227                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1228                 if (err)
1229                         connman_error("SIOCSIFFLAGS failed: %s",
1230                                                         strerror(errno));
1231         }
1232
1233 done:
1234         close(sk);
1235         return err;
1236 }
1237
1238 int connman_inet_create_tunnel(char **iface)
1239 {
1240         struct ifreq ifr;
1241         int i, fd;
1242
1243         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
1244         if (fd < 0) {
1245                 i = -errno;
1246                 connman_error("Failed to open /dev/net/tun: %s",
1247                                 strerror(errno));
1248                 return i;
1249         }
1250
1251         memset(&ifr, 0, sizeof(ifr));
1252         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
1253
1254         for (i = 0; i < 256; i++) {
1255                 sprintf(ifr.ifr_name, "tun%d", i);
1256
1257                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
1258                         break;
1259         }
1260
1261         if (i == 256) {
1262                 connman_error("Failed to find available tun device");
1263                 close(fd);
1264                 return -ENODEV;
1265         }
1266
1267         *iface = g_strdup(ifr.ifr_name);
1268
1269         return fd;
1270 }
1271
1272 struct rs_cb_data {
1273         GIOChannel *channel;
1274         __connman_inet_rs_cb_t callback;
1275         struct sockaddr_in6 addr;
1276         guint rs_timeout;
1277         guint watch_id;
1278         void *user_data;
1279 };
1280
1281 #define CMSG_BUF_LEN 512
1282 #define IN6ADDR_ALL_NODES_MC_INIT \
1283         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x1 } } } /* ff02::1 */
1284 #define IN6ADDR_ALL_ROUTERS_MC_INIT \
1285         { { { 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2 } } } /* ff02::2 */
1286
1287 static const struct in6_addr in6addr_all_nodes_mc = IN6ADDR_ALL_NODES_MC_INIT;
1288 static const struct in6_addr in6addr_all_routers_mc =
1289                                                 IN6ADDR_ALL_ROUTERS_MC_INIT;
1290
1291 static void rs_cleanup(struct rs_cb_data *data)
1292 {
1293         if (data->channel != NULL) {
1294                 g_io_channel_shutdown(data->channel, TRUE, NULL);
1295                 g_io_channel_unref(data->channel);
1296                 data->channel = NULL;
1297         }
1298
1299         if (data->rs_timeout > 0)
1300                 g_source_remove(data->rs_timeout);
1301
1302         if (data->watch_id > 0)
1303                 g_source_remove(data->watch_id);
1304
1305         g_free(data);
1306 }
1307
1308 static gboolean rs_timeout_cb(gpointer user_data)
1309 {
1310         struct rs_cb_data *data = user_data;
1311
1312         DBG("user data %p", user_data);
1313
1314         if (data == NULL)
1315                 return FALSE;
1316
1317         if (data->callback != NULL)
1318                 data->callback(NULL, 0, data->user_data);
1319
1320         data->rs_timeout = 0;
1321         rs_cleanup(data);
1322         return FALSE;
1323 }
1324
1325 static int icmpv6_recv(int fd, gpointer user_data)
1326 {
1327         struct msghdr mhdr;
1328         struct iovec iov;
1329         unsigned char chdr[CMSG_BUF_LEN];
1330         unsigned char buf[1540];
1331         struct rs_cb_data *data = user_data;
1332         struct nd_router_advert *hdr;
1333         struct sockaddr_in6 saddr;
1334         ssize_t len;
1335
1336         DBG("");
1337
1338         iov.iov_len = sizeof(buf);
1339         iov.iov_base = buf;
1340
1341         mhdr.msg_name = (void *)&saddr;
1342         mhdr.msg_namelen = sizeof(struct sockaddr_in6);
1343         mhdr.msg_iov = &iov;
1344         mhdr.msg_iovlen = 1;
1345         mhdr.msg_control = (void *)chdr;
1346         mhdr.msg_controllen = CMSG_BUF_LEN;
1347
1348         len = recvmsg(fd, &mhdr, 0);
1349         if (len < 0) {
1350                 data->callback(NULL, 0, data->user_data);
1351                 rs_cleanup(data);
1352                 return -errno;
1353         }
1354
1355         hdr = (struct nd_router_advert *)buf;
1356         DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
1357                                 sizeof(struct nd_router_advert));
1358         if (hdr->nd_ra_code != 0)
1359                 return 0;
1360
1361         data->callback(hdr, len, data->user_data);
1362         rs_cleanup(data);
1363
1364         return len;
1365 }
1366
1367 static gboolean icmpv6_event(GIOChannel *chan, GIOCondition cond,
1368                                                                 gpointer data)
1369 {
1370         int fd, ret;
1371
1372         DBG("");
1373
1374         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1375                 return FALSE;
1376
1377         fd = g_io_channel_unix_get_fd(chan);
1378         ret = icmpv6_recv(fd, data);
1379         if (ret == 0)
1380                 return TRUE;
1381
1382         return FALSE;
1383 }
1384
1385 /* Adapted from RFC 1071 "C" Implementation Example */
1386 static uint16_t csum(const void *phdr, const void *data, socklen_t datalen)
1387 {
1388         register unsigned long sum = 0;
1389         socklen_t count;
1390         uint16_t *addr;
1391         int i;
1392
1393         /* caller must make sure datalen is even */
1394
1395         addr = (uint16_t *)phdr;
1396         for (i = 0; i < 20; i++)
1397                 sum += *addr++;
1398
1399         count = datalen;
1400         addr = (uint16_t *)data;
1401
1402         while (count > 1) {
1403                 sum += *(addr++);
1404                 count -= 2;
1405         }
1406
1407         while (sum >> 16)
1408                 sum = (sum & 0xffff) + (sum >> 16);
1409
1410         return (uint16_t)~sum;
1411 }
1412
1413 static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest)
1414 {
1415         struct _phdr {
1416                 struct in6_addr src;
1417                 struct in6_addr dst;
1418                 uint32_t plen;
1419                 uint8_t reserved[3];
1420                 uint8_t nxt;
1421         } phdr;
1422
1423         struct {
1424                 struct ip6_hdr ip;
1425                 union {
1426                         struct icmp6_hdr icmp;
1427                         struct nd_neighbor_solicit ns;
1428                         struct nd_router_solicit rs;
1429                 } i;
1430         } frame;
1431
1432         struct msghdr msgh;
1433         struct cmsghdr *cmsg;
1434         struct in6_pktinfo *pinfo;
1435         struct sockaddr_in6 dst;
1436         char cbuf[CMSG_SPACE(sizeof(*pinfo))];
1437         struct iovec iov;
1438         int fd, datalen, ret;
1439
1440         DBG("");
1441
1442         fd = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_RAW);
1443         if (fd < 0)
1444                 return -errno;
1445
1446         memset(&frame, 0, sizeof(frame));
1447         memset(&dst, 0, sizeof(dst));
1448
1449         datalen = sizeof(frame.i.rs); /* 8, csum() safe */
1450         dst.sin6_addr = *dest;
1451
1452         /* Fill in the IPv6 header */
1453         frame.ip.ip6_vfc = 0x60;
1454         frame.ip.ip6_plen = htons(datalen);
1455         frame.ip.ip6_nxt = IPPROTO_ICMPV6;
1456         frame.ip.ip6_hlim = 255;
1457         frame.ip.ip6_dst = dst.sin6_addr;
1458         /* all other fields are already set to zero */
1459
1460         /* Prepare pseudo header for csum */
1461         memset(&phdr, 0, sizeof(phdr));
1462         phdr.dst = dst.sin6_addr;
1463         phdr.plen = htonl(datalen);
1464         phdr.nxt = IPPROTO_ICMPV6;
1465
1466         /* Fill in remaining ICMP header fields */
1467         frame.i.icmp.icmp6_type = type;
1468         frame.i.icmp.icmp6_cksum = csum(&phdr, &frame.i, datalen);
1469
1470         iov.iov_base = &frame;
1471         iov.iov_len = sizeof(frame.ip) + datalen;
1472
1473         dst.sin6_family = AF_INET6;
1474         msgh.msg_name = &dst;
1475         msgh.msg_namelen = sizeof(dst);
1476         msgh.msg_iov = &iov;
1477         msgh.msg_iovlen = 1;
1478         msgh.msg_flags = 0;
1479
1480         memset(cbuf, 0, CMSG_SPACE(sizeof(*pinfo)));
1481         cmsg = (struct cmsghdr *)cbuf;
1482         pinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
1483         pinfo->ipi6_ifindex = oif;
1484
1485         cmsg->cmsg_len = CMSG_LEN(sizeof(*pinfo));
1486         cmsg->cmsg_level = IPPROTO_IPV6;
1487         cmsg->cmsg_type = IPV6_PKTINFO;
1488         msgh.msg_control = cmsg;
1489         msgh.msg_controllen = cmsg->cmsg_len;
1490
1491         ret = sendmsg(fd, &msgh, 0);
1492
1493         close(fd);
1494         return ret;
1495 }
1496
1497 static inline void ipv6_addr_set(struct in6_addr *addr,
1498                                 uint32_t w1, uint32_t w2,
1499                                 uint32_t w3, uint32_t w4)
1500 {
1501         addr->s6_addr32[0] = w1;
1502         addr->s6_addr32[1] = w2;
1503         addr->s6_addr32[2] = w3;
1504         addr->s6_addr32[3] = w4;
1505 }
1506
1507 static inline void ipv6_addr_solict_mult(const struct in6_addr *addr,
1508                                         struct in6_addr *solicited)
1509 {
1510         ipv6_addr_set(solicited, htonl(0xFF020000), 0, htonl(0x1),
1511                         htonl(0xFF000000) | addr->s6_addr32[3]);
1512 }
1513
1514 static int if_mc_group(int sock, int ifindex, const struct in6_addr *mc_addr,
1515                                                                 int cmd)
1516 {
1517         unsigned int val = 0;
1518         struct ipv6_mreq mreq;
1519         int ret;
1520
1521         memset(&mreq, 0, sizeof(mreq));
1522         mreq.ipv6mr_interface = ifindex;
1523         mreq.ipv6mr_multiaddr = *mc_addr;
1524
1525         ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
1526                         &val, sizeof(int));
1527
1528         if (ret < 0)
1529                 return ret;
1530
1531         return setsockopt(sock, IPPROTO_IPV6, cmd, &mreq, sizeof(mreq));
1532 }
1533
1534 int __connman_inet_ipv6_send_rs(int index, int timeout,
1535                         __connman_inet_rs_cb_t callback, void *user_data)
1536 {
1537         struct rs_cb_data *data;
1538         struct icmp6_filter filter;
1539         struct in6_addr solicit;
1540         struct in6_addr dst = in6addr_all_routers_mc;
1541         int sk;
1542
1543         DBG("");
1544
1545         if (timeout <= 0)
1546                 return -EINVAL;
1547
1548         data = g_try_malloc0(sizeof(struct rs_cb_data));
1549         if (data == NULL)
1550                 return -ENOMEM;
1551
1552         data->callback = callback;
1553         data->user_data = user_data;
1554         data->rs_timeout = g_timeout_add_seconds(timeout, rs_timeout_cb, data);
1555
1556         sk = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
1557         if (sk < 0)
1558                 return -errno;
1559
1560         ICMP6_FILTER_SETBLOCKALL(&filter);
1561         ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
1562
1563         setsockopt(sk, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
1564                                                 sizeof(struct icmp6_filter));
1565
1566         ipv6_addr_solict_mult(&dst, &solicit);
1567         if_mc_group(sk, index, &in6addr_all_nodes_mc, IPV6_JOIN_GROUP);
1568         if_mc_group(sk, index, &solicit, IPV6_JOIN_GROUP);
1569
1570         data->channel = g_io_channel_unix_new(sk);
1571         g_io_channel_set_close_on_unref(data->channel, TRUE);
1572
1573         g_io_channel_set_encoding(data->channel, NULL, NULL);
1574         g_io_channel_set_buffered(data->channel, FALSE);
1575
1576         data->watch_id = g_io_add_watch(data->channel,
1577                         G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1578                         icmpv6_event, data);
1579
1580         ndisc_send_unspec(ND_ROUTER_SOLICIT, index, &dst);
1581
1582         return 0;
1583 }
1584
1585 GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
1586                                         unsigned int length)
1587 {
1588         GSList *prefixes = NULL;
1589         uint8_t *pos;
1590         int len;
1591
1592         if (length <= sizeof(struct nd_router_advert))
1593                 return NULL;
1594
1595         len = length - sizeof(struct nd_router_advert);
1596         pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
1597
1598         while (len > 0) {
1599                 struct nd_opt_prefix_info *pinfo;
1600                 char prefix_str[INET6_ADDRSTRLEN+1], *str;
1601                 const char *prefix;
1602                 int optlen;
1603
1604                 if (len < 2)
1605                         break;
1606
1607                 optlen = pos[1] << 3;
1608                 if (optlen == 0 || optlen > len)
1609                         break;
1610
1611                 switch (pos[0]) {
1612                 case ND_OPT_PREFIX_INFORMATION:
1613                         pinfo = (struct nd_opt_prefix_info *)pos;
1614                         prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
1615                                         prefix_str, INET6_ADDRSTRLEN);
1616                         if (prefix == NULL)
1617                                 break;
1618
1619                         str = g_strdup_printf("%s/%d", prefix,
1620                                                 pinfo->nd_opt_pi_prefix_len);
1621                         prefixes = g_slist_prepend(prefixes, str);
1622
1623                         DBG("prefix %s", str);
1624
1625                         break;
1626                 }
1627
1628                 len -= optlen;
1629                 pos += optlen;
1630         }
1631
1632         return prefixes;
1633 }
1634
1635 static int get_dest_addr(int family, int index, char *buf, int len)
1636 {
1637         struct ifreq ifr;
1638         void *addr;
1639         int sk;
1640
1641         sk = socket(family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1642         if (sk < 0)
1643                 return -errno;
1644
1645         memset(&ifr, 0, sizeof(ifr));
1646         ifr.ifr_ifindex = index;
1647
1648         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1649                 DBG("SIOCGIFNAME (%d/%s)", errno, strerror(errno));
1650                 close(sk);
1651                 return -errno;
1652         }
1653
1654         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
1655                 DBG("SIOCGIFFLAGS (%d/%s)", errno, strerror(errno));
1656                 close(sk);
1657                 return -errno;
1658         }
1659
1660         if ((ifr.ifr_flags & IFF_POINTOPOINT) == 0) {
1661                 close(sk);
1662                 errno = EINVAL;
1663                 return -errno;
1664         }
1665
1666         DBG("index %d %s", index, ifr.ifr_name);
1667
1668         if (ioctl(sk, SIOCGIFDSTADDR, &ifr) < 0) {
1669                 connman_error("Get destination address failed (%s)",
1670                                                         strerror(errno));
1671                 close(sk);
1672                 return -errno;
1673         }
1674
1675         close(sk);
1676
1677         switch (family) {
1678         case AF_INET:
1679                 addr = &((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
1680                 break;
1681         case AF_INET6:
1682                 addr = &((struct sockaddr_in6 *)&ifr.ifr_dstaddr)->sin6_addr;
1683                 break;
1684         default:
1685                 errno = EINVAL;
1686                 return -errno;
1687         }
1688
1689         if (inet_ntop(family, addr, buf, len) == NULL) {
1690                 DBG("error %d/%s", errno, strerror(errno));
1691                 return -errno;
1692         }
1693
1694         return 0;
1695 }
1696
1697 int connman_inet_get_dest_addr(int index, char **dest)
1698 {
1699         char addr[INET_ADDRSTRLEN];
1700         int ret;
1701
1702         ret = get_dest_addr(PF_INET, index, addr, INET_ADDRSTRLEN);
1703         if (ret < 0)
1704                 return ret;
1705
1706         *dest = g_strdup(addr);
1707
1708         DBG("destination %s", *dest);
1709
1710         return 0;
1711 }
1712
1713 int connman_inet_ipv6_get_dest_addr(int index, char **dest)
1714 {
1715         char addr[INET6_ADDRSTRLEN];
1716         int ret;
1717
1718         ret = get_dest_addr(PF_INET6, index, addr, INET6_ADDRSTRLEN);
1719         if (ret < 0)
1720                 return ret;
1721
1722         *dest = g_strdup(addr);
1723
1724         DBG("destination %s", *dest);
1725
1726         return 0;
1727 }
1728
1729 int __connman_inet_rtnl_open(struct __connman_inet_rtnl_handle *rth)
1730 {
1731         int sndbuf = 1024;
1732         int rcvbuf = 1024 * 4;
1733
1734         rth->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
1735         if (rth->fd < 0) {
1736                 connman_error("Can not open netlink socket: %s",
1737                                                 strerror(errno));
1738                 return -errno;
1739         }
1740
1741         if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf,
1742                         sizeof(sndbuf)) < 0) {
1743                 connman_error("SO_SNDBUF: %s", strerror(errno));
1744                 return -errno;
1745         }
1746
1747         if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf,
1748                         sizeof(rcvbuf)) < 0) {
1749                 connman_error("SO_RCVBUF: %s", strerror(errno));
1750                 return -errno;
1751         }
1752
1753         memset(&rth->local, 0, sizeof(rth->local));
1754         rth->local.nl_family = AF_NETLINK;
1755         rth->local.nl_groups = 0;
1756
1757         if (bind(rth->fd, (struct sockaddr *)&rth->local,
1758                                                 sizeof(rth->local)) < 0) {
1759                 connman_error("Can not bind netlink socket: %s",
1760                                                         strerror(errno));
1761                 return -errno;
1762         }
1763
1764         rth->seq = time(NULL);
1765
1766         DBG("fd %d", rth->fd);
1767
1768         return 0;
1769 }
1770
1771 struct inet_rtnl_cb_data {
1772         GIOChannel *channel;
1773         __connman_inet_rtnl_cb_t callback;
1774         guint rtnl_timeout;
1775         guint watch_id;
1776         struct __connman_inet_rtnl_handle *rtnl;
1777         void *user_data;
1778 };
1779
1780 static void inet_rtnl_cleanup(struct inet_rtnl_cb_data *data)
1781 {
1782         struct __connman_inet_rtnl_handle *rth = data->rtnl;
1783
1784         if (data->channel != NULL) {
1785                 g_io_channel_shutdown(data->channel, TRUE, NULL);
1786                 g_io_channel_unref(data->channel);
1787                 data->channel = NULL;
1788         }
1789
1790         DBG("data %p", data);
1791
1792         if (data->rtnl_timeout > 0)
1793                 g_source_remove(data->rtnl_timeout);
1794
1795         if (data->watch_id > 0)
1796                 g_source_remove(data->watch_id);
1797
1798         if (rth != NULL) {
1799                 __connman_inet_rtnl_close(rth);
1800                 g_free(rth);
1801         }
1802
1803         g_free(data);
1804 }
1805
1806 static gboolean inet_rtnl_timeout_cb(gpointer user_data)
1807 {
1808         struct inet_rtnl_cb_data *data = user_data;
1809
1810         DBG("user data %p", user_data);
1811
1812         if (data == NULL)
1813                 return FALSE;
1814
1815         if (data->callback != NULL)
1816                 data->callback(NULL, data->user_data);
1817
1818         data->rtnl_timeout = 0;
1819         inet_rtnl_cleanup(data);
1820         return FALSE;
1821 }
1822
1823 static int inet_rtnl_recv(GIOChannel *chan, gpointer user_data)
1824 {
1825         struct inet_rtnl_cb_data *rtnl_data = user_data;
1826         struct __connman_inet_rtnl_handle *rth = rtnl_data->rtnl;
1827         struct nlmsghdr *h = NULL;
1828         struct sockaddr_nl nladdr;
1829         socklen_t addr_len = sizeof(nladdr);
1830         unsigned char buf[4096];
1831         void *ptr = buf;
1832         gsize len;
1833         int status, fd;
1834
1835         memset(buf, 0, sizeof(buf));
1836         memset(&nladdr, 0, sizeof(nladdr));
1837
1838         fd = g_io_channel_unix_get_fd(chan);
1839
1840         status = recvfrom(fd, buf, sizeof(buf), 0,
1841                        (struct sockaddr *) &nladdr, &addr_len);
1842         if (status < 0) {
1843                 if (errno == EINTR || errno == EAGAIN)
1844                         return 0;
1845
1846                 return -1;
1847         }
1848
1849         if (status == 0)
1850                 return -1;
1851
1852         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1853                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1854                 return 0;
1855         }
1856
1857         len = status;
1858
1859         while (len > 0) {
1860                 struct nlmsgerr *err;
1861
1862                 h = ptr;
1863
1864                 if (!NLMSG_OK(h, len)) {
1865                         return -1;
1866                         break;
1867                 }
1868
1869                 if (h->nlmsg_seq != rth->seq) {
1870                         /* Skip this msg */
1871                         DBG("skip %d/%d len %d", rth->seq,
1872                                 h->nlmsg_seq, h->nlmsg_len);
1873
1874                         len -= h->nlmsg_len;
1875                         ptr += h->nlmsg_len;
1876                         continue;
1877                 }
1878
1879                 switch (h->nlmsg_type) {
1880                 case NLMSG_NOOP:
1881                 case NLMSG_OVERRUN:
1882                         return -1;
1883
1884                 case NLMSG_ERROR:
1885                         err = (struct nlmsgerr *)NLMSG_DATA(h);
1886                         connman_error("RTNETLINK answers %s (%d)",
1887                                 strerror(-err->error), -err->error);
1888                         return err->error;
1889                 }
1890
1891                 break;
1892         }
1893
1894         if (h->nlmsg_seq == rth->seq) {
1895                 DBG("received %d seq %d", h->nlmsg_len, h->nlmsg_seq);
1896
1897                 rtnl_data->callback(h, rtnl_data->user_data);
1898
1899                 inet_rtnl_cleanup(rtnl_data);
1900         }
1901
1902         return 0;
1903 }
1904
1905 static gboolean inet_rtnl_event(GIOChannel *chan, GIOCondition cond,
1906                                                         gpointer user_data)
1907 {
1908         int ret;
1909
1910         DBG("");
1911
1912         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1913                 return FALSE;
1914
1915         ret = inet_rtnl_recv(chan, user_data);
1916         if (ret != 0)
1917                 return TRUE;
1918
1919         return FALSE;
1920 }
1921
1922 int __connman_inet_rtnl_talk(struct __connman_inet_rtnl_handle *rtnl,
1923                         struct nlmsghdr *n, int timeout,
1924                         __connman_inet_rtnl_cb_t callback, void *user_data)
1925 {
1926         struct sockaddr_nl nladdr;
1927         struct inet_rtnl_cb_data *data;
1928         unsigned seq;
1929         int err;
1930
1931         memset(&nladdr, 0, sizeof(nladdr));
1932         nladdr.nl_family = AF_NETLINK;
1933
1934         n->nlmsg_seq = seq = ++rtnl->seq;
1935
1936         if (callback != NULL) {
1937                 data = g_try_malloc0(sizeof(struct inet_rtnl_cb_data));
1938                 if (data == NULL)
1939                         return -ENOMEM;
1940
1941                 data->callback = callback;
1942                 data->user_data = user_data;
1943                 data->rtnl = rtnl;
1944                 data->rtnl_timeout = g_timeout_add_seconds(timeout,
1945                                                 inet_rtnl_timeout_cb, data);
1946
1947                 data->channel = g_io_channel_unix_new(rtnl->fd);
1948                 g_io_channel_set_close_on_unref(data->channel, TRUE);
1949
1950                 g_io_channel_set_encoding(data->channel, NULL, NULL);
1951                 g_io_channel_set_buffered(data->channel, FALSE);
1952
1953                 data->watch_id = g_io_add_watch(data->channel,
1954                                 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1955                                                 inet_rtnl_event, data);
1956         } else
1957                 n->nlmsg_flags |= NLM_F_ACK;
1958
1959         err = sendto(rtnl->fd, &rtnl->req.n, rtnl->req.n.nlmsg_len, 0,
1960                 (struct sockaddr *) &nladdr, sizeof(nladdr));
1961         DBG("handle %p len %d err %d", rtnl, rtnl->req.n.nlmsg_len, err);
1962         if (err < 0) {
1963                 connman_error("Can not talk to rtnetlink");
1964                 return -errno;
1965         }
1966
1967         if ((unsigned int)err != rtnl->req.n.nlmsg_len) {
1968                 connman_error("Sent %d bytes, msg truncated", err);
1969                 return -EINVAL;
1970         }
1971
1972         return 0;
1973 }
1974
1975 void __connman_inet_rtnl_close(struct __connman_inet_rtnl_handle *rth)
1976 {
1977         DBG("handle %p", rth);
1978
1979         if (rth->fd >= 0) {
1980                 close(rth->fd);
1981                 rth->fd = -1;
1982         }
1983 }
1984
1985 int __connman_inet_rtnl_addattr32(struct nlmsghdr *n, size_t maxlen, int type,
1986                                 __u32 data)
1987 {
1988         int len = RTA_LENGTH(4);
1989         struct rtattr *rta;
1990
1991         if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen) {
1992                 DBG("Error! max allowed bound %zd exceeded", maxlen);
1993                 return -1;
1994         }
1995         rta = NLMSG_TAIL(n);
1996         rta->rta_type = type;
1997         rta->rta_len = len;
1998         memcpy(RTA_DATA(rta), &data, 4);
1999         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
2000
2001         return 0;
2002 }
2003
2004 static int parse_rtattr(struct rtattr *tb[], int max,
2005                         struct rtattr *rta, int len)
2006 {
2007         memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
2008         while (RTA_OK(rta, len)) {
2009                 if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
2010                         tb[rta->rta_type] = rta;
2011                 rta = RTA_NEXT(rta, len);
2012         }
2013         if (len)
2014                 connman_error("Deficit %d, rta_len=%d", len, rta->rta_len);
2015
2016         return 0;
2017 }
2018
2019 struct get_route_cb_data {
2020         connman_inet_addr_cb_t callback;
2021         void *user_data;
2022 };
2023
2024 static void get_route_cb(struct nlmsghdr *answer, void *user_data)
2025 {
2026         struct get_route_cb_data *data = user_data;
2027         struct rtattr *tb[RTA_MAX+1];
2028         struct rtmsg *r = NLMSG_DATA(answer);
2029         int len, index = -1;
2030         char abuf[256];
2031         const char *addr = NULL;
2032
2033         DBG("answer %p data %p", answer, user_data);
2034
2035         if (answer == NULL)
2036                 goto out;
2037
2038         len = answer->nlmsg_len;
2039
2040         if (answer->nlmsg_type != RTM_NEWROUTE &&
2041                                 answer->nlmsg_type != RTM_DELROUTE) {
2042                 connman_error("Not a route: %08x %08x %08x",
2043                         answer->nlmsg_len, answer->nlmsg_type,
2044                         answer->nlmsg_flags);
2045                 goto out;
2046         }
2047
2048         len -= NLMSG_LENGTH(sizeof(*r));
2049         if (len < 0) {
2050                 connman_error("BUG: wrong nlmsg len %d", len);
2051                 goto out;
2052         }
2053
2054         parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
2055
2056         if (tb[RTA_OIF] != NULL)
2057                 index = *(int *)RTA_DATA(tb[RTA_OIF]);
2058
2059         if (tb[RTA_GATEWAY] != NULL)
2060                 addr = inet_ntop(r->rtm_family,
2061                                 RTA_DATA(tb[RTA_GATEWAY]),
2062                                 abuf, sizeof(abuf));
2063
2064         DBG("addr %s index %d user %p", addr, index, data->user_data);
2065
2066 out:
2067         if (data != NULL && data->callback != NULL)
2068                 data->callback(addr, index, data->user_data);
2069
2070         g_free(data);
2071
2072         return;
2073 }
2074
2075 /*
2076  * Return the interface index that contains route to host.
2077  */
2078 int __connman_inet_get_route(const char *dest_address,
2079                         connman_inet_addr_cb_t callback, void *user_data)
2080 {
2081         struct get_route_cb_data *data;
2082         struct addrinfo hints, *rp;
2083         struct __connman_inet_rtnl_handle *rth;
2084         int err;
2085
2086         DBG("dest %s", dest_address);
2087
2088         if (dest_address == NULL)
2089                 return -EINVAL;
2090
2091         memset(&hints, 0, sizeof(hints));
2092         hints.ai_family = AF_UNSPEC;
2093         hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV | AI_NUMERICHOST;
2094
2095         err = getaddrinfo(dest_address, NULL, &hints, &rp);
2096         if (err)
2097                 return -EINVAL;
2098
2099         rth = g_try_malloc0(sizeof(struct __connman_inet_rtnl_handle));
2100         if (rth == NULL) {
2101                 freeaddrinfo(rp);
2102                 return -ENOMEM;
2103         }
2104
2105         rth->req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
2106         rth->req.n.nlmsg_flags = NLM_F_REQUEST;
2107         rth->req.n.nlmsg_type = RTM_GETROUTE;
2108         rth->req.u.r.rt.rtm_family = rp->ai_family;
2109         rth->req.u.r.rt.rtm_table = 0;
2110         rth->req.u.r.rt.rtm_protocol = 0;
2111         rth->req.u.r.rt.rtm_scope = 0;
2112         rth->req.u.r.rt.rtm_type = 0;
2113         rth->req.u.r.rt.rtm_src_len = 0;
2114         rth->req.u.r.rt.rtm_dst_len = rp->ai_addrlen << 3;
2115         rth->req.u.r.rt.rtm_tos = 0;
2116
2117         __connman_inet_rtnl_addattr_l(&rth->req.n, sizeof(rth->req), RTA_DST,
2118                                 &rp->ai_addr, rp->ai_addrlen);
2119
2120         freeaddrinfo(rp);
2121
2122         err = __connman_inet_rtnl_open(rth);
2123         if (err < 0)
2124                 goto fail;
2125
2126         data = g_try_malloc(sizeof(struct get_route_cb_data));
2127         if (data == NULL) {
2128                 err = -ENOMEM;
2129                 goto done;
2130         }
2131
2132         data->callback = callback;
2133         data->user_data = user_data;
2134
2135 #define GET_ROUTE_TIMEOUT 2
2136         err = __connman_inet_rtnl_talk(rth, &rth->req.n, GET_ROUTE_TIMEOUT,
2137                                 get_route_cb, data);
2138         if (err < 0) {
2139                 g_free(data);
2140                 goto done;
2141         }
2142
2143         return 0;
2144
2145 done:
2146         __connman_inet_rtnl_close(rth);
2147
2148 fail:
2149         g_free(rth);
2150         return err;
2151 }
2152
2153 int connman_inet_check_ipaddress(const char *host)
2154 {
2155         struct addrinfo hints;
2156         struct addrinfo *addr;
2157         int result;
2158
2159         memset(&hints, 0, sizeof(struct addrinfo));
2160         hints.ai_flags = AI_NUMERICHOST;
2161         addr = NULL;
2162
2163         result = getaddrinfo(host, NULL, &hints, &addr);
2164         if (result == 0)
2165                 result = addr->ai_family;
2166         freeaddrinfo(addr);
2167
2168         return result;
2169 }
2170
2171 /* Check routine modified from ics-dhcp 4.2.3-P2 */
2172 connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
2173 {
2174         const char *p;
2175
2176         /*
2177          * Not empty or complete length not over 255 characters.
2178          */
2179         if ((len == 0) || (len > 256))
2180                 return FALSE;
2181
2182         /*
2183          * Consists of [[:alnum:]-]+ labels separated by [.]
2184          * a [_] is against RFC but seems to be "widely used"
2185          */
2186         for (p = ptr; (*p != 0) && (len-- > 0); p++) {
2187
2188                 if ((*p == '-') || (*p == '_')) {
2189                         /*
2190                          * Not allowed at begin or end of a label.
2191                          */
2192                         if (((p - ptr) == 0) || (len == 0) || (p[1] == '.'))
2193                                 return FALSE;
2194
2195                 } else if (*p == '.') {
2196                         /*
2197                          * Each label has to be 1-63 characters;
2198                          * we allow [.] at the end ('foo.bar.')
2199                          */
2200                         size_t d = p - ptr;
2201
2202                         if ((d <= 0) || (d >= 64))
2203                                 return FALSE;
2204
2205                         ptr = p + 1; /* Jump to the next label */
2206
2207                 } else if (isalnum((unsigned char)*p) == 0) {
2208                         /*
2209                          * Also numbers at the begin are fine
2210                          */
2211                         return FALSE;
2212                 }
2213         }
2214
2215         return TRUE;
2216 }
2217
2218 char **__connman_inet_get_running_interfaces(void)
2219 {
2220         char **result;
2221         struct ifconf ifc;
2222         struct ifreq *ifr = NULL;
2223         int sk, i, numif, count = 0;
2224
2225         memset(&ifc, 0, sizeof(ifc));
2226
2227         sk = socket(AF_INET, SOCK_DGRAM, 0);
2228         if (sk < 0)
2229                 return NULL;
2230
2231         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2232                 goto error;
2233
2234         /*
2235          * Allocate some extra bytes just in case there will
2236          * be new interfaces added between two SIOCGIFCONF
2237          * calls.
2238          */
2239         ifr = g_try_malloc0(ifc.ifc_len * 2);
2240         if (ifr == NULL)
2241                 goto error;
2242
2243         ifc.ifc_req = ifr;
2244
2245         if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
2246                 goto error;
2247
2248         numif = ifc.ifc_len / sizeof(struct ifreq);
2249
2250         result = g_try_malloc0((numif + 1) * sizeof(char *));
2251         if (result == NULL)
2252                 goto error;
2253
2254         close(sk);
2255
2256         for (i = 0; i < numif; i++) {
2257                 struct ifreq *r = &ifr[i];
2258                 struct in6_addr *addr6;
2259                 in_addr_t addr4;
2260
2261                 /*
2262                  * Note that we do not return loopback interfaces here as they
2263                  * are not needed for our purposes.
2264                  */
2265                 switch (r->ifr_addr.sa_family) {
2266                 case AF_INET:
2267                         addr4 = ntohl(((struct sockaddr_in *)
2268                                                 &r->ifr_addr)->sin_addr.s_addr);
2269                         if (((addr4 & 0xff000000) >> 24) == 127)
2270                                 continue;
2271                         break;
2272                 case AF_INET6:
2273                         addr6 = &((struct sockaddr_in6 *)
2274                                                 &r->ifr_addr)->sin6_addr;
2275                         if (IN6_IS_ADDR_LINKLOCAL(addr6))
2276                                 continue;
2277                         break;
2278                 }
2279
2280                 result[count++] = g_strdup(r->ifr_name);
2281         }
2282
2283         free(ifr);
2284
2285         if (count < numif)
2286                 result = g_try_realloc(result, (count + 1) * sizeof(char *));
2287
2288         return result;
2289
2290 error:
2291         close(sk);
2292         free(ifr);
2293         return NULL;
2294 }
2295
2296 connman_bool_t connman_inet_is_ipv6_supported()
2297 {
2298         int sk;
2299
2300         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
2301         if (sk < 0)
2302                 return FALSE;
2303
2304         close(sk);
2305         return TRUE;
2306 }