Add first draft of plugin API description
[connman] / src / iface-inet.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 <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <sys/ioctl.h>
30 #include <sys/socket.h>
31 #include <net/if.h>
32 #include <net/ethernet.h>
33
34 #include "connman.h"
35
36 int __connman_iface_create_identifier(struct connman_iface *iface)
37 {
38         struct ifreq ifr;
39         struct ether_addr *eth;
40         int sk, err;
41
42         DBG("iface %p", iface);
43
44         sk = socket(PF_INET, SOCK_DGRAM, 0);
45         if (sk < 0)
46                 return -EIO;
47
48         memset(&ifr, 0, sizeof(ifr));
49         ifr.ifr_ifindex = iface->index;
50
51         err = ioctl(sk, SIOCGIFNAME, &ifr);
52
53         if (err == 0)
54                 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
55
56         close(sk);
57
58         if (err < 0)
59                 return -EIO;
60
61         iface->identifier = malloc(18);
62         if (iface->identifier == NULL)
63                 return -ENOMEM;
64
65         eth = (void *) &ifr.ifr_hwaddr.sa_data;
66         sprintf(iface->identifier, "%02X-%02X-%02X-%02X-%02X-%02X",
67                                                 eth->ether_addr_octet[0],
68                                                 eth->ether_addr_octet[1],
69                                                 eth->ether_addr_octet[2],
70                                                 eth->ether_addr_octet[3],
71                                                 eth->ether_addr_octet[4],
72                                                 eth->ether_addr_octet[5]);
73
74         return 0;
75 }
76
77 int __connman_iface_init_via_inet(struct connman_iface *iface)
78 {
79         struct ifreq ifr;
80         int sk, err;
81
82         DBG("iface %p", iface);
83
84         sk = socket(PF_INET, SOCK_DGRAM, 0);
85         if (sk < 0)
86                 return -EIO;
87
88         memset(&ifr, 0, sizeof(ifr));
89         ifr.ifr_ifindex = iface->index;
90
91         err = ioctl(sk, SIOCGIFNAME, &ifr);
92
93         if (err == 0)
94                 err = ioctl(sk, SIOCGIFFLAGS, &ifr);
95
96         close(sk);
97
98         if (err < 0)
99                 return -EIO;
100
101         if (ifr.ifr_flags & IFF_UP)
102                 iface->state = CONNMAN_IFACE_STATE_ENABLED;
103         else
104                 iface->state = CONNMAN_IFACE_STATE_OFF;
105
106         if (ifr.ifr_flags & IFF_RUNNING)
107                 iface->state = CONNMAN_IFACE_STATE_CARRIER;
108
109         return 0;
110 }
111
112 int __connman_iface_up(struct connman_iface *iface)
113 {
114         struct ifreq ifr;
115         int sk, err;
116
117         DBG("iface %p", iface);
118
119         sk = socket(PF_INET, SOCK_DGRAM, 0);
120         if (sk < 0)
121                 return -errno;
122
123         memset(&ifr, 0, sizeof(ifr));
124         ifr.ifr_ifindex = iface->index;
125
126         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
127                 err = -errno;
128                 goto done;
129         }
130
131         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
132                 err = -errno;
133                 goto done;
134         }
135
136         if (ifr.ifr_flags & IFF_UP) {
137                 err = -EALREADY;
138                 goto done;
139         }
140
141         ifr.ifr_flags |= IFF_UP;
142
143         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
144                 err = -errno;
145                 goto done;
146         }
147
148         if (iface->driver->start)
149                 err = iface->driver->start(iface);
150         else
151                 err = 0;
152
153 done:
154         close(sk);
155
156         return err;
157 }
158
159 int __connman_iface_down(struct connman_iface *iface)
160 {
161         struct ifreq ifr;
162         int sk, err;
163
164         DBG("iface %p", iface);
165
166         if (iface->driver->stop) {
167                 err = iface->driver->stop(iface);
168                 if (err < 0)
169                         return err;
170         }
171
172         sk = socket(PF_INET, SOCK_DGRAM, 0);
173         if (sk < 0)
174                 return -errno;
175
176         memset(&ifr, 0, sizeof(ifr));
177         ifr.ifr_ifindex = iface->index;
178
179         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
180                 err = -errno;
181                 goto done;
182         }
183
184         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
185                 err = -errno;
186                 goto done;
187         }
188
189         if (!(ifr.ifr_flags & IFF_UP)) {
190                 err = -EALREADY;
191                 goto done;
192         }
193
194         ifr.ifr_flags &= ~IFF_UP;
195
196         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0)
197                 err = -errno;
198         else
199                 err = 0;
200
201 done:
202         close(sk);
203
204         return err;
205 }