Support for ppp default route setting
[framework/connectivity/connman.git] / src / inet.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/stat.h>
32 #include <sys/ioctl.h>
33 #include <sys/socket.h>
34 #include <arpa/inet.h>
35 #include <net/route.h>
36 #include <net/ethernet.h>
37 #include <linux/if_arp.h>
38 #include <linux/wireless.h>
39
40 #include "connman.h"
41
42 int connman_inet_ifindex(const char *name)
43 {
44         struct ifreq ifr;
45         int sk, err;
46
47         if (name == NULL)
48                 return -1;
49
50         sk = socket(PF_INET, SOCK_DGRAM, 0);
51         if (sk < 0)
52                 return -1;
53
54         memset(&ifr, 0, sizeof(ifr));
55         strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
56
57         err = ioctl(sk, SIOCGIFINDEX, &ifr);
58
59         close(sk);
60
61         if (err < 0)
62                 return -1;
63
64         return ifr.ifr_ifindex;
65 }
66
67 char *connman_inet_ifname(int index)
68 {
69         struct ifreq ifr;
70         int sk, err;
71
72         if (index < 0)
73                 return NULL;
74
75         sk = socket(PF_INET, SOCK_DGRAM, 0);
76         if (sk < 0)
77                 return NULL;
78
79         memset(&ifr, 0, sizeof(ifr));
80         ifr.ifr_ifindex = index;
81
82         err = ioctl(sk, SIOCGIFNAME, &ifr);
83
84         close(sk);
85
86         if (err < 0)
87                 return NULL;
88
89         return strdup(ifr.ifr_name);
90 }
91
92 short int connman_inet_ifflags(int index)
93 {
94         struct ifreq ifr;
95         int sk, err;
96
97         sk = socket(PF_INET, SOCK_DGRAM, 0);
98         if (sk < 0)
99                 return -errno;
100
101         memset(&ifr, 0, sizeof(ifr));
102         ifr.ifr_ifindex = index;
103
104         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
105                 err = -errno;
106                 goto done;
107         }
108
109         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
110                 err = -errno;
111                 goto done;
112         }
113
114         err = ifr.ifr_flags;
115
116 done:
117         close(sk);
118
119         return err;
120 }
121
122 int connman_inet_ifup(int index)
123 {
124         struct ifreq ifr;
125         int sk, err;
126
127         sk = socket(PF_INET, SOCK_DGRAM, 0);
128         if (sk < 0)
129                 return -errno;
130
131         memset(&ifr, 0, sizeof(ifr));
132         ifr.ifr_ifindex = index;
133
134         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
135                 err = -errno;
136                 goto done;
137         }
138
139         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
140                 err = -errno;
141                 goto done;
142         }
143
144         if (ifr.ifr_flags & IFF_UP) {
145                 err = -EALREADY;
146                 goto done;
147         }
148
149         ifr.ifr_flags |= IFF_UP;
150
151         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
152                 err = -errno;
153                 goto done;
154         }
155
156         err = 0;
157
158 done:
159         close(sk);
160
161         return err;
162 }
163
164 int connman_inet_ifdown(int index)
165 {
166         struct ifreq ifr;
167         int sk, err;
168
169         sk = socket(PF_INET, SOCK_DGRAM, 0);
170         if (sk < 0)
171                 return -errno;
172
173         memset(&ifr, 0, sizeof(ifr));
174         ifr.ifr_ifindex = index;
175
176         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
177                 err = -errno;
178                 goto done;
179         }
180
181         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
182                 err = -errno;
183                 goto done;
184         }
185
186         if (!(ifr.ifr_flags & IFF_UP)) {
187                 err = -EALREADY;
188                 goto done;
189         }
190
191         ifr.ifr_flags &= ~IFF_UP;
192
193         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
194                 err = -errno;
195         else
196                 err = 0;
197
198 done:
199         close(sk);
200
201         return err;
202 }
203
204 static unsigned short index2type(int index)
205 {
206         struct ifreq ifr;
207         int sk, err;
208
209         if (index < 0)
210                 return ARPHRD_VOID;
211
212         sk = socket(PF_INET, SOCK_DGRAM, 0);
213         if (sk < 0)
214                 return ARPHRD_VOID;
215
216         memset(&ifr, 0, sizeof(ifr));
217         ifr.ifr_ifindex = index;
218
219         err = ioctl(sk, SIOCGIFNAME, &ifr);
220
221         if (err == 0)
222                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
223
224         close(sk);
225
226         if (err < 0)
227                 return ARPHRD_VOID;
228
229         return ifr.ifr_hwaddr.sa_family;
230 }
231
232 static char *index2addr(int index)
233 {
234         struct ifreq ifr;
235         struct ether_addr eth;
236         char *str;
237         int sk, err;
238
239         if (index < 0)
240                 return NULL;
241
242         sk = socket(PF_INET, SOCK_DGRAM, 0);
243         if (sk < 0)
244                 return NULL;
245
246         memset(&ifr, 0, sizeof(ifr));
247         ifr.ifr_ifindex = index;
248
249         err = ioctl(sk, SIOCGIFNAME, &ifr);
250
251         if (err == 0)
252                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
253
254         close(sk);
255
256         if (err < 0)
257                 return NULL;
258
259         str = malloc(18);
260         if (!str)
261                 return NULL;
262
263         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
264         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
265                                                 eth.ether_addr_octet[0],
266                                                 eth.ether_addr_octet[1],
267                                                 eth.ether_addr_octet[2],
268                                                 eth.ether_addr_octet[3],
269                                                 eth.ether_addr_octet[4],
270                                                 eth.ether_addr_octet[5]);
271
272         return str;
273 }
274
275 static char *index2ident(int index, const char *prefix)
276 {
277         struct ifreq ifr;
278         struct ether_addr eth;
279         char *str;
280         int sk, err, len;
281
282         if (index < 0)
283                 return NULL;
284
285         sk = socket(PF_INET, SOCK_DGRAM, 0);
286         if (sk < 0)
287                 return NULL;
288
289         memset(&ifr, 0, sizeof(ifr));
290         ifr.ifr_ifindex = index;
291
292         err = ioctl(sk, SIOCGIFNAME, &ifr);
293
294         if (err == 0)
295                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
296
297         close(sk);
298
299         if (err < 0)
300                 return NULL;
301
302         len = prefix ? strlen(prefix) + 18 : 18;
303
304         str = malloc(len);
305         if (!str)
306                 return NULL;
307
308         memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
309         snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
310                                                 prefix ? prefix : "",
311                                                 eth.ether_addr_octet[0],
312                                                 eth.ether_addr_octet[1],
313                                                 eth.ether_addr_octet[2],
314                                                 eth.ether_addr_octet[3],
315                                                 eth.ether_addr_octet[4],
316                                                 eth.ether_addr_octet[5]);
317
318         return str;
319 }
320
321 connman_bool_t connman_inet_is_cfg80211(int index)
322 {
323         connman_bool_t result = FALSE;
324         char phy80211_path[PATH_MAX];
325         struct stat st;
326         struct ifreq ifr;
327         int sk;
328
329         sk = socket(PF_INET, SOCK_DGRAM, 0);
330         if (sk < 0)
331                 return FALSE;
332
333         memset(&ifr, 0, sizeof(ifr));
334         ifr.ifr_ifindex = index;
335
336         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
337                 goto done;
338
339         snprintf(phy80211_path, PATH_MAX,
340                                 "/sys/class/net/%s/phy80211", ifr.ifr_name);
341
342         if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
343                 result = TRUE;
344
345 done:
346         close(sk);
347
348         return result;
349 }
350
351 enum connman_device_type __connman_inet_get_device_type(int index)
352 {
353         enum connman_device_type devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
354         unsigned short type = index2type(index);
355         const char *devname;
356         struct ifreq ifr;
357         int sk;
358
359         sk = socket(PF_INET, SOCK_DGRAM, 0);
360         if (sk < 0)
361                 return devtype;
362
363         memset(&ifr, 0, sizeof(ifr));
364         ifr.ifr_ifindex = index;
365
366         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0)
367                 goto done;
368
369         devname = ifr.ifr_name;
370
371         if (type == ARPHRD_ETHER) {
372                 char phy80211_path[PATH_MAX];
373                 char bonding_path[PATH_MAX];
374                 char bridge_path[PATH_MAX];
375                 char wimax_path[PATH_MAX];
376                 struct stat st;
377                 struct iwreq iwr;
378
379                 snprintf(phy80211_path, PATH_MAX,
380                                         "/sys/class/net/%s/phy80211", devname);
381                 snprintf(bonding_path, PATH_MAX,
382                                         "/sys/class/net/%s/bonding", devname);
383                 snprintf(bridge_path, PATH_MAX,
384                                         "/sys/class/net/%s/bridge", devname);
385                 snprintf(wimax_path, PATH_MAX,
386                                         "/sys/class/net/%s/wimax", devname);
387
388                 memset(&iwr, 0, sizeof(iwr));
389                 strncpy(iwr.ifr_ifrn.ifrn_name, devname, IFNAMSIZ);
390
391                 if (g_str_has_prefix(devname, "vmnet") == TRUE)
392                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
393                 else if (g_str_has_prefix(ifr.ifr_name, "vboxnet") == TRUE)
394                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
395                 else if (g_str_has_prefix(devname, "bnep") == TRUE)
396                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
397                 else if (g_str_has_prefix(devname, "wmx") == TRUE)
398                         devtype = CONNMAN_DEVICE_TYPE_WIMAX;
399                 else if (stat(wimax_path, &st) == 0 && (st.st_mode & S_IFDIR))
400                         devtype = CONNMAN_DEVICE_TYPE_WIMAX;
401                 else if (stat(bridge_path, &st) == 0 && (st.st_mode & S_IFDIR))
402                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
403                 else if (stat(bonding_path, &st) == 0 && (st.st_mode & S_IFDIR))
404                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
405                 else if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
406                         devtype = CONNMAN_DEVICE_TYPE_WIFI;
407                 else if (ioctl(sk, SIOCGIWNAME, &iwr) == 0)
408                         devtype = CONNMAN_DEVICE_TYPE_WIFI;
409                 else
410                         devtype = CONNMAN_DEVICE_TYPE_ETHERNET;
411         }
412
413 done:
414         close(sk);
415
416         return devtype;
417 }
418
419 struct connman_device *connman_inet_create_device(int index)
420 {
421         enum connman_device_mode mode = CONNMAN_DEVICE_MODE_UNKNOWN;
422         enum connman_device_type type;
423         struct connman_device *device;
424         char *devname, *ident = NULL;
425         char *addr = NULL, *name = NULL, *node = NULL;
426
427         if (index < 0)
428                 return NULL;
429
430         devname = connman_inet_ifname(index);
431         if (devname == NULL)
432                 return NULL;
433
434         if (__connman_element_device_isfiltered(devname) == TRUE) {
435                 connman_info("Ignoring interface %s (filtered)", devname);
436                 return NULL;
437         }
438
439         __connman_udev_get_devtype(devname);
440
441         type = __connman_inet_get_device_type(index);
442
443         switch (type) {
444         case CONNMAN_DEVICE_TYPE_UNKNOWN:
445                 connman_info("Ignoring interface %s (type unknown)", devname);
446                 g_free(devname);
447                 return NULL;
448         case CONNMAN_DEVICE_TYPE_ETHERNET:
449         case CONNMAN_DEVICE_TYPE_WIFI:
450         case CONNMAN_DEVICE_TYPE_WIMAX:
451                 name = index2ident(index, "");
452                 addr = index2addr(index);
453                 break;
454         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
455         case CONNMAN_DEVICE_TYPE_CELLULAR:
456         case CONNMAN_DEVICE_TYPE_GPS:
457         case CONNMAN_DEVICE_TYPE_VENDOR:
458                 name = strdup(devname);
459                 break;
460         }
461
462         device = connman_device_create(name, type);
463         if (device == NULL)
464                 goto done;
465
466         switch (type) {
467         case CONNMAN_DEVICE_TYPE_UNKNOWN:
468         case CONNMAN_DEVICE_TYPE_VENDOR:
469         case CONNMAN_DEVICE_TYPE_GPS:
470                 mode = CONNMAN_DEVICE_MODE_UNKNOWN;
471                 break;
472         case CONNMAN_DEVICE_TYPE_ETHERNET:
473                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
474                 ident = index2ident(index, NULL);
475                 break;
476         case CONNMAN_DEVICE_TYPE_WIFI:
477         case CONNMAN_DEVICE_TYPE_WIMAX:
478                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
479                 ident = index2ident(index, NULL);
480                 break;
481         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
482                 mode = CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE;
483                 break;
484         case CONNMAN_DEVICE_TYPE_CELLULAR:
485                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
486                 ident = index2ident(index, NULL);
487                 break;
488         }
489
490         connman_device_set_mode(device, mode);
491
492         connman_device_set_index(device, index);
493         connman_device_set_interface(device, devname, node);
494
495         if (ident != NULL) {
496                 connman_device_set_ident(device, ident);
497                 free(ident);
498         }
499
500         connman_device_set_string(device, "Address", addr);
501
502 done:
503         g_free(devname);
504         g_free(node);
505         free(name);
506         free(addr);
507
508         return device;
509 }
510
511 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_vpn(int index, const char *gateway, const char *host)
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 | RTF_GATEWAY;
638
639         memset(&addr, 0, sizeof(addr));
640         addr.sin_family = AF_INET;
641         addr.sin_addr.s_addr = inet_addr(host);
642         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
643
644         memset(&addr, 0, sizeof(addr));
645         addr.sin_family = AF_INET;
646         addr.sin_addr.s_addr = inet_addr(gateway);;
647         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
648
649         memset(&addr, 0, sizeof(addr));
650         addr.sin_family = AF_INET;
651         addr.sin_addr.s_addr = INADDR_ANY;
652         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
653
654         rt.rt_dev = ifr.ifr_name;
655
656         err = ioctl(sk, SIOCADDRT, &rt);
657         if (err < 0)
658                 connman_error("Adding host route failed (%s)",
659                                                         strerror(errno));
660
661         close(sk);
662
663         return err;
664 }
665
666 int connman_inet_add_host_route(int index, const char *host)
667 {
668         struct ifreq ifr;
669         struct rtentry rt;
670         struct sockaddr_in addr;
671         int sk, err;
672
673         sk = socket(PF_INET, SOCK_DGRAM, 0);
674         if (sk < 0)
675                 return -1;
676
677         memset(&ifr, 0, sizeof(ifr));
678         ifr.ifr_ifindex = index;
679
680         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
681                 close(sk);
682                 return -1;
683         }
684
685         DBG("ifname %s", ifr.ifr_name);
686
687         memset(&rt, 0, sizeof(rt));
688         rt.rt_flags = RTF_UP | RTF_HOST;
689
690         memset(&addr, 0, sizeof(addr));
691         addr.sin_family = AF_INET;
692         addr.sin_addr.s_addr = inet_addr(host);
693         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
694
695         memset(&addr, 0, sizeof(addr));
696         addr.sin_family = AF_INET;
697         addr.sin_addr.s_addr = INADDR_ANY;
698         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
699
700         memset(&addr, 0, sizeof(addr));
701         addr.sin_family = AF_INET;
702         addr.sin_addr.s_addr = INADDR_ANY;
703         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
704
705         rt.rt_dev = ifr.ifr_name;
706
707         err = ioctl(sk, SIOCADDRT, &rt);
708         if (err < 0)
709                 connman_error("Adding host route failed (%s)",
710                                                         strerror(errno));
711
712         close(sk);
713
714         return err;
715 }
716
717 int connman_inet_del_host_route(int index, const char *host)
718 {
719         struct ifreq ifr;
720         struct rtentry rt;
721         struct sockaddr_in addr;
722         int sk, err;
723
724         sk = socket(PF_INET, SOCK_DGRAM, 0);
725         if (sk < 0)
726                 return -1;
727
728         memset(&ifr, 0, sizeof(ifr));
729         ifr.ifr_ifindex = index;
730
731         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
732                 close(sk);
733                 return -1;
734         }
735
736         DBG("ifname %s", ifr.ifr_name);
737
738         memset(&rt, 0, sizeof(rt));
739         rt.rt_flags = RTF_UP | RTF_HOST;
740
741         memset(&addr, 0, sizeof(addr));
742         addr.sin_family = AF_INET;
743         addr.sin_addr.s_addr = inet_addr(host);
744         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
745
746         rt.rt_dev = ifr.ifr_name;
747
748         err = ioctl(sk, SIOCDELRT, &rt);
749         if (err < 0)
750                 connman_error("Deleting host route failed (%s)",
751                                                         strerror(errno));
752
753         close(sk);
754
755         return err;
756 }
757
758 int connman_inet_set_gateway_address(int index, const char *gateway)
759 {
760         struct ifreq ifr;
761         struct rtentry rt;
762         struct sockaddr_in addr;
763         int sk, err;
764
765         sk = socket(PF_INET, SOCK_DGRAM, 0);
766         if (sk < 0)
767                 return -1;
768
769         memset(&ifr, 0, sizeof(ifr));
770         ifr.ifr_ifindex = index;
771
772         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
773                 close(sk);
774                 return -1;
775         }
776
777         DBG("ifname %s", ifr.ifr_name);
778
779         memset(&rt, 0, sizeof(rt));
780         rt.rt_flags = RTF_UP | RTF_GATEWAY;
781
782         memset(&addr, 0, sizeof(addr));
783         addr.sin_family = AF_INET;
784         addr.sin_addr.s_addr = INADDR_ANY;
785         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
786
787         memset(&addr, 0, sizeof(addr));
788         addr.sin_family = AF_INET;
789         addr.sin_addr.s_addr = inet_addr(gateway);
790         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
791
792         memset(&addr, 0, sizeof(addr));
793         addr.sin_family = AF_INET;
794         addr.sin_addr.s_addr = INADDR_ANY;
795         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
796
797         err = ioctl(sk, SIOCADDRT, &rt);
798         if (err < 0)
799                 connman_error("Setting default gateway route failed (%s)",
800                                                         strerror(errno));
801
802         close(sk);
803
804         return err;
805 }
806
807 int connman_inet_set_gateway_interface(int index)
808 {
809         struct ifreq ifr;
810         struct rtentry rt;
811         struct sockaddr_in addr;
812         int sk, err;
813
814         DBG("");
815
816         sk = socket(PF_INET, SOCK_DGRAM, 0);
817         if (sk < 0)
818                 return -1;
819
820         memset(&ifr, 0, sizeof(ifr));
821         ifr.ifr_ifindex = index;
822
823         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
824                 close(sk);
825                 return -1;
826         }
827
828         DBG("ifname %s", ifr.ifr_name);
829
830         memset(&rt, 0, sizeof(rt));
831         rt.rt_flags = RTF_UP;
832
833         memset(&addr, 0, sizeof(addr));
834         addr.sin_family = AF_INET;
835         addr.sin_addr.s_addr = INADDR_ANY;
836
837         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
838         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
839         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
840
841         rt.rt_dev = ifr.ifr_name;
842
843         err = ioctl(sk, SIOCADDRT, &rt);
844         if (err < 0)
845                 connman_error("Setting default interface route failed (%s)",
846                                                         strerror(errno));
847         close(sk);
848
849         return err;
850 }
851
852 int connman_inet_clear_gateway_address(int index, const char *gateway)
853 {
854         struct ifreq ifr;
855         struct rtentry rt;
856         struct sockaddr_in addr;
857         int sk, err;
858
859         DBG("");
860
861         sk = socket(PF_INET, SOCK_DGRAM, 0);
862         if (sk < 0)
863                 return -1;
864
865         memset(&ifr, 0, sizeof(ifr));
866         ifr.ifr_ifindex = index;
867
868         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
869                 close(sk);
870                 return -1;
871         }
872
873         DBG("ifname %s", ifr.ifr_name);
874
875         memset(&rt, 0, sizeof(rt));
876         rt.rt_flags = RTF_UP | RTF_GATEWAY;
877
878         memset(&addr, 0, sizeof(addr));
879         addr.sin_family = AF_INET;
880         addr.sin_addr.s_addr = INADDR_ANY;
881         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
882
883         memset(&addr, 0, sizeof(addr));
884         addr.sin_family = AF_INET;
885         addr.sin_addr.s_addr = inet_addr(gateway);
886         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
887
888         memset(&addr, 0, sizeof(addr));
889         addr.sin_family = AF_INET;
890         addr.sin_addr.s_addr = INADDR_ANY;
891         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
892
893         err = ioctl(sk, SIOCDELRT, &rt);
894         if (err < 0)
895                 connman_error("Removing default gateway route failed (%s)",
896                                                         strerror(errno));
897
898         close(sk);
899
900         return err;
901 }
902
903 int connman_inet_clear_gateway_interface(int index)
904 {
905         struct ifreq ifr;
906         struct rtentry rt;
907         struct sockaddr_in addr;
908         int sk, err;
909
910         DBG("");
911
912         sk = socket(PF_INET, SOCK_DGRAM, 0);
913         if (sk < 0)
914                 return -1;
915
916         memset(&ifr, 0, sizeof(ifr));
917         ifr.ifr_ifindex = index;
918
919         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
920                 close(sk);
921                 return -1;
922         }
923
924         DBG("ifname %s", ifr.ifr_name);
925
926         memset(&rt, 0, sizeof(rt));
927         rt.rt_flags = RTF_UP;
928
929         memset(&addr, 0, sizeof(addr));
930         addr.sin_family = AF_INET;
931         addr.sin_addr.s_addr = INADDR_ANY;
932
933         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
934         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
935         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
936
937         rt.rt_dev = ifr.ifr_name;
938
939         err = ioctl(sk, SIOCDELRT, &rt);
940         if (err < 0)
941                 connman_error("Removing default interface route failed (%s)",
942                                                         strerror(errno));
943         close(sk);
944
945         return err;
946 }