inet: MTU and tunnel setup functions added.
[platform/upstream/connman.git] / src / inet.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/stat.h>
32 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <linux/sockios.h>
35 #include <arpa/inet.h>
36 #include <net/route.h>
37 #include <net/ethernet.h>
38 #include <net/if.h>
39 #include <net/if_arp.h>
40
41 #include "connman.h"
42
43 #define NLMSG_TAIL(nmsg)                                \
44         ((struct rtattr *) (((uint8_t*) (nmsg)) +       \
45         NLMSG_ALIGN((nmsg)->nlmsg_len)))
46
47 static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type,
48                                 const void *data, size_t data_length)
49 {
50         size_t length;
51         struct rtattr *rta;
52
53         length = RTA_LENGTH(data_length);
54
55         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length)
56                 return -E2BIG;
57
58         rta = NLMSG_TAIL(n);
59         rta->rta_type = type;
60         rta->rta_len = length;
61         memcpy(RTA_DATA(rta), data, data_length);
62         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length);
63
64         return 0;
65 }
66
67 int __connman_inet_modify_address(int cmd, int flags,
68                                 int index, int family,
69                                 const char *address,
70                                 const char *peer,
71                                 unsigned char prefixlen,
72                                 const char *broadcast)
73 {
74         uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
75                         NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
76                         RTA_LENGTH(sizeof(struct in6_addr)) +
77                         RTA_LENGTH(sizeof(struct in6_addr))];
78
79         struct nlmsghdr *header;
80         struct sockaddr_nl nl_addr;
81         struct ifaddrmsg *ifaddrmsg;
82         struct in6_addr ipv6_addr;
83         struct in_addr ipv4_addr, ipv4_dest, ipv4_bcast;
84         int sk, err;
85
86         DBG("");
87
88         if (address == NULL)
89                 return -1;
90
91         if (family != AF_INET && family != AF_INET6)
92                 return -1;
93
94         memset(&request, 0, sizeof(request));
95
96         header = (struct nlmsghdr *)request;
97         header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
98         header->nlmsg_type = cmd;
99         header->nlmsg_flags = NLM_F_REQUEST | flags;
100         header->nlmsg_seq = 1;
101
102         ifaddrmsg = NLMSG_DATA(header);
103         ifaddrmsg->ifa_family = family;
104         ifaddrmsg->ifa_prefixlen = prefixlen;
105         ifaddrmsg->ifa_flags = IFA_F_PERMANENT;
106         ifaddrmsg->ifa_scope = RT_SCOPE_UNIVERSE;
107         ifaddrmsg->ifa_index = index;
108
109         if (family == AF_INET) {
110                 if (inet_pton(AF_INET, address, &ipv4_addr) < 1)
111                         return -1;
112
113                 if (broadcast != NULL)
114                         inet_pton(AF_INET, broadcast, &ipv4_bcast);
115                 else
116                         ipv4_bcast.s_addr = ipv4_addr.s_addr |
117                                 htonl(0xfffffffflu >> prefixlen);
118
119                 if (peer != NULL) {
120                         if (inet_pton(AF_INET, peer, &ipv4_dest) < 1)
121                                 return -1;
122
123                         if ((err = add_rtattr(header, sizeof(request),
124                                         IFA_ADDRESS,
125                                         &ipv4_dest, sizeof(ipv4_dest))) < 0)
126                         return err;
127                 }
128
129                 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
130                                 &ipv4_addr, sizeof(ipv4_addr))) < 0)
131                         return err;
132
133                 if ((err = add_rtattr(header, sizeof(request), IFA_BROADCAST,
134                                 &ipv4_bcast, sizeof(ipv4_bcast))) < 0)
135                         return err;
136
137         } else if (family == AF_INET6) {
138                 if (inet_pton(AF_INET6, address, &ipv6_addr) < 1)
139                         return -1;
140
141                 if ((err = add_rtattr(header, sizeof(request), IFA_LOCAL,
142                                 &ipv6_addr, sizeof(ipv6_addr))) < 0)
143                         return err;
144         }
145
146         sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
147         if (sk < 0)
148                 return -1;
149
150         memset(&nl_addr, 0, sizeof(nl_addr));
151         nl_addr.nl_family = AF_NETLINK;
152
153         if ((err = sendto(sk, request, header->nlmsg_len, 0,
154                         (struct sockaddr *) &nl_addr, sizeof(nl_addr))) < 0)
155                 goto done;
156
157         err = 0;
158
159 done:
160         close(sk);
161
162         return err;
163 }
164
165 int connman_inet_ifindex(const char *name)
166 {
167         struct ifreq ifr;
168         int sk, err;
169
170         if (name == NULL)
171                 return -1;
172
173         sk = socket(PF_INET, SOCK_DGRAM, 0);
174         if (sk < 0)
175                 return -1;
176
177         memset(&ifr, 0, sizeof(ifr));
178         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
179
180         err = ioctl(sk, SIOCGIFINDEX, &ifr);
181
182         close(sk);
183
184         if (err < 0)
185                 return -1;
186
187         return ifr.ifr_ifindex;
188 }
189
190 char *connman_inet_ifname(int index)
191 {
192         struct ifreq ifr;
193         int sk, err;
194
195         if (index < 0)
196                 return NULL;
197
198         sk = socket(PF_INET, SOCK_DGRAM, 0);
199         if (sk < 0)
200                 return NULL;
201
202         memset(&ifr, 0, sizeof(ifr));
203         ifr.ifr_ifindex = index;
204
205         err = ioctl(sk, SIOCGIFNAME, &ifr);
206
207         close(sk);
208
209         if (err < 0)
210                 return NULL;
211
212         return strdup(ifr.ifr_name);
213 }
214
215 short int connman_inet_ifflags(int index)
216 {
217         struct ifreq ifr;
218         int sk, err;
219
220         sk = socket(PF_INET, SOCK_DGRAM, 0);
221         if (sk < 0)
222                 return -errno;
223
224         memset(&ifr, 0, sizeof(ifr));
225         ifr.ifr_ifindex = index;
226
227         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
228                 err = -errno;
229                 goto done;
230         }
231
232         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
233                 err = -errno;
234                 goto done;
235         }
236
237         err = ifr.ifr_flags;
238
239 done:
240         close(sk);
241
242         return err;
243 }
244
245 int connman_inet_ifup(int index)
246 {
247         struct ifreq ifr;
248         int sk, err;
249
250         sk = socket(PF_INET, SOCK_DGRAM, 0);
251         if (sk < 0)
252                 return -errno;
253
254         memset(&ifr, 0, sizeof(ifr));
255         ifr.ifr_ifindex = index;
256
257         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
258                 err = -errno;
259                 goto done;
260         }
261
262         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
263                 err = -errno;
264                 goto done;
265         }
266
267         if (ifr.ifr_flags & IFF_UP) {
268                 err = -EALREADY;
269                 goto done;
270         }
271
272         ifr.ifr_flags |= IFF_UP;
273
274         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
275                 err = -errno;
276                 goto done;
277         }
278
279         err = 0;
280
281 done:
282         close(sk);
283
284         return err;
285 }
286
287 int connman_inet_ifdown(int index)
288 {
289         struct ifreq ifr;
290         int sk, err;
291
292         sk = socket(PF_INET, SOCK_DGRAM, 0);
293         if (sk < 0)
294                 return -errno;
295
296         memset(&ifr, 0, sizeof(ifr));
297         ifr.ifr_ifindex = index;
298
299         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
300                 err = -errno;
301                 goto done;
302         }
303
304         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
305                 err = -errno;
306                 goto done;
307         }
308
309         if (!(ifr.ifr_flags & IFF_UP)) {
310                 err = -EALREADY;
311                 goto done;
312         }
313
314         ifr.ifr_flags &= ~IFF_UP;
315
316         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
317                 err = -errno;
318         else
319                 err = 0;
320
321 done:
322         close(sk);
323
324         return err;
325 }
326
327 static char *index2addr(int index)
328 {
329         struct ifreq ifr;
330         struct ether_addr eth;
331         char *str;
332         int sk, err;
333
334         if (index < 0)
335                 return NULL;
336
337         sk = socket(PF_INET, SOCK_DGRAM, 0);
338         if (sk < 0)
339                 return NULL;
340
341         memset(&ifr, 0, sizeof(ifr));
342         ifr.ifr_ifindex = index;
343
344         err = ioctl(sk, SIOCGIFNAME, &ifr);
345
346         if (err == 0)
347                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
348
349         close(sk);
350
351         if (err < 0)
352                 return NULL;
353
354         str = malloc(18);
355         if (!str)
356                 return NULL;
357
358         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
359         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
360                                                 eth.ether_addr_octet[0],
361                                                 eth.ether_addr_octet[1],
362                                                 eth.ether_addr_octet[2],
363                                                 eth.ether_addr_octet[3],
364                                                 eth.ether_addr_octet[4],
365                                                 eth.ether_addr_octet[5]);
366
367         return str;
368 }
369
370 static char *index2ident(int index, const char *prefix)
371 {
372         struct ifreq ifr;
373         struct ether_addr eth;
374         char *str;
375         int sk, err, len;
376
377         if (index < 0)
378                 return NULL;
379
380         sk = socket(PF_INET, SOCK_DGRAM, 0);
381         if (sk < 0)
382                 return NULL;
383
384         memset(&ifr, 0, sizeof(ifr));
385         ifr.ifr_ifindex = index;
386
387         err = ioctl(sk, SIOCGIFNAME, &ifr);
388
389         if (err == 0)
390                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
391
392         close(sk);
393
394         if (err < 0)
395                 return NULL;
396
397         len = prefix ? strlen(prefix) + 18 : 18;
398
399         str = malloc(len);
400         if (!str)
401                 return NULL;
402
403         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
404         snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
405                                                 prefix ? prefix : "",
406                                                 eth.ether_addr_octet[0],
407                                                 eth.ether_addr_octet[1],
408                                                 eth.ether_addr_octet[2],
409                                                 eth.ether_addr_octet[3],
410                                                 eth.ether_addr_octet[4],
411                                                 eth.ether_addr_octet[5]);
412
413         return str;
414 }
415
416 connman_bool_t connman_inet_is_cfg80211(int index)
417 {
418         connman_bool_t result = FALSE;
419         char phy80211_path[PATH_MAX];
420         struct stat st;
421         struct ifreq ifr;
422         int sk;
423
424         sk = socket(PF_INET, SOCK_DGRAM, 0);
425         if (sk < 0)
426                 return FALSE;
427
428         memset(&ifr, 0, sizeof(ifr));
429         ifr.ifr_ifindex = index;
430
431         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
432                 goto done;
433
434         snprintf(phy80211_path, PATH_MAX,
435                                 "/sys/class/net/%s/phy80211", ifr.ifr_name);
436
437         if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
438                 result = TRUE;
439
440 done:
441         close(sk);
442
443         return result;
444 }
445
446 struct connman_device *connman_inet_create_device(int index)
447 {
448         enum connman_device_type type;
449         struct connman_device *device;
450         char *devname, *ident = NULL;
451         char *addr = NULL, *name = NULL;
452
453         if (index < 0)
454                 return NULL;
455
456         devname = connman_inet_ifname(index);
457         if (devname == NULL)
458                 return NULL;
459
460         if (__connman_element_device_isfiltered(devname) == TRUE) {
461                 connman_info("Ignoring interface %s (filtered)", devname);
462                 free(devname);
463                 return NULL;
464         }
465
466         type = __connman_rtnl_get_device_type(index);
467
468         switch (type) {
469         case CONNMAN_DEVICE_TYPE_UNKNOWN:
470                 connman_info("Ignoring interface %s (type unknown)", devname);
471                 free(devname);
472                 return NULL;
473         case CONNMAN_DEVICE_TYPE_ETHERNET:
474         case CONNMAN_DEVICE_TYPE_GADGET:
475         case CONNMAN_DEVICE_TYPE_WIFI:
476         case CONNMAN_DEVICE_TYPE_WIMAX:
477                 name = index2ident(index, "");
478                 addr = index2addr(index);
479                 break;
480         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
481         case CONNMAN_DEVICE_TYPE_CELLULAR:
482         case CONNMAN_DEVICE_TYPE_GPS:
483         case CONNMAN_DEVICE_TYPE_VENDOR:
484                 name = strdup(devname);
485                 break;
486         }
487
488         device = connman_device_create(name, type);
489         if (device == NULL)
490                 goto done;
491
492         switch (type) {
493         case CONNMAN_DEVICE_TYPE_UNKNOWN:
494         case CONNMAN_DEVICE_TYPE_VENDOR:
495         case CONNMAN_DEVICE_TYPE_GPS:
496                 break;
497         case CONNMAN_DEVICE_TYPE_ETHERNET:
498         case CONNMAN_DEVICE_TYPE_GADGET:
499                 ident = index2ident(index, NULL);
500                 break;
501         case CONNMAN_DEVICE_TYPE_WIFI:
502         case CONNMAN_DEVICE_TYPE_WIMAX:
503                 ident = index2ident(index, NULL);
504                 break;
505         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
506                 break;
507         case CONNMAN_DEVICE_TYPE_CELLULAR:
508                 ident = index2ident(index, NULL);
509                 break;
510         }
511
512         connman_device_set_index(device, index);
513         connman_device_set_interface(device, devname);
514
515         if (ident != NULL) {
516                 connman_device_set_ident(device, ident);
517                 free(ident);
518         }
519
520         connman_device_set_string(device, "Address", addr);
521
522 done:
523         free(devname);
524         free(name);
525         free(addr);
526
527         return device;
528 }
529
530 struct in6_ifreq {
531         struct in6_addr ifr6_addr;
532         __u32 ifr6_prefixlen;
533         unsigned int ifr6_ifindex;
534 };
535
536 int connman_inet_set_ipv6_address(int index,
537                 struct connman_ipaddress *ipaddress)
538 {
539         unsigned char prefix_len;
540         const char *address;
541
542         if (ipaddress->local == NULL)
543                 return 0;
544
545         prefix_len = ipaddress->prefixlen;
546         address = ipaddress->local;
547
548         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
549
550         if ((__connman_inet_modify_address(RTM_NEWADDR,
551                         NLM_F_REPLACE | NLM_F_ACK, index, AF_INET6,
552                                 address, NULL, prefix_len, NULL)) < 0) {
553                 connman_error("Set IPv6 address error");
554                 return -1;
555         }
556
557         return 0;
558 }
559
560 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
561 {
562         unsigned char prefix_len;
563         const char *address, *broadcast, *peer;
564
565         if (ipaddress->local == NULL)
566                 return -1;
567
568         prefix_len = ipaddress->prefixlen;
569         address = ipaddress->local;
570         broadcast = ipaddress->broadcast;
571         peer = ipaddress->peer;
572
573         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
574
575         if ((__connman_inet_modify_address(RTM_NEWADDR,
576                         NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
577                                 address, peer, prefix_len, broadcast)) < 0) {
578                 DBG("address setting failed");
579                 return -1;
580         }
581
582         return 0;
583 }
584
585 int connman_inet_clear_ipv6_address(int index, const char *address,
586                                                         int prefix_len)
587 {
588         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
589
590         if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET6,
591                                         address, NULL, prefix_len, NULL)) < 0) {
592                 connman_error("Clear IPv6 address error");
593                 return -1;
594         }
595
596         return 0;
597 }
598
599 int connman_inet_clear_address(int index, struct connman_ipaddress *ipaddress)
600 {
601         unsigned char prefix_len;
602         const char *address, *broadcast, *peer;
603
604         prefix_len = ipaddress->prefixlen;
605         address = ipaddress->local;
606         broadcast = ipaddress->broadcast;
607         peer = ipaddress->peer;
608
609         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
610
611         if ((__connman_inet_modify_address(RTM_DELADDR, 0, index, AF_INET,
612                                 address, peer, prefix_len, broadcast)) < 0) {
613                 DBG("address removal failed");
614                 return -1;
615         }
616
617         return 0;
618 }
619
620 int connman_inet_add_host_route(int index, const char *host,
621                                 const char *gateway)
622 {
623         return connman_inet_add_network_route(index, host, gateway, NULL);
624 }
625
626 int connman_inet_del_host_route(int index, const char *host)
627 {
628         return connman_inet_del_network_route(index, host);
629 }
630
631 int connman_inet_add_network_route(int index, const char *host,
632                                         const char *gateway,
633                                         const char *netmask)
634 {
635         struct ifreq ifr;
636         struct rtentry rt;
637         struct sockaddr_in addr;
638         int sk, err;
639
640         sk = socket(PF_INET, SOCK_DGRAM, 0);
641         if (sk < 0)
642                 return -1;
643
644         memset(&ifr, 0, sizeof(ifr));
645         ifr.ifr_ifindex = index;
646
647         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
648                 close(sk);
649                 return -1;
650         }
651
652         DBG("ifname %s", ifr.ifr_name);
653
654         memset(&rt, 0, sizeof(rt));
655         rt.rt_flags = RTF_UP;
656         if (gateway != NULL)
657                 rt.rt_flags |= RTF_GATEWAY;
658         if (netmask == NULL)
659                 rt.rt_flags |= RTF_HOST;
660
661         memset(&addr, 0, sizeof(addr));
662         addr.sin_family = AF_INET;
663         addr.sin_addr.s_addr = inet_addr(host);
664         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
665
666         memset(&addr, 0, sizeof(addr));
667         addr.sin_family = AF_INET;
668         if (gateway != NULL)
669                 addr.sin_addr.s_addr = inet_addr(gateway);
670         else
671                 addr.sin_addr.s_addr = INADDR_ANY;
672         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
673
674         memset(&addr, 0, sizeof(addr));
675         addr.sin_family = AF_INET;
676         addr.sin_addr.s_addr = INADDR_ANY;
677         if (netmask != NULL)
678                 addr.sin_addr.s_addr = inet_addr(netmask);
679         else
680                 addr.sin_addr.s_addr = INADDR_ANY;
681         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
682
683         rt.rt_dev = ifr.ifr_name;
684
685         err = ioctl(sk, SIOCADDRT, &rt);
686         if (err < 0)
687                 connman_error("Adding host route failed (%s)",
688                                                         strerror(errno));
689
690         close(sk);
691
692         return err;
693 }
694
695 int connman_inet_del_network_route(int index, const char *host)
696 {
697         struct ifreq ifr;
698         struct rtentry rt;
699         struct sockaddr_in addr;
700         int sk, err;
701
702         sk = socket(PF_INET, SOCK_DGRAM, 0);
703         if (sk < 0)
704                 return -1;
705
706         memset(&ifr, 0, sizeof(ifr));
707         ifr.ifr_ifindex = index;
708
709         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
710                 close(sk);
711                 return -1;
712         }
713
714         DBG("ifname %s", ifr.ifr_name);
715
716         memset(&rt, 0, sizeof(rt));
717         rt.rt_flags = RTF_UP | RTF_HOST;
718
719         memset(&addr, 0, sizeof(addr));
720         addr.sin_family = AF_INET;
721         addr.sin_addr.s_addr = inet_addr(host);
722         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
723
724         rt.rt_dev = ifr.ifr_name;
725
726         err = ioctl(sk, SIOCDELRT, &rt);
727         if (err < 0)
728                 connman_error("Deleting host route failed (%s)",
729                                                         strerror(errno));
730
731         close(sk);
732
733         return err;
734 }
735
736 int connman_inet_del_ipv6_network_route(int index, const char *host,
737                                                 unsigned char prefix_len)
738 {
739         struct in6_rtmsg rt;
740         int sk, err;
741
742         DBG("index %d host %s", index, host);
743
744         if (host == NULL)
745                 return -EINVAL;
746
747         memset(&rt, 0, sizeof(rt));
748
749         rt.rtmsg_dst_len = prefix_len;
750
751         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
752         if (err < 0)
753                 goto out;
754
755         rt.rtmsg_flags = RTF_UP | RTF_HOST;
756
757         rt.rtmsg_metric = 1;
758         rt.rtmsg_ifindex = index;
759
760         sk = socket(AF_INET6, SOCK_DGRAM, 0);
761         if (sk < 0) {
762                 err = -1;
763                 goto out;
764         }
765
766         err = ioctl(sk, SIOCDELRT, &rt);
767         close(sk);
768 out:
769         if (err < 0)
770                 connman_error("Del IPv6 host route error");
771
772         return err;
773 }
774
775 int connman_inet_del_ipv6_host_route(int index, const char *host)
776 {
777         return connman_inet_del_ipv6_network_route(index, host, 128);
778 }
779
780 int connman_inet_add_ipv6_network_route(int index, const char *host,
781                                         const char *gateway,
782                                                 unsigned char prefix_len)
783 {
784         struct in6_rtmsg rt;
785         int sk, err;
786
787         DBG("index %d host %s gateway %s", index, host, gateway);
788
789         if (host == NULL)
790                 return -EINVAL;
791
792         memset(&rt, 0, sizeof(rt));
793
794         rt.rtmsg_dst_len = prefix_len;
795
796         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
797         if (err < 0)
798                 goto out;
799
800         rt.rtmsg_flags = RTF_UP | RTF_HOST;
801
802         if (gateway != NULL) {
803                 rt.rtmsg_flags |= RTF_GATEWAY;
804                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
805         }
806
807         rt.rtmsg_metric = 1;
808         rt.rtmsg_ifindex = index;
809
810         sk = socket(AF_INET6, SOCK_DGRAM, 0);
811         if (sk < 0) {
812                 err = -1;
813                 goto out;
814         }
815
816         err = ioctl(sk, SIOCADDRT, &rt);
817         close(sk);
818 out:
819         if (err < 0)
820                 connman_error("Set IPv6 host route error");
821
822         return err;
823 }
824
825 int connman_inet_add_ipv6_host_route(int index, const char *host,
826                                         const char *gateway)
827 {
828         return connman_inet_add_ipv6_network_route(index, host, gateway, 128);
829 }
830
831 int connman_inet_set_ipv6_gateway_address(int index, const char *gateway)
832 {
833         struct in6_rtmsg rt;
834         int sk, err;
835
836         DBG("index %d, gateway %s", index, gateway);
837
838         if (gateway == NULL)
839                 return -EINVAL;
840
841         memset(&rt, 0, sizeof(rt));
842
843         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
844         if (err < 0)
845                 goto out;
846
847         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
848         rt.rtmsg_metric = 1;
849         rt.rtmsg_dst_len = 0;
850         rt.rtmsg_ifindex = index;
851
852         sk = socket(AF_INET6, SOCK_DGRAM, 0);
853         if (sk < 0) {
854                 err = -1;
855                 goto out;
856         }
857
858         err = ioctl(sk, SIOCADDRT, &rt);
859         close(sk);
860 out:
861         if (err < 0)
862                 connman_error("Set default IPv6 gateway error");
863
864         return err;
865 }
866
867 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
868 {
869         struct in6_rtmsg rt;
870         int sk, err;
871
872         DBG("index %d, gateway %s", index, gateway);
873
874         if (gateway == NULL)
875                 return -EINVAL;
876
877         memset(&rt, 0, sizeof(rt));
878
879         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
880         if (err < 0)
881                 goto out;
882
883         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
884         rt.rtmsg_metric = 1;
885         rt.rtmsg_dst_len = 0;
886         rt.rtmsg_ifindex = index;
887
888         sk = socket(AF_INET6, SOCK_DGRAM, 0);
889         if (sk < 0) {
890                 err = -1;
891                 goto out;
892         }
893
894         err = ioctl(sk, SIOCDELRT, &rt);
895         close(sk);
896 out:
897         if (err < 0)
898                 connman_error("Clear default IPv6 gateway error");
899
900         return err;
901 }
902
903 int connman_inet_set_gateway_address(int index, const char *gateway)
904 {
905         struct ifreq ifr;
906         struct rtentry rt;
907         struct sockaddr_in addr;
908         int sk, err;
909
910         sk = socket(PF_INET, SOCK_DGRAM, 0);
911         if (sk < 0)
912                 return -1;
913
914         memset(&ifr, 0, sizeof(ifr));
915         ifr.ifr_ifindex = index;
916
917         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
918                 close(sk);
919                 return -1;
920         }
921
922         DBG("ifname %s", ifr.ifr_name);
923
924         memset(&rt, 0, sizeof(rt));
925         rt.rt_flags = RTF_UP | RTF_GATEWAY;
926
927         memset(&addr, 0, sizeof(addr));
928         addr.sin_family = AF_INET;
929         addr.sin_addr.s_addr = INADDR_ANY;
930         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
931
932         memset(&addr, 0, sizeof(addr));
933         addr.sin_family = AF_INET;
934         addr.sin_addr.s_addr = inet_addr(gateway);
935         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
936
937         memset(&addr, 0, sizeof(addr));
938         addr.sin_family = AF_INET;
939         addr.sin_addr.s_addr = INADDR_ANY;
940         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
941
942         err = ioctl(sk, SIOCADDRT, &rt);
943         if (err < 0)
944                 connman_error("Setting default gateway route failed (%s)",
945                                                         strerror(errno));
946
947         close(sk);
948
949         return err;
950 }
951
952 int connman_inet_set_gateway_interface(int index)
953 {
954         struct ifreq ifr;
955         struct rtentry rt;
956         struct sockaddr_in addr;
957         int sk, err;
958
959         DBG("");
960
961         sk = socket(PF_INET, SOCK_DGRAM, 0);
962         if (sk < 0)
963                 return -1;
964
965         memset(&ifr, 0, sizeof(ifr));
966         ifr.ifr_ifindex = index;
967
968         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
969                 close(sk);
970                 return -1;
971         }
972
973         DBG("ifname %s", ifr.ifr_name);
974
975         memset(&rt, 0, sizeof(rt));
976         rt.rt_flags = RTF_UP;
977
978         memset(&addr, 0, sizeof(addr));
979         addr.sin_family = AF_INET;
980         addr.sin_addr.s_addr = INADDR_ANY;
981
982         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
983         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
984         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
985
986         rt.rt_dev = ifr.ifr_name;
987
988         err = ioctl(sk, SIOCADDRT, &rt);
989         if (err < 0)
990                 connman_error("Setting default interface route failed (%s)",
991                                                         strerror(errno));
992         close(sk);
993
994         return err;
995 }
996
997 int connman_inet_clear_gateway_address(int index, const char *gateway)
998 {
999         struct ifreq ifr;
1000         struct rtentry rt;
1001         struct sockaddr_in addr;
1002         int sk, err;
1003
1004         DBG("");
1005
1006         sk = socket(PF_INET, SOCK_DGRAM, 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 | RTF_GATEWAY;
1022
1023         memset(&addr, 0, sizeof(addr));
1024         addr.sin_family = AF_INET;
1025         addr.sin_addr.s_addr = INADDR_ANY;
1026         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1027
1028         memset(&addr, 0, sizeof(addr));
1029         addr.sin_family = AF_INET;
1030         addr.sin_addr.s_addr = inet_addr(gateway);
1031         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1032
1033         memset(&addr, 0, sizeof(addr));
1034         addr.sin_family = AF_INET;
1035         addr.sin_addr.s_addr = INADDR_ANY;
1036         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1037
1038         err = ioctl(sk, SIOCDELRT, &rt);
1039         if (err < 0)
1040                 connman_error("Removing default gateway route failed (%s)",
1041                                                         strerror(errno));
1042
1043         close(sk);
1044
1045         return err;
1046 }
1047
1048 int connman_inet_clear_gateway_interface(int index)
1049 {
1050         struct ifreq ifr;
1051         struct rtentry rt;
1052         struct sockaddr_in addr;
1053         int sk, err;
1054
1055         DBG("");
1056
1057         sk = socket(PF_INET, SOCK_DGRAM, 0);
1058         if (sk < 0)
1059                 return -1;
1060
1061         memset(&ifr, 0, sizeof(ifr));
1062         ifr.ifr_ifindex = index;
1063
1064         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1065                 close(sk);
1066                 return -1;
1067         }
1068
1069         DBG("ifname %s", ifr.ifr_name);
1070
1071         memset(&rt, 0, sizeof(rt));
1072         rt.rt_flags = RTF_UP;
1073
1074         memset(&addr, 0, sizeof(addr));
1075         addr.sin_family = AF_INET;
1076         addr.sin_addr.s_addr = INADDR_ANY;
1077
1078         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1079         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1080         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1081
1082         rt.rt_dev = ifr.ifr_name;
1083
1084         err = ioctl(sk, SIOCDELRT, &rt);
1085         if (err < 0)
1086                 connman_error("Removing default interface route failed (%s)",
1087                                                         strerror(errno));
1088         close(sk);
1089
1090         return err;
1091 }
1092
1093 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1094 {
1095         struct ifreq ifr;
1096         struct in_addr _host_addr;
1097         in_addr_t host_addr, netmask_addr, if_addr;
1098         struct sockaddr_in *netmask, *addr;
1099         int sk;
1100
1101         DBG("host %s", host);
1102
1103         if (host == NULL)
1104                 return FALSE;
1105
1106         if (inet_aton(host, &_host_addr) == 0)
1107                 return -1;
1108         host_addr = _host_addr.s_addr;
1109
1110         sk = socket(PF_INET, SOCK_DGRAM, 0);
1111         if (sk < 0)
1112                 return FALSE;
1113
1114         memset(&ifr, 0, sizeof(ifr));
1115         ifr.ifr_ifindex = index;
1116
1117         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1118                 close(sk);
1119                 return FALSE;
1120         }
1121
1122         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1123                 close(sk);
1124                 return FALSE;
1125         }
1126
1127         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1128         netmask_addr = netmask->sin_addr.s_addr;
1129
1130         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1131                 close(sk);
1132                 return FALSE;
1133         }
1134         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1135         if_addr = addr->sin_addr.s_addr;
1136
1137         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1138 }
1139
1140 int connman_inet_remove_from_bridge(int index, const char *bridge)
1141 {
1142         struct ifreq ifr;
1143         int sk, err;
1144
1145         if (bridge == NULL)
1146                 return -EINVAL;
1147
1148         sk = socket(AF_INET, SOCK_STREAM, 0);
1149         if (sk < 0)
1150                 return sk;
1151
1152         memset(&ifr, 0, sizeof(ifr));
1153         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1154         ifr.ifr_ifindex = index;
1155
1156         err = ioctl(sk, SIOCBRDELIF, &ifr);
1157
1158         close(sk);
1159
1160         if (err < 0) {
1161                 connman_error("Remove interface from bridge error %s",
1162                                                         strerror(errno));
1163                 return err;
1164         }
1165
1166         return 0;
1167 }
1168
1169 int connman_inet_add_to_bridge(int index, const char *bridge)
1170 {
1171         struct ifreq ifr;
1172         int sk, err;
1173
1174         if (bridge == NULL)
1175                 return -EINVAL;
1176
1177         sk = socket(AF_INET, SOCK_STREAM, 0);
1178         if (sk < 0)
1179                 return sk;
1180
1181         memset(&ifr, 0, sizeof(ifr));
1182         strncpy(ifr.ifr_name, bridge, IFNAMSIZ - 1);
1183         ifr.ifr_ifindex = index;
1184
1185         err = ioctl(sk, SIOCBRADDIF, &ifr);
1186
1187         close(sk);
1188
1189         if (err < 0) {
1190                 connman_error("Add interface to bridge error %s",
1191                                                         strerror(errno));
1192                 return err;
1193         }
1194
1195         return 0;
1196 }
1197
1198 int connman_inet_set_mtu(int index, int mtu)
1199 {
1200         struct ifreq ifr;
1201         int sk, err;
1202
1203         sk = socket(AF_INET, SOCK_DGRAM, 0);
1204         if (sk < 0)
1205                 return sk;
1206
1207         memset(&ifr, 0, sizeof(ifr));
1208         ifr.ifr_ifindex = index;
1209
1210         err = ioctl(sk, SIOCGIFNAME, &ifr);
1211         if (err == 0) {
1212                 ifr.ifr_mtu = mtu;
1213                 err = ioctl(sk, SIOCSIFMTU, &ifr);
1214         }
1215
1216         close(sk);
1217         return err;
1218 }
1219
1220 int connman_inet_setup_tunnel(char *tunnel, int mtu)
1221 {
1222         struct ifreq ifr;
1223         int sk, err, index;
1224         __u32 mask;
1225         __u32 flags;
1226
1227         if (tunnel == NULL)
1228                 return -EINVAL;
1229
1230         sk = socket(AF_INET, SOCK_DGRAM, 0);
1231         if (sk < 0)
1232                 return sk;
1233
1234         index = if_nametoindex(tunnel);
1235
1236         err = connman_inet_set_mtu(index, mtu);
1237         if (err < 0)
1238                 return err;
1239         else if (err)
1240                 goto done;
1241
1242         memset(&ifr, 0, sizeof(ifr));
1243         strncpy(ifr.ifr_name, tunnel, IFNAMSIZ);
1244         err = ioctl(sk, SIOCGIFFLAGS, &ifr);
1245         if (err)
1246                 goto done;
1247
1248         mask = IFF_UP;
1249         flags = IFF_UP;
1250
1251         if ((ifr.ifr_flags ^ flags) & mask) {
1252                 ifr.ifr_flags &= ~mask;
1253                 ifr.ifr_flags |= mask & flags;
1254                 err = ioctl(sk, SIOCSIFFLAGS, &ifr);
1255                 if (err)
1256                         connman_error("SIOCSIFFLAGS failed: %s",
1257                                                         strerror(errno));
1258         }
1259
1260 done:
1261         close(sk);
1262         return err;
1263 }