2 * Linux ioctl helper functions for driver wrappers
3 * Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
16 #include <sys/ioctl.h>
18 #include <net/if_arp.h>
20 #include "utils/common.h"
21 #include "linux_ioctl.h"
24 int linux_set_iface_flags(int sock
, const char *ifname
, int dev_up
)
31 os_memset(&ifr
, 0, sizeof(ifr
));
32 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
34 if (ioctl(sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
35 wpa_printf(MSG_ERROR
, "Could not read interface %s flags: %s",
36 ifname
, strerror(errno
));
41 if (ifr
.ifr_flags
& IFF_UP
)
43 ifr
.ifr_flags
|= IFF_UP
;
45 if (!(ifr
.ifr_flags
& IFF_UP
))
47 ifr
.ifr_flags
&= ~IFF_UP
;
50 if (ioctl(sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
51 wpa_printf(MSG_ERROR
, "Could not set interface %s flags: %s",
52 ifname
, strerror(errno
));
60 int linux_get_ifhwaddr(int sock
, const char *ifname
, u8
*addr
)
64 os_memset(&ifr
, 0, sizeof(ifr
));
65 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
66 if (ioctl(sock
, SIOCGIFHWADDR
, &ifr
)) {
67 wpa_printf(MSG_ERROR
, "Could not get interface %s hwaddr: %s",
68 ifname
, strerror(errno
));
72 if (ifr
.ifr_hwaddr
.sa_family
!= ARPHRD_ETHER
) {
73 wpa_printf(MSG_ERROR
, "%s: Invalid HW-addr family 0x%04x",
74 ifname
, ifr
.ifr_hwaddr
.sa_family
);
77 os_memcpy(addr
, ifr
.ifr_hwaddr
.sa_data
, ETH_ALEN
);
83 int linux_set_ifhwaddr(int sock
, const char *ifname
, const u8
*addr
)
87 os_memset(&ifr
, 0, sizeof(ifr
));
88 os_strlcpy(ifr
.ifr_name
, ifname
, IFNAMSIZ
);
89 os_memcpy(ifr
.ifr_hwaddr
.sa_data
, addr
, ETH_ALEN
);
90 ifr
.ifr_hwaddr
.sa_family
= ARPHRD_ETHER
;
92 if (ioctl(sock
, SIOCSIFHWADDR
, &ifr
)) {
93 wpa_printf(MSG_DEBUG
, "Could not set interface %s hwaddr: %s",
94 ifname
, strerror(errno
));
103 #define SIOCBRADDBR 0x89a0
106 #define SIOCBRDELBR 0x89a1
109 #define SIOCBRADDIF 0x89a2
112 #define SIOCBRDELIF 0x89a3
116 int linux_br_add(int sock
, const char *brname
)
118 if (ioctl(sock
, SIOCBRADDBR
, brname
) < 0) {
119 wpa_printf(MSG_DEBUG
, "Could not add bridge %s: %s",
120 brname
, strerror(errno
));
128 int linux_br_del(int sock
, const char *brname
)
130 if (ioctl(sock
, SIOCBRDELBR
, brname
) < 0) {
131 wpa_printf(MSG_DEBUG
, "Could not remove bridge %s: %s",
132 brname
, strerror(errno
));
140 int linux_br_add_if(int sock
, const char *brname
, const char *ifname
)
145 ifindex
= if_nametoindex(ifname
);
149 os_memset(&ifr
, 0, sizeof(ifr
));
150 os_strlcpy(ifr
.ifr_name
, brname
, IFNAMSIZ
);
151 ifr
.ifr_ifindex
= ifindex
;
152 if (ioctl(sock
, SIOCBRADDIF
, &ifr
) < 0) {
153 wpa_printf(MSG_DEBUG
, "Could not add interface %s into bridge "
154 "%s: %s", ifname
, brname
, strerror(errno
));
162 int linux_br_del_if(int sock
, const char *brname
, const char *ifname
)
167 ifindex
= if_nametoindex(ifname
);
171 os_memset(&ifr
, 0, sizeof(ifr
));
172 os_strlcpy(ifr
.ifr_name
, brname
, IFNAMSIZ
);
173 ifr
.ifr_ifindex
= ifindex
;
174 if (ioctl(sock
, SIOCBRDELIF
, &ifr
) < 0) {
175 wpa_printf(MSG_DEBUG
, "Could not remove interface %s from "
176 "bridge %s: %s", ifname
, brname
, strerror(errno
));
184 int linux_br_get(char *brname
, const char *ifname
)
186 char path
[128], brlink
[128], *pos
;
187 os_snprintf(path
, sizeof(path
), "/sys/class/net/%s/brport/bridge",
189 os_memset(brlink
, 0, sizeof(brlink
));
190 if (readlink(path
, brlink
, sizeof(brlink
) - 1) < 0)
192 pos
= os_strrchr(brlink
, '/');
196 os_strlcpy(brname
, pos
, IFNAMSIZ
);