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