Remove dependency on udev
[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 <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         type = __connman_inet_get_device_type(index);
440
441         switch (type) {
442         case CONNMAN_DEVICE_TYPE_UNKNOWN:
443                 connman_info("Ignoring interface %s (type unknown)", devname);
444                 g_free(devname);
445                 return NULL;
446         case CONNMAN_DEVICE_TYPE_ETHERNET:
447         case CONNMAN_DEVICE_TYPE_WIFI:
448         case CONNMAN_DEVICE_TYPE_WIMAX:
449                 name = index2ident(index, "");
450                 addr = index2addr(index);
451                 break;
452         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
453         case CONNMAN_DEVICE_TYPE_CELLULAR:
454         case CONNMAN_DEVICE_TYPE_GPS:
455         case CONNMAN_DEVICE_TYPE_VENDOR:
456                 name = strdup(devname);
457                 break;
458         }
459
460         device = connman_device_create(name, type);
461         if (device == NULL)
462                 goto done;
463
464         switch (type) {
465         case CONNMAN_DEVICE_TYPE_UNKNOWN:
466         case CONNMAN_DEVICE_TYPE_VENDOR:
467         case CONNMAN_DEVICE_TYPE_GPS:
468                 mode = CONNMAN_DEVICE_MODE_UNKNOWN;
469                 break;
470         case CONNMAN_DEVICE_TYPE_ETHERNET:
471                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
472                 ident = index2ident(index, NULL);
473                 break;
474         case CONNMAN_DEVICE_TYPE_WIFI:
475         case CONNMAN_DEVICE_TYPE_WIMAX:
476                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
477                 ident = index2ident(index, NULL);
478                 break;
479         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
480                 mode = CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE;
481                 break;
482         case CONNMAN_DEVICE_TYPE_CELLULAR:
483                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
484                 ident = index2ident(index, NULL);
485                 break;
486         }
487
488         connman_device_set_mode(device, mode);
489
490         connman_device_set_index(device, index);
491         connman_device_set_interface(device, devname, node);
492
493         if (ident != NULL) {
494                 connman_device_set_ident(device, ident);
495                 free(ident);
496         }
497
498         connman_device_set_string(device, "Address", addr);
499
500 done:
501         g_free(devname);
502         g_free(node);
503         free(name);
504         free(addr);
505
506         return device;
507 }
508
509 struct in6_ifreq {
510         struct in6_addr ifr6_addr;
511         __u32 ifr6_prefixlen;
512         unsigned int ifr6_ifindex;
513 };
514
515 int connman_inet_set_ipv6_address(int index,
516                 struct connman_ipaddress *ipaddress)
517 {
518         int sk, err;
519         struct in6_ifreq ifr6;
520
521         DBG("index %d ipaddress->local %s", index, ipaddress->local);
522
523         if (ipaddress->local == NULL)
524                 return 0;
525
526         sk = socket(PF_INET6, SOCK_DGRAM, 0);
527         if (sk < 0) {
528                 err = -1;
529                 goto out;
530         }
531
532         memset(&ifr6, 0, sizeof(ifr6));
533
534         err = inet_pton(AF_INET6, ipaddress->local, &ifr6.ifr6_addr);
535         if (err < 0)
536                 goto out;
537
538         ifr6.ifr6_ifindex = index;
539         ifr6.ifr6_prefixlen = ipaddress->prefixlen;
540
541         err = ioctl(sk, SIOCSIFADDR, &ifr6);
542         close(sk);
543 out:
544         if (err < 0)
545                 connman_error("Set IPv6 address error");
546
547         return err;
548 }
549
550 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
551 {
552         struct ifreq ifr;
553         struct sockaddr_in addr;
554         int sk, err;
555
556         sk = socket(PF_INET, SOCK_DGRAM, 0);
557         if (sk < 0)
558                 return -1;
559
560         memset(&ifr, 0, sizeof(ifr));
561         ifr.ifr_ifindex = index;
562
563         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
564                 close(sk);
565                 return -1;
566         }
567
568         DBG("ifname %s", ifr.ifr_name);
569
570         if (ipaddress->local == NULL) {
571                 close(sk);
572                 return -1;
573         }
574
575         memset(&addr, 0, sizeof(addr));
576         addr.sin_family = AF_INET;
577         addr.sin_addr.s_addr = inet_addr(ipaddress->local);
578         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
579
580         err = ioctl(sk, SIOCSIFADDR, &ifr);
581
582         if (err < 0)
583                 DBG("address setting failed (%s)", strerror(errno));
584
585         memset(&addr, 0, sizeof(addr));
586         addr.sin_family = AF_INET;
587         addr.sin_addr.s_addr = htonl(~(0xfffffffflu >> ipaddress->prefixlen));
588         memcpy(&ifr.ifr_netmask, &addr, sizeof(ifr.ifr_netmask));
589
590         err = ioctl(sk, SIOCSIFNETMASK, &ifr);
591
592         if (err < 0)
593                 DBG("netmask setting failed (%s)", strerror(errno));
594
595         memset(&addr, 0, sizeof(addr));
596         addr.sin_family = AF_INET;
597
598         if (ipaddress->broadcast != NULL)
599                 addr.sin_addr.s_addr = inet_addr(ipaddress->broadcast);
600         else
601                 addr.sin_addr.s_addr = inet_addr(ipaddress->local) |
602                                 htonl(0xfffffffflu >> ipaddress->prefixlen);
603
604         memcpy(&ifr.ifr_broadaddr, &addr, sizeof(ifr.ifr_broadaddr));
605
606         err = ioctl(sk, SIOCSIFBRDADDR, &ifr);
607
608         if (err < 0)
609                 DBG("broadcast setting failed (%s)", strerror(errno));
610
611         close(sk);
612
613         return 0;
614 }
615
616 int connman_inet_clear_ipv6_address(int index, const char *address,
617                                                         int prefix_len)
618 {
619         struct in6_ifreq ifr6;
620         int sk, err;
621
622         DBG("index %d address %s prefix_len %d", index, address, prefix_len);
623
624         memset(&ifr6, 0, sizeof(ifr6));
625
626         err = inet_pton(AF_INET6, address, &ifr6.ifr6_addr);
627         if (err < 0)
628                 goto out;
629
630         ifr6.ifr6_ifindex = index;
631         ifr6.ifr6_prefixlen = prefix_len;
632
633         sk = socket(PF_INET6, SOCK_DGRAM, 0);
634         if (sk < 0) {
635                 err = -1;
636                 goto out;
637         }
638
639         err = ioctl(sk, SIOCDIFADDR, &ifr6);
640         close(sk);
641 out:
642         if (err < 0)
643                 connman_error("Clear IPv6 address error");
644
645         return err;
646 }
647
648 int connman_inet_clear_address(int index)
649 {
650
651
652         struct ifreq ifr;
653         struct sockaddr_in addr;
654         int sk, err;
655
656         sk = socket(PF_INET, SOCK_DGRAM, 0);
657         if (sk < 0)
658                 return -1;
659
660         memset(&ifr, 0, sizeof(ifr));
661         ifr.ifr_ifindex = index;
662
663         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
664                 close(sk);
665                 return -1;
666         }
667
668         DBG("ifname %s", ifr.ifr_name);
669
670         memset(&addr, 0, sizeof(addr));
671         addr.sin_family = AF_INET;
672         addr.sin_addr.s_addr = INADDR_ANY;
673         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
674
675         //err = ioctl(sk, SIOCDIFADDR, &ifr);
676         err = ioctl(sk, SIOCSIFADDR, &ifr);
677
678         close(sk);
679
680         if (err < 0 && errno != EADDRNOTAVAIL) {
681                 DBG("address removal failed (%s)", strerror(errno));
682                 return -1;
683         }
684
685         return 0;
686 }
687
688 int connman_inet_add_host_route(int index, const char *host, const char *gateway)
689 {
690         struct ifreq ifr;
691         struct rtentry rt;
692         struct sockaddr_in addr;
693         int sk, err;
694
695         sk = socket(PF_INET, SOCK_DGRAM, 0);
696         if (sk < 0)
697                 return -1;
698
699         memset(&ifr, 0, sizeof(ifr));
700         ifr.ifr_ifindex = index;
701
702         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
703                 close(sk);
704                 return -1;
705         }
706
707         DBG("ifname %s", ifr.ifr_name);
708
709         memset(&rt, 0, sizeof(rt));
710         rt.rt_flags = RTF_UP | RTF_HOST;
711         if (gateway != NULL)
712                 rt.rt_flags |= RTF_GATEWAY;
713
714         memset(&addr, 0, sizeof(addr));
715         addr.sin_family = AF_INET;
716         addr.sin_addr.s_addr = inet_addr(host);
717         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
718
719         memset(&addr, 0, sizeof(addr));
720         addr.sin_family = AF_INET;
721         if (gateway != NULL)
722                 addr.sin_addr.s_addr = inet_addr(gateway);
723         else
724                 addr.sin_addr.s_addr = INADDR_ANY;
725         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
726
727         memset(&addr, 0, sizeof(addr));
728         addr.sin_family = AF_INET;
729         addr.sin_addr.s_addr = INADDR_ANY;
730         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
731
732         rt.rt_dev = ifr.ifr_name;
733
734         err = ioctl(sk, SIOCADDRT, &rt);
735         if (err < 0)
736                 connman_error("Adding host route failed (%s)",
737                                                         strerror(errno));
738
739         close(sk);
740
741         return err;
742 }
743
744 int connman_inet_del_host_route(int index, const char *host)
745 {
746         struct ifreq ifr;
747         struct rtentry rt;
748         struct sockaddr_in addr;
749         int sk, err;
750
751         sk = socket(PF_INET, SOCK_DGRAM, 0);
752         if (sk < 0)
753                 return -1;
754
755         memset(&ifr, 0, sizeof(ifr));
756         ifr.ifr_ifindex = index;
757
758         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
759                 close(sk);
760                 return -1;
761         }
762
763         DBG("ifname %s", ifr.ifr_name);
764
765         memset(&rt, 0, sizeof(rt));
766         rt.rt_flags = RTF_UP | RTF_HOST;
767
768         memset(&addr, 0, sizeof(addr));
769         addr.sin_family = AF_INET;
770         addr.sin_addr.s_addr = inet_addr(host);
771         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
772
773         rt.rt_dev = ifr.ifr_name;
774
775         err = ioctl(sk, SIOCDELRT, &rt);
776         if (err < 0)
777                 connman_error("Deleting host route failed (%s)",
778                                                         strerror(errno));
779
780         close(sk);
781
782         return err;
783 }
784
785 int connman_inet_del_ipv6_host_route(int index, const char *host)
786 {
787         struct in6_rtmsg rt;
788         int sk, err;
789
790         DBG("index %d host %s", index, host);
791
792         if (host == NULL)
793                 return -EINVAL;
794
795         memset(&rt, 0, sizeof(rt));
796
797         rt.rtmsg_dst_len = 128;
798
799         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
800         if (err < 0)
801                 goto out;
802
803         rt.rtmsg_flags = RTF_UP | RTF_HOST;
804
805         rt.rtmsg_metric = 1;
806         rt.rtmsg_ifindex = index;
807
808         sk = socket(AF_INET6, SOCK_DGRAM, 0);
809         if (sk < 0) {
810                 err = -1;
811                 goto out;
812         }
813
814         err = ioctl(sk, SIOCDELRT, &rt);
815         close(sk);
816 out:
817         if (err < 0)
818                 connman_error("Del IPv6 host route error");
819
820         return err;
821 }
822
823 int connman_inet_add_ipv6_host_route(int index, const char *host,
824                                                 const char *gateway)
825 {
826         struct in6_rtmsg rt;
827         int sk, err;
828
829         DBG("index %d host %s gateway %s", index, host, gateway);
830
831         if (host == NULL)
832                 return -EINVAL;
833
834         memset(&rt, 0, sizeof(rt));
835
836         rt.rtmsg_dst_len = 128;
837
838         err = inet_pton(AF_INET6, host, &rt.rtmsg_dst);
839         if (err < 0)
840                 goto out;
841
842         rt.rtmsg_flags = RTF_UP | RTF_HOST;
843
844         if (gateway != NULL) {
845                 rt.rtmsg_flags |= RTF_GATEWAY;
846                 inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
847         }
848
849         rt.rtmsg_metric = 1;
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 IPv6 host route error");
863
864         return err;
865 }
866
867 int connman_inet_set_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, SIOCADDRT, &rt);
895         close(sk);
896 out:
897         if (err < 0)
898                 connman_error("Set default IPv6 gateway error");
899
900         return err;
901 }
902
903 int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
904 {
905         struct in6_rtmsg rt;
906         int sk, err;
907
908         DBG("index %d, gateway %s", index, gateway);
909
910         if (gateway == NULL)
911                 return -EINVAL;
912
913         memset(&rt, 0, sizeof(rt));
914
915         err = inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway);
916         if (err < 0)
917                 goto out;
918
919         rt.rtmsg_flags = RTF_UP | RTF_GATEWAY;
920         rt.rtmsg_metric = 1;
921         rt.rtmsg_dst_len = 0;
922         rt.rtmsg_ifindex = index;
923
924         sk = socket(AF_INET6, SOCK_DGRAM, 0);
925         if (sk < 0) {
926                 err = -1;
927                 goto out;
928         }
929
930         err = ioctl(sk, SIOCDELRT, &rt);
931         close(sk);
932 out:
933         if (err < 0)
934                 connman_error("Clear default IPv6 gateway error");
935
936         return err;
937 }
938
939 int connman_inet_set_gateway_address(int index, const char *gateway)
940 {
941         struct ifreq ifr;
942         struct rtentry rt;
943         struct sockaddr_in addr;
944         int sk, err;
945
946         sk = socket(PF_INET, SOCK_DGRAM, 0);
947         if (sk < 0)
948                 return -1;
949
950         memset(&ifr, 0, sizeof(ifr));
951         ifr.ifr_ifindex = index;
952
953         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
954                 close(sk);
955                 return -1;
956         }
957
958         DBG("ifname %s", ifr.ifr_name);
959
960         memset(&rt, 0, sizeof(rt));
961         rt.rt_flags = RTF_UP | RTF_GATEWAY;
962
963         memset(&addr, 0, sizeof(addr));
964         addr.sin_family = AF_INET;
965         addr.sin_addr.s_addr = INADDR_ANY;
966         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
967
968         memset(&addr, 0, sizeof(addr));
969         addr.sin_family = AF_INET;
970         addr.sin_addr.s_addr = inet_addr(gateway);
971         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
972
973         memset(&addr, 0, sizeof(addr));
974         addr.sin_family = AF_INET;
975         addr.sin_addr.s_addr = INADDR_ANY;
976         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
977
978         err = ioctl(sk, SIOCADDRT, &rt);
979         if (err < 0)
980                 connman_error("Setting default gateway route failed (%s)",
981                                                         strerror(errno));
982
983         close(sk);
984
985         return err;
986 }
987
988 int connman_inet_set_gateway_interface(int index)
989 {
990         struct ifreq ifr;
991         struct rtentry rt;
992         struct sockaddr_in addr;
993         int sk, err;
994
995         DBG("");
996
997         sk = socket(PF_INET, SOCK_DGRAM, 0);
998         if (sk < 0)
999                 return -1;
1000
1001         memset(&ifr, 0, sizeof(ifr));
1002         ifr.ifr_ifindex = index;
1003
1004         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1005                 close(sk);
1006                 return -1;
1007         }
1008
1009         DBG("ifname %s", ifr.ifr_name);
1010
1011         memset(&rt, 0, sizeof(rt));
1012         rt.rt_flags = RTF_UP;
1013
1014         memset(&addr, 0, sizeof(addr));
1015         addr.sin_family = AF_INET;
1016         addr.sin_addr.s_addr = INADDR_ANY;
1017
1018         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1019         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1020         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1021
1022         rt.rt_dev = ifr.ifr_name;
1023
1024         err = ioctl(sk, SIOCADDRT, &rt);
1025         if (err < 0)
1026                 connman_error("Setting default interface route failed (%s)",
1027                                                         strerror(errno));
1028         close(sk);
1029
1030         return err;
1031 }
1032
1033 int connman_inet_clear_gateway_address(int index, const char *gateway)
1034 {
1035         struct ifreq ifr;
1036         struct rtentry rt;
1037         struct sockaddr_in addr;
1038         int sk, err;
1039
1040         DBG("");
1041
1042         sk = socket(PF_INET, SOCK_DGRAM, 0);
1043         if (sk < 0)
1044                 return -1;
1045
1046         memset(&ifr, 0, sizeof(ifr));
1047         ifr.ifr_ifindex = index;
1048
1049         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1050                 close(sk);
1051                 return -1;
1052         }
1053
1054         DBG("ifname %s", ifr.ifr_name);
1055
1056         memset(&rt, 0, sizeof(rt));
1057         rt.rt_flags = RTF_UP | RTF_GATEWAY;
1058
1059         memset(&addr, 0, sizeof(addr));
1060         addr.sin_family = AF_INET;
1061         addr.sin_addr.s_addr = INADDR_ANY;
1062         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1063
1064         memset(&addr, 0, sizeof(addr));
1065         addr.sin_family = AF_INET;
1066         addr.sin_addr.s_addr = inet_addr(gateway);
1067         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1068
1069         memset(&addr, 0, sizeof(addr));
1070         addr.sin_family = AF_INET;
1071         addr.sin_addr.s_addr = INADDR_ANY;
1072         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1073
1074         err = ioctl(sk, SIOCDELRT, &rt);
1075         if (err < 0)
1076                 connman_error("Removing default gateway route failed (%s)",
1077                                                         strerror(errno));
1078
1079         close(sk);
1080
1081         return err;
1082 }
1083
1084 int connman_inet_clear_gateway_interface(int index)
1085 {
1086         struct ifreq ifr;
1087         struct rtentry rt;
1088         struct sockaddr_in addr;
1089         int sk, err;
1090
1091         DBG("");
1092
1093         sk = socket(PF_INET, SOCK_DGRAM, 0);
1094         if (sk < 0)
1095                 return -1;
1096
1097         memset(&ifr, 0, sizeof(ifr));
1098         ifr.ifr_ifindex = index;
1099
1100         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1101                 close(sk);
1102                 return -1;
1103         }
1104
1105         DBG("ifname %s", ifr.ifr_name);
1106
1107         memset(&rt, 0, sizeof(rt));
1108         rt.rt_flags = RTF_UP;
1109
1110         memset(&addr, 0, sizeof(addr));
1111         addr.sin_family = AF_INET;
1112         addr.sin_addr.s_addr = INADDR_ANY;
1113
1114         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1115         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1116         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1117
1118         rt.rt_dev = ifr.ifr_name;
1119
1120         err = ioctl(sk, SIOCDELRT, &rt);
1121         if (err < 0)
1122                 connman_error("Removing default interface route failed (%s)",
1123                                                         strerror(errno));
1124         close(sk);
1125
1126         return err;
1127 }
1128
1129 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
1130 {
1131         struct ifreq ifr;
1132         struct in_addr _host_addr;
1133         in_addr_t host_addr, netmask_addr, if_addr;
1134         struct sockaddr_in *netmask, *addr;
1135         int sk;
1136
1137         DBG("host %s", host);
1138
1139         if (host == NULL)
1140                 return FALSE;
1141
1142         if (inet_aton(host, &_host_addr) == 0)
1143                 return -1;
1144         host_addr = _host_addr.s_addr;
1145
1146         sk = socket(PF_INET, SOCK_DGRAM, 0);
1147         if (sk < 0)
1148                 return FALSE;
1149
1150         memset(&ifr, 0, sizeof(ifr));
1151         ifr.ifr_ifindex = index;
1152
1153         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
1154                 close(sk);
1155                 return FALSE;
1156         }
1157
1158         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
1159                 close(sk);
1160                 return FALSE;
1161         }
1162
1163         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
1164         netmask_addr = netmask->sin_addr.s_addr;
1165
1166         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
1167                 close(sk);
1168                 return FALSE;
1169         }
1170         addr = (struct sockaddr_in *)&ifr.ifr_addr;
1171         if_addr = addr->sin_addr.s_addr;
1172
1173         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
1174 }