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