Check for ipaddress local and broadcast pointers
[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                 char *devnode;
379
380                 snprintf(phy80211_path, PATH_MAX,
381                                         "/sys/class/net/%s/phy80211", devname);
382                 snprintf(bonding_path, PATH_MAX,
383                                         "/sys/class/net/%s/bonding", devname);
384                 snprintf(bridge_path, PATH_MAX,
385                                         "/sys/class/net/%s/bridge", devname);
386                 snprintf(wimax_path, PATH_MAX,
387                                         "/sys/class/net/%s/wimax", devname);
388
389                 memset(&iwr, 0, sizeof(iwr));
390                 strncpy(iwr.ifr_ifrn.ifrn_name, devname, IFNAMSIZ);
391
392                 devnode = __connman_udev_get_mbm_devnode(devname);
393                 if (devnode != NULL) {
394                         devtype = CONNMAN_DEVICE_TYPE_MBM;
395                         g_free(devnode);
396                         goto done;
397                 }
398
399                 if (g_str_has_prefix(devname, "vmnet") == TRUE)
400                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
401                 else if (g_str_has_prefix(ifr.ifr_name, "vboxnet") == TRUE)
402                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
403                 else if (g_str_has_prefix(devname, "bnep") == TRUE)
404                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
405                 else if (g_str_has_prefix(devname, "wmx") == TRUE)
406                         devtype = CONNMAN_DEVICE_TYPE_WIMAX;
407                 else if (stat(wimax_path, &st) == 0 && (st.st_mode & S_IFDIR))
408                         devtype = CONNMAN_DEVICE_TYPE_WIMAX;
409                 else if (stat(bridge_path, &st) == 0 && (st.st_mode & S_IFDIR))
410                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
411                 else if (stat(bonding_path, &st) == 0 && (st.st_mode & S_IFDIR))
412                         devtype = CONNMAN_DEVICE_TYPE_UNKNOWN;
413                 else if (stat(phy80211_path, &st) == 0 && (st.st_mode & S_IFDIR))
414                         devtype = CONNMAN_DEVICE_TYPE_WIFI;
415                 else if (ioctl(sk, SIOCGIWNAME, &iwr) == 0)
416                         devtype = CONNMAN_DEVICE_TYPE_WIFI;
417                 else
418                         devtype = CONNMAN_DEVICE_TYPE_ETHERNET;
419         } else if (type == ARPHRD_NONE) {
420                 if (g_str_has_prefix(devname, "hso") == TRUE)
421                         devtype = CONNMAN_DEVICE_TYPE_HSO;
422         }
423
424 done:
425         close(sk);
426
427         return devtype;
428 }
429
430 struct connman_device *connman_inet_create_device(int index)
431 {
432         enum connman_device_mode mode = CONNMAN_DEVICE_MODE_UNKNOWN;
433         enum connman_device_type type;
434         struct connman_device *device;
435         char *devname, *ident = NULL;
436         char *addr = NULL, *name = NULL, *node = NULL;
437
438         if (index < 0)
439                 return NULL;
440
441         devname = connman_inet_ifname(index);
442         if (devname == NULL)
443                 return NULL;
444
445         if (__connman_element_device_isfiltered(devname) == TRUE) {
446                 connman_info("Ignoring interface %s (filtered)", devname);
447                 return NULL;
448         }
449
450         __connman_udev_get_devtype(devname);
451
452         type = __connman_inet_get_device_type(index);
453
454         switch (type) {
455         case CONNMAN_DEVICE_TYPE_UNKNOWN:
456                 connman_info("Ignoring interface %s (type unknown)", devname);
457                 g_free(devname);
458                 return NULL;
459         case CONNMAN_DEVICE_TYPE_ETHERNET:
460         case CONNMAN_DEVICE_TYPE_WIFI:
461         case CONNMAN_DEVICE_TYPE_WIMAX:
462                 name = index2ident(index, "");
463                 addr = index2addr(index);
464                 break;
465         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
466         case CONNMAN_DEVICE_TYPE_CELLULAR:
467         case CONNMAN_DEVICE_TYPE_GPS:
468         case CONNMAN_DEVICE_TYPE_HSO:
469         case CONNMAN_DEVICE_TYPE_VENDOR:
470                 name = strdup(devname);
471                 break;
472         case CONNMAN_DEVICE_TYPE_MBM:
473                 name = index2ident(index, "");
474                 addr = index2addr(index);
475                 node = __connman_udev_get_mbm_devnode(devname);
476                 break;
477         }
478
479         device = connman_device_create(name, type);
480         if (device == NULL)
481                 goto done;
482
483         switch (type) {
484         case CONNMAN_DEVICE_TYPE_UNKNOWN:
485         case CONNMAN_DEVICE_TYPE_VENDOR:
486         case CONNMAN_DEVICE_TYPE_GPS:
487                 mode = CONNMAN_DEVICE_MODE_UNKNOWN;
488                 break;
489         case CONNMAN_DEVICE_TYPE_ETHERNET:
490                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
491                 ident = index2ident(index, NULL);
492                 break;
493         case CONNMAN_DEVICE_TYPE_WIFI:
494         case CONNMAN_DEVICE_TYPE_WIMAX:
495                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
496                 ident = index2ident(index, NULL);
497                 break;
498         case CONNMAN_DEVICE_TYPE_BLUETOOTH:
499                 mode = CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE;
500                 break;
501         case CONNMAN_DEVICE_TYPE_CELLULAR:
502         case CONNMAN_DEVICE_TYPE_MBM:
503         case CONNMAN_DEVICE_TYPE_HSO:
504                 mode = CONNMAN_DEVICE_MODE_NETWORK_SINGLE;
505                 ident = index2ident(index, NULL);
506                 break;
507         }
508
509         connman_device_set_mode(device, mode);
510
511         connman_device_set_index(device, index);
512         connman_device_set_interface(device, devname, node);
513
514         if (ident != NULL) {
515                 connman_device_set_ident(device, ident);
516                 free(ident);
517         }
518
519         connman_device_set_string(device, "Address", addr);
520
521 done:
522         g_free(devname);
523         g_free(node);
524         free(name);
525         free(addr);
526
527         return device;
528 }
529
530 int connman_inet_set_address(int index, struct connman_ipaddress *ipaddress)
531 {
532         struct ifreq ifr;
533         struct sockaddr_in addr;
534         int sk, err;
535
536         sk = socket(PF_INET, SOCK_DGRAM, 0);
537         if (sk < 0)
538                 return -1;
539
540         memset(&ifr, 0, sizeof(ifr));
541         ifr.ifr_ifindex = index;
542
543         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
544                 close(sk);
545                 return -1;
546         }
547
548         DBG("ifname %s", ifr.ifr_name);
549
550         if (ipaddress->local == NULL) {
551                 close(sk);
552                 return -1;
553         }
554
555         memset(&addr, 0, sizeof(addr));
556         addr.sin_family = AF_INET;
557         addr.sin_addr.s_addr = inet_addr(ipaddress->local);
558         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
559
560         err = ioctl(sk, SIOCSIFADDR, &ifr);
561
562         if (err < 0)
563                 DBG("address setting failed (%s)", strerror(errno));
564
565         memset(&addr, 0, sizeof(addr));
566         addr.sin_family = AF_INET;
567         addr.sin_addr.s_addr = htonl(~(0xfffffffflu >> ipaddress->prefixlen));
568         memcpy(&ifr.ifr_netmask, &addr, sizeof(ifr.ifr_netmask));
569
570         err = ioctl(sk, SIOCSIFNETMASK, &ifr);
571
572         if (err < 0)
573                 DBG("netmask setting failed (%s)", strerror(errno));
574
575         memset(&addr, 0, sizeof(addr));
576         addr.sin_family = AF_INET;
577
578         if (ipaddress->broadcast != NULL)
579                 addr.sin_addr.s_addr = inet_addr(ipaddress->broadcast);
580         else
581                 addr.sin_addr.s_addr = inet_addr(ipaddress->local) |
582                                 htonl(0xfffffffflu >> ipaddress->prefixlen);
583
584         memcpy(&ifr.ifr_broadaddr, &addr, sizeof(ifr.ifr_broadaddr));
585
586         err = ioctl(sk, SIOCSIFBRDADDR, &ifr);
587
588         if (err < 0)
589                 DBG("broadcast setting failed (%s)", strerror(errno));
590
591         close(sk);
592
593         return 0;
594 }
595
596 int connman_inet_clear_address(int index)
597 {
598         struct ifreq ifr;
599         struct sockaddr_in addr;
600         int sk, err;
601
602         sk = socket(PF_INET, SOCK_DGRAM, 0);
603         if (sk < 0)
604                 return -1;
605
606         memset(&ifr, 0, sizeof(ifr));
607         ifr.ifr_ifindex = index;
608
609         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
610                 close(sk);
611                 return -1;
612         }
613
614         DBG("ifname %s", ifr.ifr_name);
615
616         memset(&addr, 0, sizeof(addr));
617         addr.sin_family = AF_INET;
618         addr.sin_addr.s_addr = INADDR_ANY;
619         memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr));
620
621         //err = ioctl(sk, SIOCDIFADDR, &ifr);
622         err = ioctl(sk, SIOCSIFADDR, &ifr);
623
624         close(sk);
625
626         if (err < 0 && errno != EADDRNOTAVAIL) {
627                 DBG("address removal failed (%s)", strerror(errno));
628                 return -1;
629         }
630
631         return 0;
632 }
633
634 int connman_inet_add_host_route(int index, const char *host)
635 {
636         struct ifreq ifr;
637         struct rtentry rt;
638         struct sockaddr_in addr;
639         int sk, err;
640
641         sk = socket(PF_INET, SOCK_DGRAM, 0);
642         if (sk < 0)
643                 return -1;
644
645         memset(&ifr, 0, sizeof(ifr));
646         ifr.ifr_ifindex = index;
647
648         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
649                 close(sk);
650                 return -1;
651         }
652
653         DBG("ifname %s", ifr.ifr_name);
654
655         memset(&rt, 0, sizeof(rt));
656         rt.rt_flags = RTF_UP | RTF_HOST;
657
658         memset(&addr, 0, sizeof(addr));
659         addr.sin_family = AF_INET;
660         addr.sin_addr.s_addr = inet_addr(host);
661         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
662
663         memset(&addr, 0, sizeof(addr));
664         addr.sin_family = AF_INET;
665         addr.sin_addr.s_addr = INADDR_ANY;
666         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
667
668         memset(&addr, 0, sizeof(addr));
669         addr.sin_family = AF_INET;
670         addr.sin_addr.s_addr = INADDR_ANY;
671         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
672
673         rt.rt_dev = ifr.ifr_name;
674
675         err = ioctl(sk, SIOCADDRT, &rt);
676         if (err < 0)
677                 connman_error("Adding host route failed (%s)",
678                                                         strerror(errno));
679
680         close(sk);
681
682         return err;
683 }
684
685 int connman_inet_del_host_route(int index, const char *host)
686 {
687         struct ifreq ifr;
688         struct rtentry rt;
689         struct sockaddr_in addr;
690         int sk, err;
691
692         sk = socket(PF_INET, SOCK_DGRAM, 0);
693         if (sk < 0)
694                 return -1;
695
696         memset(&ifr, 0, sizeof(ifr));
697         ifr.ifr_ifindex = index;
698
699         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
700                 close(sk);
701                 return -1;
702         }
703
704         DBG("ifname %s", ifr.ifr_name);
705
706         memset(&rt, 0, sizeof(rt));
707         rt.rt_flags = RTF_UP | RTF_HOST;
708
709         memset(&addr, 0, sizeof(addr));
710         addr.sin_family = AF_INET;
711         addr.sin_addr.s_addr = inet_addr(host);
712         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
713
714         rt.rt_dev = ifr.ifr_name;
715
716         err = ioctl(sk, SIOCDELRT, &rt);
717         if (err < 0)
718                 connman_error("Deleting host route failed (%s)",
719                                                         strerror(errno));
720
721         close(sk);
722
723         return err;
724 }
725
726 int connman_inet_set_gateway_address(int index, const char *gateway)
727 {
728         struct ifreq ifr;
729         struct rtentry rt;
730         struct sockaddr_in addr;
731         int sk, err;
732
733         sk = socket(PF_INET, SOCK_DGRAM, 0);
734         if (sk < 0)
735                 return -1;
736
737         memset(&ifr, 0, sizeof(ifr));
738         ifr.ifr_ifindex = index;
739
740         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
741                 close(sk);
742                 return -1;
743         }
744
745         DBG("ifname %s", ifr.ifr_name);
746
747         memset(&rt, 0, sizeof(rt));
748         rt.rt_flags = RTF_UP | RTF_GATEWAY;
749
750         memset(&addr, 0, sizeof(addr));
751         addr.sin_family = AF_INET;
752         addr.sin_addr.s_addr = INADDR_ANY;
753         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
754
755         memset(&addr, 0, sizeof(addr));
756         addr.sin_family = AF_INET;
757         addr.sin_addr.s_addr = inet_addr(gateway);
758         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
759
760         memset(&addr, 0, sizeof(addr));
761         addr.sin_family = AF_INET;
762         addr.sin_addr.s_addr = INADDR_ANY;
763         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
764
765         err = ioctl(sk, SIOCADDRT, &rt);
766         if (err < 0)
767                 connman_error("Setting default gateway route failed (%s)",
768                                                         strerror(errno));
769
770         close(sk);
771
772         return err;
773 }
774
775 int connman_inet_set_gateway_interface(int index)
776 {
777         struct ifreq ifr;
778         struct rtentry rt;
779         struct sockaddr_in addr;
780         int sk, err;
781
782         DBG("");
783
784         sk = socket(PF_INET, SOCK_DGRAM, 0);
785         if (sk < 0)
786                 return -1;
787
788         memset(&ifr, 0, sizeof(ifr));
789         ifr.ifr_ifindex = index;
790
791         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
792                 close(sk);
793                 return -1;
794         }
795
796         DBG("ifname %s", ifr.ifr_name);
797
798         memset(&rt, 0, sizeof(rt));
799         rt.rt_flags = RTF_UP;
800
801         memset(&addr, 0, sizeof(addr));
802         addr.sin_family = AF_INET;
803         addr.sin_addr.s_addr = INADDR_ANY;
804
805         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
806         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
807         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
808
809         rt.rt_dev = ifr.ifr_name;
810
811         err = ioctl(sk, SIOCADDRT, &rt);
812         if (err < 0)
813                 connman_error("Setting default interface route failed (%s)",
814                                                         strerror(errno));
815         close(sk);
816
817         return err;
818 }
819
820 int connman_inet_clear_gateway_address(int index, const char *gateway)
821 {
822         struct ifreq ifr;
823         struct rtentry rt;
824         struct sockaddr_in addr;
825         int sk, err;
826
827         DBG("");
828
829         sk = socket(PF_INET, SOCK_DGRAM, 0);
830         if (sk < 0)
831                 return -1;
832
833         memset(&ifr, 0, sizeof(ifr));
834         ifr.ifr_ifindex = index;
835
836         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
837                 close(sk);
838                 return -1;
839         }
840
841         DBG("ifname %s", ifr.ifr_name);
842
843         memset(&rt, 0, sizeof(rt));
844         rt.rt_flags = RTF_UP | RTF_GATEWAY;
845
846         memset(&addr, 0, sizeof(addr));
847         addr.sin_family = AF_INET;
848         addr.sin_addr.s_addr = INADDR_ANY;
849         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
850
851         memset(&addr, 0, sizeof(addr));
852         addr.sin_family = AF_INET;
853         addr.sin_addr.s_addr = inet_addr(gateway);
854         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
855
856         memset(&addr, 0, sizeof(addr));
857         addr.sin_family = AF_INET;
858         addr.sin_addr.s_addr = INADDR_ANY;
859         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
860
861         err = ioctl(sk, SIOCDELRT, &rt);
862         if (err < 0)
863                 connman_error("Removing default gateway route failed (%s)",
864                                                         strerror(errno));
865
866         close(sk);
867
868         return err;
869 }