No host route needed for nameservers on the same subnet
[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         __connman_udev_get_devtype(devname);
440
441         type = __connman_inet_get_device_type(index);
442
443         switch (type) {
444         case CONNMAN_DEVICE_TYPE_UNKNOWN:
445                 connman_info("Ignoring interface %s (type unknown)", devname);
446                 g_free(devname);
447                 return NULL;
448         case CONNMAN_DEVICE_TYPE_ETHERNET:
449         case CONNMAN_DEVICE_TYPE_WIFI:
450         case CONNMAN_DEVICE_TYPE_WIMAX:
451                 name = index2ident(index, "");
452                 addr = index2addr(index);
453                 break;
454         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
455         case CONNMAN_DEVICE_TYPE_CELLULAR:
456         case CONNMAN_DEVICE_TYPE_GPS:
457         case CONNMAN_DEVICE_TYPE_VENDOR:
458                 name = strdup(devname);
459                 break;
460         }
461
462         device = connman_device_create(name, type);
463         if (device == NULL)
464                 goto done;
465
466         switch (type) {
467         case CONNMAN_DEVICE_TYPE_UNKNOWN:
468         case CONNMAN_DEVICE_TYPE_VENDOR:
469         case CONNMAN_DEVICE_TYPE_GPS:
470                 mode = CONNMAN_DEVICE_MODE_UNKNOWN;
471                 break;
472         case CONNMAN_DEVICE_TYPE_ETHERNET:
473                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
474                 ident = index2ident(index, NULL);
475                 break;
476         case CONNMAN_DEVICE_TYPE_WIFI:
477         case CONNMAN_DEVICE_TYPE_WIMAX:
478                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
479                 ident = index2ident(index, NULL);
480                 break;
481         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
482                 mode = CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE;
483                 break;
484         case CONNMAN_DEVICE_TYPE_CELLULAR:
485                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
486                 ident = index2ident(index, NULL);
487                 break;
488         }
489
490         connman_device_set_mode(device, mode);
491
492         connman_device_set_index(device, index);
493         connman_device_set_interface(device, devname, node);
494
495         if (ident != NULL) {
496                 connman_device_set_ident(device, ident);
497                 free(ident);
498         }
499
500         connman_device_set_string(device, "Address", addr);
501
502 done:
503         g_free(devname);
504         g_free(node);
505         free(name);
506         free(addr);
507
508         return device;
509 }
510
511 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
512 {
513         struct ifreq ifr;
514         struct sockaddr_in addr;
515         int sk, err;
516
517         sk = socket(PF_INET, SOCK_DGRAM, 0);
518         if (sk < 0)
519                 return -1;
520
521         memset(&ifr, 0, sizeof(ifr));
522         ifr.ifr_ifindex = index;
523
524         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
525                 close(sk);
526                 return -1;
527         }
528
529         DBG("ifname %s", ifr.ifr_name);
530
531         if (ipaddress->local == NULL) {
532                 close(sk);
533                 return -1;
534         }
535
536         memset(&addr, 0, sizeof(addr));
537         addr.sin_family = AF_INET;
538         addr.sin_addr.s_addr = inet_addr(ipaddress->local);
539         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
540
541         err = ioctl(sk, SIOCSIFADDR, &ifr);
542
543         if (err < 0)
544                 DBG("address setting failed (%s)", strerror(errno));
545
546         memset(&addr, 0, sizeof(addr));
547         addr.sin_family = AF_INET;
548         addr.sin_addr.s_addr = htonl(~(0xfffffffflu >> ipaddress->prefixlen));
549         memcpy(&ifr.ifr_netmask, &addr, sizeof(ifr.ifr_netmask));
550
551         err = ioctl(sk, SIOCSIFNETMASK, &ifr);
552
553         if (err < 0)
554                 DBG("netmask setting failed (%s)", strerror(errno));
555
556         memset(&addr, 0, sizeof(addr));
557         addr.sin_family = AF_INET;
558
559         if (ipaddress->broadcast != NULL)
560                 addr.sin_addr.s_addr = inet_addr(ipaddress->broadcast);
561         else
562                 addr.sin_addr.s_addr = inet_addr(ipaddress->local) |
563                                 htonl(0xfffffffflu >> ipaddress->prefixlen);
564
565         memcpy(&ifr.ifr_broadaddr, &addr, sizeof(ifr.ifr_broadaddr));
566
567         err = ioctl(sk, SIOCSIFBRDADDR, &ifr);
568
569         if (err < 0)
570                 DBG("broadcast setting failed (%s)", strerror(errno));
571
572         close(sk);
573
574         return 0;
575 }
576
577 int connman_inet_clear_address(int index)
578 {
579         struct ifreq ifr;
580         struct sockaddr_in addr;
581         int sk, err;
582
583         sk = socket(PF_INET, SOCK_DGRAM, 0);
584         if (sk < 0)
585                 return -1;
586
587         memset(&ifr, 0, sizeof(ifr));
588         ifr.ifr_ifindex = index;
589
590         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
591                 close(sk);
592                 return -1;
593         }
594
595         DBG("ifname %s", ifr.ifr_name);
596
597         memset(&addr, 0, sizeof(addr));
598         addr.sin_family = AF_INET;
599         addr.sin_addr.s_addr = INADDR_ANY;
600         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
601
602         //err = ioctl(sk, SIOCDIFADDR, &ifr);
603         err = ioctl(sk, SIOCSIFADDR, &ifr);
604
605         close(sk);
606
607         if (err < 0 && errno != EADDRNOTAVAIL) {
608                 DBG("address removal failed (%s)", strerror(errno));
609                 return -1;
610         }
611
612         return 0;
613 }
614
615 int connman_inet_add_host_route(int index, const char *host, const char *gateway)
616 {
617         struct ifreq ifr;
618         struct rtentry rt;
619         struct sockaddr_in addr;
620         int sk, err;
621
622         sk = socket(PF_INET, SOCK_DGRAM, 0);
623         if (sk < 0)
624                 return -1;
625
626         memset(&ifr, 0, sizeof(ifr));
627         ifr.ifr_ifindex = index;
628
629         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
630                 close(sk);
631                 return -1;
632         }
633
634         DBG("ifname %s", ifr.ifr_name);
635
636         memset(&rt, 0, sizeof(rt));
637         rt.rt_flags = RTF_UP | RTF_HOST;
638         if (gateway != NULL)
639                 rt.rt_flags |= RTF_GATEWAY;
640
641         memset(&addr, 0, sizeof(addr));
642         addr.sin_family = AF_INET;
643         addr.sin_addr.s_addr = inet_addr(host);
644         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
645
646         memset(&addr, 0, sizeof(addr));
647         addr.sin_family = AF_INET;
648         if (gateway != NULL)
649                 addr.sin_addr.s_addr = inet_addr(gateway);
650         else
651                 addr.sin_addr.s_addr = INADDR_ANY;
652         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
653
654         memset(&addr, 0, sizeof(addr));
655         addr.sin_family = AF_INET;
656         addr.sin_addr.s_addr = INADDR_ANY;
657         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
658
659         rt.rt_dev = ifr.ifr_name;
660
661         err = ioctl(sk, SIOCADDRT, &rt);
662         if (err < 0)
663                 connman_error("Adding host route failed (%s)",
664                                                         strerror(errno));
665
666         close(sk);
667
668         return err;
669 }
670
671 int connman_inet_del_host_route(int index, const char *host)
672 {
673         struct ifreq ifr;
674         struct rtentry rt;
675         struct sockaddr_in addr;
676         int sk, err;
677
678         sk = socket(PF_INET, SOCK_DGRAM, 0);
679         if (sk < 0)
680                 return -1;
681
682         memset(&ifr, 0, sizeof(ifr));
683         ifr.ifr_ifindex = index;
684
685         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
686                 close(sk);
687                 return -1;
688         }
689
690         DBG("ifname %s", ifr.ifr_name);
691
692         memset(&rt, 0, sizeof(rt));
693         rt.rt_flags = RTF_UP | RTF_HOST;
694
695         memset(&addr, 0, sizeof(addr));
696         addr.sin_family = AF_INET;
697         addr.sin_addr.s_addr = inet_addr(host);
698         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
699
700         rt.rt_dev = ifr.ifr_name;
701
702         err = ioctl(sk, SIOCDELRT, &rt);
703         if (err < 0)
704                 connman_error("Deleting host route failed (%s)",
705                                                         strerror(errno));
706
707         close(sk);
708
709         return err;
710 }
711
712 int connman_inet_set_gateway_address(int index, const char *gateway)
713 {
714         struct ifreq ifr;
715         struct rtentry rt;
716         struct sockaddr_in addr;
717         int sk, err;
718
719         sk = socket(PF_INET, SOCK_DGRAM, 0);
720         if (sk < 0)
721                 return -1;
722
723         memset(&ifr, 0, sizeof(ifr));
724         ifr.ifr_ifindex = index;
725
726         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
727                 close(sk);
728                 return -1;
729         }
730
731         DBG("ifname %s", ifr.ifr_name);
732
733         memset(&rt, 0, sizeof(rt));
734         rt.rt_flags = RTF_UP | RTF_GATEWAY;
735
736         memset(&addr, 0, sizeof(addr));
737         addr.sin_family = AF_INET;
738         addr.sin_addr.s_addr = INADDR_ANY;
739         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
740
741         memset(&addr, 0, sizeof(addr));
742         addr.sin_family = AF_INET;
743         addr.sin_addr.s_addr = inet_addr(gateway);
744         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
745
746         memset(&addr, 0, sizeof(addr));
747         addr.sin_family = AF_INET;
748         addr.sin_addr.s_addr = INADDR_ANY;
749         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
750
751         err = ioctl(sk, SIOCADDRT, &rt);
752         if (err < 0)
753                 connman_error("Setting default gateway route failed (%s)",
754                                                         strerror(errno));
755
756         close(sk);
757
758         return err;
759 }
760
761 int connman_inet_set_gateway_interface(int index)
762 {
763         struct ifreq ifr;
764         struct rtentry rt;
765         struct sockaddr_in addr;
766         int sk, err;
767
768         DBG("");
769
770         sk = socket(PF_INET, SOCK_DGRAM, 0);
771         if (sk < 0)
772                 return -1;
773
774         memset(&ifr, 0, sizeof(ifr));
775         ifr.ifr_ifindex = index;
776
777         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
778                 close(sk);
779                 return -1;
780         }
781
782         DBG("ifname %s", ifr.ifr_name);
783
784         memset(&rt, 0, sizeof(rt));
785         rt.rt_flags = RTF_UP;
786
787         memset(&addr, 0, sizeof(addr));
788         addr.sin_family = AF_INET;
789         addr.sin_addr.s_addr = INADDR_ANY;
790
791         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
792         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
793         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
794
795         rt.rt_dev = ifr.ifr_name;
796
797         err = ioctl(sk, SIOCADDRT, &rt);
798         if (err < 0)
799                 connman_error("Setting default interface route failed (%s)",
800                                                         strerror(errno));
801         close(sk);
802
803         return err;
804 }
805
806 int connman_inet_clear_gateway_address(int index, const char *gateway)
807 {
808         struct ifreq ifr;
809         struct rtentry rt;
810         struct sockaddr_in addr;
811         int sk, err;
812
813         DBG("");
814
815         sk = socket(PF_INET, SOCK_DGRAM, 0);
816         if (sk < 0)
817                 return -1;
818
819         memset(&ifr, 0, sizeof(ifr));
820         ifr.ifr_ifindex = index;
821
822         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
823                 close(sk);
824                 return -1;
825         }
826
827         DBG("ifname %s", ifr.ifr_name);
828
829         memset(&rt, 0, sizeof(rt));
830         rt.rt_flags = RTF_UP | RTF_GATEWAY;
831
832         memset(&addr, 0, sizeof(addr));
833         addr.sin_family = AF_INET;
834         addr.sin_addr.s_addr = INADDR_ANY;
835         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
836
837         memset(&addr, 0, sizeof(addr));
838         addr.sin_family = AF_INET;
839         addr.sin_addr.s_addr = inet_addr(gateway);
840         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
841
842         memset(&addr, 0, sizeof(addr));
843         addr.sin_family = AF_INET;
844         addr.sin_addr.s_addr = INADDR_ANY;
845         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
846
847         err = ioctl(sk, SIOCDELRT, &rt);
848         if (err < 0)
849                 connman_error("Removing default gateway route failed (%s)",
850                                                         strerror(errno));
851
852         close(sk);
853
854         return err;
855 }
856
857 int connman_inet_clear_gateway_interface(int index)
858 {
859         struct ifreq ifr;
860         struct rtentry rt;
861         struct sockaddr_in addr;
862         int sk, err;
863
864         DBG("");
865
866         sk = socket(PF_INET, SOCK_DGRAM, 0);
867         if (sk < 0)
868                 return -1;
869
870         memset(&ifr, 0, sizeof(ifr));
871         ifr.ifr_ifindex = index;
872
873         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
874                 close(sk);
875                 return -1;
876         }
877
878         DBG("ifname %s", ifr.ifr_name);
879
880         memset(&rt, 0, sizeof(rt));
881         rt.rt_flags = RTF_UP;
882
883         memset(&addr, 0, sizeof(addr));
884         addr.sin_family = AF_INET;
885         addr.sin_addr.s_addr = INADDR_ANY;
886
887         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
888         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
889         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
890
891         rt.rt_dev = ifr.ifr_name;
892
893         err = ioctl(sk, SIOCDELRT, &rt);
894         if (err < 0)
895                 connman_error("Removing default interface route failed (%s)",
896                                                         strerror(errno));
897         close(sk);
898
899         return err;
900 }
901
902 connman_bool_t connman_inet_compare_subnet(int index, const char *host)
903 {
904         struct ifreq ifr;
905         struct in_addr _host_addr;
906         in_addr_t host_addr, netmask_addr, if_addr;
907         struct sockaddr_in *netmask, *addr;
908         int sk;
909
910         DBG("host %s", host);
911
912         if (host == NULL)
913                 return FALSE;
914
915         if (inet_aton(host, &_host_addr) == 0)
916                 return -1;
917         host_addr = _host_addr.s_addr;
918
919         sk = socket(PF_INET, SOCK_DGRAM, 0);
920         if (sk < 0)
921                 return FALSE;
922
923         memset(&ifr, 0, sizeof(ifr));
924         ifr.ifr_ifindex = index;
925
926         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
927                 close(sk);
928                 return FALSE;
929         }
930
931         if (ioctl(sk, SIOCGIFNETMASK, &ifr) < 0) {
932                 close(sk);
933                 return FALSE;
934         }
935
936         netmask = (struct sockaddr_in *)&ifr.ifr_netmask;
937         netmask_addr = netmask->sin_addr.s_addr;
938
939         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
940                 close(sk);
941                 return FALSE;
942         }
943         addr = (struct sockaddr_in *)&ifr.ifr_addr;
944         if_addr = addr->sin_addr.s_addr;
945
946         return ((if_addr & netmask_addr) == (host_addr & netmask_addr));
947 }