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