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