]>
git.ipfire.org Git - thirdparty/hostap.git/blob - src/drivers/linux_ioctl.c
2 * Linux ioctl helper functions for driver wrappers
3 * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
10 #include <sys/ioctl.h>
12 #include <net/if_arp.h>
14 #include "utils/common.h"
15 #include "common/linux_bridge.h"
16 #include "linux_ioctl.h"
19 int linux_set_iface_flags(int sock
, const char *ifname
, int dev_up
)
27 os_memset(&ifr
, 0, sizeof(ifr
));
28 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
30 if (ioctl(sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
31 ret
= errno
? -errno
: -999;
32 wpa_printf(MSG_ERROR
, "Could not read interface %s flags: %s",
33 ifname
, strerror(errno
));
38 if (ifr
.ifr_flags
& IFF_UP
)
40 ifr
.ifr_flags
|= IFF_UP
;
42 if (!(ifr
.ifr_flags
& IFF_UP
))
44 ifr
.ifr_flags
&= ~IFF_UP
;
47 if (ioctl(sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
48 ret
= errno
? -errno
: -999;
49 wpa_printf(MSG_ERROR
, "Could not set interface %s flags (%s): "
51 ifname
, dev_up
? "UP" : "DOWN", strerror(errno
));
59 int linux_iface_up(int sock
, const char *ifname
)
67 os_memset(&ifr
, 0, sizeof(ifr
));
68 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
70 if (ioctl(sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
71 ret
= errno
? -errno
: -999;
72 wpa_printf(MSG_ERROR
, "Could not read interface %s flags: %s",
73 ifname
, strerror(errno
));
77 return !!(ifr
.ifr_flags
& IFF_UP
);
81 int linux_get_ifhwaddr(int sock
, const char *ifname
, u8
*addr
)
85 os_memset(&ifr
, 0, sizeof(ifr
));
86 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
87 if (ioctl(sock
, SIOCGIFHWADDR
, &ifr
)) {
88 wpa_printf(MSG_ERROR
, "Could not get interface %s hwaddr: %s",
89 ifname
, strerror(errno
));
93 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) {
94 wpa_printf(MSG_ERROR
, "%s: Invalid HW-addr family 0x%04x",
95 ifname
, ifr
.ifr_hwaddr
.sa_family
);
98 os_memcpy(addr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
104 int linux_set_ifhwaddr(int sock
, const char *ifname
, const u8
*addr
)
108 os_memset(&ifr
, 0, sizeof(ifr
));
109 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
110 os_memcpy(ifr
.ifr_hwaddr
.sa_data
, addr
, ETH_ALEN
);
111 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
113 if (ioctl(sock
, SIOCSIFHWADDR
, &ifr
)) {
114 wpa_printf(MSG_DEBUG
, "Could not set interface %s hwaddr: %s",
115 ifname
, strerror(errno
));
123 int linux_br_add(int sock
, const char *brname
)
125 if (ioctl(sock
, SIOCBRADDBR
, brname
) < 0) {
126 int saved_errno
= errno
;
128 wpa_printf(MSG_DEBUG
, "Could not add bridge %s: %s",
129 brname
, strerror(errno
));
138 int linux_br_del(int sock
, const char *brname
)
140 if (ioctl(sock
, SIOCBRDELBR
, brname
) < 0) {
141 wpa_printf(MSG_DEBUG
, "Could not remove bridge %s: %s",
142 brname
, strerror(errno
));
150 int linux_br_add_if(int sock
, const char *brname
, const char *ifname
)
155 ifindex
= if_nametoindex(ifname
);
159 os_memset(&ifr
, 0, sizeof(ifr
));
160 os_strlcpy(ifr
.ifr_name
, brname
, IFNAMSIZ
);
161 ifr
.ifr_ifindex
= ifindex
;
162 if (ioctl(sock
, SIOCBRADDIF
, &ifr
) < 0) {
163 int saved_errno
= errno
;
165 wpa_printf(MSG_DEBUG
, "Could not add interface %s into bridge "
166 "%s: %s", ifname
, brname
, strerror(errno
));
175 int linux_br_del_if(int sock
, const char *brname
, const char *ifname
)
180 ifindex
= if_nametoindex(ifname
);
184 os_memset(&ifr
, 0, sizeof(ifr
));
185 os_strlcpy(ifr
.ifr_name
, brname
, IFNAMSIZ
);
186 ifr
.ifr_ifindex
= ifindex
;
187 if (ioctl(sock
, SIOCBRDELIF
, &ifr
) < 0) {
188 wpa_printf(MSG_DEBUG
, "Could not remove interface %s from "
189 "bridge %s: %s", ifname
, brname
, strerror(errno
));
197 int linux_br_get(char *brname
, const char *ifname
)
199 char path
[128], brlink
[128], *pos
;
202 os_snprintf(path
, sizeof(path
), "/sys/class/net/%s/brport/bridge",
204 res
= readlink(path
, brlink
, sizeof(brlink
));
205 if (res
< 0 || (size_t) res
>= sizeof(brlink
))
208 pos
= os_strrchr(brlink
, '/');
212 os_strlcpy(brname
, pos
, IFNAMSIZ
);
217 int linux_master_get(char *master_ifname
, const char *ifname
)
219 char buf
[128], masterlink
[128], *pos
;
222 /* check whether there is a master */
223 os_snprintf(buf
, sizeof(buf
), "/sys/class/net/%s/master", ifname
);
225 res
= readlink(buf
, masterlink
, sizeof(masterlink
));
226 if (res
< 0 || (size_t) res
>= sizeof(masterlink
))
229 masterlink
[res
] = '\0';
231 pos
= os_strrchr(masterlink
, '/');
235 os_strlcpy(master_ifname
, pos
, IFNAMSIZ
);