AquilaOS documentation
How it works, and its code
Toggle main menu visibility
Loading...
Searching...
No Matches
ifioctl.c
Go to the documentation of this file.
1
8
9
#include <
core/system.h
>
10
#include <
core/string.h
>
11
#include <
net/byteorder.h
>
12
#include <
net/inet.h
>
13
#include <
sys/proc.h
>
14
#include <
sys/sched.h
>
15
#include <
sys/uaccess.h
>
16
17
#include <aquila/errno.h>
18
#include <aquila/if.h>
19
#include <aquila/in.h>
20
#include <aquila/ioctl.h>
21
#include <aquila/route.h>
22
24
static
int
netif_index
(
struct
netif
*
netif
)
25
{
26
int
i = 1;
27
28
for
(
struct
netif
*n =
netifs
; n && n !=
netif
; n = n->
next
)
29
++i;
30
31
return
i;
32
}
33
35
static
void
ifaddr_put
(
struct
sockaddr *a,
uint32_t
ip
)
36
{
37
struct
sockaddr_in *sin = (
struct
sockaddr_in *) a;
38
39
memset
(a, 0,
sizeof
(*a));
40
sin->sin_family = AF_INET;
41
sin->sin_addr.s_addr = ip;
42
}
43
46
static
int
ifaddr_get
(
const
struct
sockaddr *a,
uint32_t
*ip)
47
{
48
const
struct
sockaddr_in *sin = (
const
struct
sockaddr_in *) a;
49
50
if
(sin->sin_family != AF_INET)
51
return
-EAFNOSUPPORT;
52
53
*ip = sin->sin_addr.s_addr;
54
return
0;
55
}
56
60
static
int
ifconf
(
struct
ifconf
*uifc)
61
{
62
struct
ifconf
ifc;
63
64
if
(copyin(&ifc, uifc,
sizeof
(ifc)))
65
return
-EFAULT;
66
67
int
n = 0;
68
69
for
(
struct
netif
*
netif
=
netifs
;
netif
;
netif
=
netif
->
next
)
70
++n;
71
72
if
(!ifc.ifc_buf) {
73
ifc.ifc_len = n *
sizeof
(
struct
ifreq);
74
return
copyout(uifc, &ifc,
sizeof
(ifc));
75
}
76
77
if
(ifc.ifc_len < 0)
78
return
-EINVAL;
79
80
int
len = 0;
81
82
/* make each entry here, then copy it out */
83
for
(
struct
netif
*
netif
=
netifs
;
netif
;
netif
=
netif
->
next
) {
84
if
(len + (
int
)
sizeof
(
struct
ifreq) > ifc.ifc_len)
85
break
;
86
87
struct
ifreq ifr;
88
memset
(&ifr, 0,
sizeof
(ifr));
89
memcpy
(ifr.ifr_name,
netif
->
name
,
sizeof
(
netif
->
name
));
90
ifaddr_put
(&ifr.ifr_addr,
netif
->
ip
);
91
92
if
(copyout(ifc.ifc_buf + len, &ifr,
sizeof
(ifr)))
93
return
-EFAULT;
94
95
len +=
sizeof
(
struct
ifreq);
96
}
97
98
ifc.ifc_len = len;
99
return
copyout(uifc, &ifc,
sizeof
(ifc));
100
}
101
106
static
int
route
(
int
request,
struct
rtentry *urt)
107
{
108
struct
rtentry _rt, *rt = &_rt;
109
110
if
(copyin(rt, urt,
sizeof
(*rt)))
111
return
-EFAULT;
112
113
const
struct
sockaddr_in *dst = (
const
struct
sockaddr_in *) &rt->rt_dst;
114
const
struct
sockaddr_in *mask = (
const
struct
sockaddr_in *) &rt->rt_genmask;
115
const
struct
sockaddr_in *gateway = (
const
struct
sockaddr_in *) &rt->rt_gateway;
116
117
if
(dst->sin_addr.s_addr || mask->sin_addr.s_addr)
118
return
-EINVAL;
119
120
if
(request == SIOCDELRT) {
121
for
(
struct
netif
*
netif
=
netifs
;
netif
;
netif
=
netif
->
next
)
122
netif
->
gateway
= 0;
123
124
return
0;
125
}
126
127
uint32_t
gw = gateway->sin_addr.s_addr;
128
129
if
(!(rt->rt_flags & RTF_GATEWAY) || gateway->sin_family != AF_INET || !gw)
130
return
-EINVAL;
131
132
for
(
struct
netif
*
netif
=
netifs
;
netif
;
netif
=
netif
->
next
) {
133
if
(
netif
->
ip
&& (gw &
netif
->
netmask
) == (
netif
->
ip
&
netif
->
netmask
)) {
134
netif
->
gateway
= gw;
135
return
0;
136
}
137
}
138
139
return
-ENETUNREACH;
140
}
141
142
static
int
ifreq_request
(
int
request,
struct
ifreq *ifr);
143
153
int
inet_ifioctl
(
int
request,
void
*argp)
154
{
155
switch
(request) {
156
case
SIOCGIFCONF:
157
return
ifconf
(argp);
158
159
case
SIOCADDRT:
160
case
SIOCDELRT:
161
if
(
curproc
->uid)
162
return
-EPERM;
163
164
return
route
(request, argp);
165
}
166
167
/* the requests about one interface, named in a struct ifreq: work on
168
* the kernel's copy of it, then copy it back out */
169
struct
ifreq ifr;
170
171
switch
(request) {
172
case
SIOCGIFFLAGS:
case
SIOCSIFFLAGS:
173
case
SIOCGIFADDR:
case
SIOCSIFADDR:
174
case
SIOCGIFNETMASK:
case
SIOCSIFNETMASK:
175
case
SIOCGIFBRDADDR:
case
SIOCGIFHWADDR:
176
case
SIOCGIFMTU:
case
SIOCGIFINDEX:
177
break
;
178
default
:
179
return
-ENOTTY;
180
}
181
182
if
(copyin(&ifr, argp,
sizeof
(ifr)))
183
return
-EFAULT;
184
185
ifr.ifr_name[
sizeof
(ifr.ifr_name) - 1] =
'\0'
;
186
187
int
err =
ifreq_request
(request, &ifr);
188
return
err ? err : copyout(argp, &ifr,
sizeof
(ifr));
189
}
190
193
static
int
ifreq_request
(
int
request,
struct
ifreq *ifr)
194
{
195
struct
netif
*
netif
=
netif_find
(ifr->ifr_name);
196
197
if
(!
netif
)
198
return
-ENODEV;
199
200
int
set = request == SIOCSIFFLAGS || request == SIOCSIFADDR || request == SIOCSIFNETMASK;
201
202
if
(set &&
curproc
->uid)
203
return
-EPERM;
204
205
uint32_t
ip
;
206
int
err;
207
208
switch
(request) {
209
case
SIOCGIFFLAGS:
210
ifr->ifr_flags = (
netif
->
flags
&
NETIF_LOOPBACK
? IFF_LOOPBACK : IFF_BROADCAST | IFF_MULTICAST) |
211
(
netif
->
flags
&
NETIF_UP
? IFF_UP : 0) |
212
(
netif
->
flags
&
NETIF_RUNNING
? IFF_RUNNING : 0);
213
return
0;
214
215
case
SIOCSIFFLAGS:
216
if
(ifr->ifr_flags & IFF_UP)
217
netif
->
flags
|=
NETIF_UP
;
218
else
219
netif
->
flags
&=
~NETIF_UP
;
220
return
0;
221
222
case
SIOCGIFADDR:
223
ifaddr_put
(&ifr->ifr_addr,
netif
->
ip
);
224
return
0;
225
226
case
SIOCSIFADDR:
227
if
((err =
ifaddr_get
(&ifr->ifr_addr, &
ip
)))
228
return
err;
229
230
netif
->
ip
=
ip
;
231
232
/* a /24 mask until one is set (whatever the address's
233
* class) */
234
if
(!
netif
->
netmask
)
235
netif
->
netmask
=
htonl
(0xffffff00);
236
237
return
0;
238
239
case
SIOCGIFNETMASK:
240
ifaddr_put
(&ifr->ifr_netmask,
netif
->
netmask
);
241
return
0;
242
243
case
SIOCSIFNETMASK:
244
if
((err =
ifaddr_get
(&ifr->ifr_netmask, &
ip
)))
245
return
err;
246
247
netif
->
netmask
=
ip
;
248
return
0;
249
250
case
SIOCGIFBRDADDR:
251
ifaddr_put
(&ifr->ifr_broadaddr,
netif
->
ip
| ~
netif
->
netmask
);
252
return
0;
253
254
case
SIOCGIFHWADDR:
255
memset
(&ifr->ifr_hwaddr, 0,
sizeof
(ifr->ifr_hwaddr));
256
ifr->ifr_hwaddr.sa_family =
netif
->
flags
&
NETIF_LOOPBACK
? ARPHRD_LOOPBACK : ARPHRD_ETHER;
257
memcpy
(ifr->ifr_hwaddr.sa_data,
netif
->
mac
, 6);
258
return
0;
259
260
case
SIOCGIFMTU:
261
ifr->ifr_mtu =
netif
->
mtu
;
262
return
0;
263
264
case
SIOCGIFINDEX:
265
ifr->ifr_ifindex =
netif_index
(
netif
);
266
return
0;
267
}
268
269
return
-ENOTTY;
270
}
byteorder.h
htonl
#define htonl(x)
Definition
byteorder.h:11
ifaddr_get
static int ifaddr_get(const struct sockaddr *a, uint32_t *ip)
Reads an IPv4 address from a struct sockaddr.
Definition
ifioctl.c:46
ifconf
static int ifconf(struct ifconf *uifc)
Handles SIOCGIFCONF: lists as many interfaces as the buffer has room for, or says how much room is ne...
Definition
ifioctl.c:60
ifaddr_put
static void ifaddr_put(struct sockaddr *a, uint32_t ip)
Writes an IPv4 address into a struct sockaddr.
Definition
ifioctl.c:35
ifreq_request
static int ifreq_request(int request, struct ifreq *ifr)
Handles a request about one interface, on the kernel's copy of the struct ifreq.
Definition
ifioctl.c:193
route
static int route(int request, struct rtentry *urt)
Handles SIOCADDRT and SIOCDELRT, for the default route only (0.0.0.0/0 through a gateway): the gatewa...
Definition
ifioctl.c:106
netif_index
static int netif_index(struct netif *netif)
Returns an interface's index: its place in the list, from 1.
Definition
ifioctl.c:24
system.h
inet.h
inet_ifioctl
int inet_ifioctl(int request, void *argp)
Handles an interface ioctl() request on an AF_INET socket.
Definition
ifioctl.c:153
memset
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition
libc.c:23
memcpy
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition
libc.c:11
NETIF_LOOPBACK
#define NETIF_LOOPBACK
Definition
netif.h:10
NETIF_UP
#define NETIF_UP
Definition
netif.h:8
netif_find
struct netif * netif_find(const char *name)
Finds an interface by its name.
Definition
netif.c:186
NETIF_RUNNING
#define NETIF_RUNNING
Definition
netif.h:9
netifs
struct netif * netifs
Definition
netif.c:34
proc.h
sched.h
curproc
#define curproc
Definition
sched.h:13
uint32_t
unsigned int uint32_t
Definition
stddef.h:22
string.h
netif
A network interface (net/netif.c): a device that sends and receives Ethernet frames,...
Definition
netif.h:16
netif::flags
int flags
Definition
netif.h:20
netif::ip
uint32_t ip
Definition
netif.h:24
netif::netmask
uint32_t netmask
Definition
netif.h:24
netif::name
char name[8]
Definition
netif.h:17
netif::gateway
uint32_t gateway
Definition
netif.h:24
netif::mac
uint8_t mac[6]
Definition
netif.h:18
netif::mtu
uint16_t mtu
Definition
netif.h:19
netif::next
struct netif * next
Definition
netif.h:37
uaccess.h
kernel
net
inet
ifioctl.c
Generated by
1.18.0