Fix parsing of netlink messages for routing
[connman] / plugins / net.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007  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 <fcntl.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/ioctl.h>
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <net/if.h>
36
37 #include "net.h"
38
39 int __net_ifaddr(int ifindex, struct in_addr *addr)
40 {
41         struct ifreq ifr;
42         int sk;
43
44         sk = socket(PF_INET, SOCK_DGRAM, 0);
45         if (sk < 0)
46                 return -errno;
47
48         memset(&ifr, 0, sizeof(ifr));
49         ifr.ifr_ifindex = ifindex;
50
51         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
52                 close(sk);
53                 return -errno;
54         }
55
56         if (ioctl(sk, SIOCGIFADDR, &ifr) < 0) {
57                 close(sk);
58                 return -errno;
59         }
60
61         close(sk);
62
63         *addr = ((struct sockaddr_in *) (&ifr.ifr_addr))->sin_addr;
64
65         return 0;
66 }
67
68 char *__net_ifname(int ifindex)
69 {
70         struct ifreq ifr;
71         int sk, err;
72
73         sk = socket(PF_INET, SOCK_DGRAM, 0);
74         if (sk < 0)
75                 return NULL;
76
77         memset(&ifr, 0, sizeof(ifr));
78         ifr.ifr_ifindex = ifindex;
79
80         err = ioctl(sk, SIOCGIFNAME, &ifr);
81
82         close(sk);
83
84         if (err < 0)
85                 return NULL;
86
87         return strdup(ifr.ifr_name);
88 }
89
90 void __net_free(void *ptr)
91 {
92         if (ptr)
93                 free(ptr);
94 }
95
96 int __net_clear(int ifindex)
97 {
98         char *ifname, cmd[128];
99
100         ifname = __net_ifname(ifindex);
101         if (ifname == NULL)
102                 return -1;
103
104         sprintf(cmd, "resolvconf -d %s", ifname);
105         printf("[NET] %s\n", cmd);
106         system(cmd);
107
108         sprintf(cmd, "ip addr flush dev %s", ifname);
109         printf("[NET] %s\n", cmd);
110         system(cmd);
111
112         __net_free(ifname);
113
114         return 0;
115 }
116
117 int __net_set(int ifindex, struct in_addr *addr, struct in_addr *mask,
118                                 struct in_addr *route, struct in_addr *bcast,
119                                                 struct in_addr *namesrv)
120 {
121         char *ifname, cmd[128], msk[32], brd[32];
122
123         ifname = __net_ifname(ifindex);
124         if (ifname == NULL)
125                 return -1;
126
127         __net_clear(ifindex);
128
129         sprintf(msk, "%s", "24");
130         sprintf(brd, "%s", inet_ntoa(*bcast));
131         sprintf(cmd, "ip addr add %s/%s brd %s dev %s",
132                                 inet_ntoa(*addr), msk, brd, ifname);
133         printf("[NET] %s\n", cmd);
134         system(cmd);
135
136         sprintf(cmd, "ip route add default via %s dev %s",
137                                         inet_ntoa(*route), ifname);
138         printf("[NET] %s\n", cmd);
139         system(cmd);
140
141         sprintf(cmd, "echo \"nameserver %s\" | resolvconf -a %s",
142                                         inet_ntoa(*namesrv), ifname);
143         printf("[NET] %s\n", cmd);
144         system(cmd);
145
146         __net_free(ifname);
147
148         return 0;
149 }