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