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 "linux_ioctl.h"
18 int linux_set_iface_flags(int sock, const char *ifname, int dev_up)
26 os_memset(&ifr, 0, sizeof(ifr));
27 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
29 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
30 ret = errno ? -errno : -999;
31 wpa_printf(MSG_ERROR, "Could not read interface %s flags: %s",
32 ifname, strerror(errno));
37 if (ifr.ifr_flags & IFF_UP)
39 ifr.ifr_flags |= IFF_UP;
41 if (!(ifr.ifr_flags & IFF_UP))
43 ifr.ifr_flags &= ~IFF_UP;
46 if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
47 ret = errno ? -errno : -999;
48 wpa_printf(MSG_ERROR, "Could not set interface %s flags (%s): "
50 ifname, dev_up ? "UP" : "DOWN", strerror(errno));
58 int linux_iface_up(int sock, const char *ifname)
66 os_memset(&ifr, 0, sizeof(ifr));
67 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
69 if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
70 ret = errno ? -errno : -999;
71 wpa_printf(MSG_ERROR, "Could not read interface %s flags: %s",
72 ifname, strerror(errno));
76 return !!(ifr.ifr_flags & IFF_UP);
80 int linux_get_ifhwaddr(int sock, const char *ifname, u8 *addr)
84 os_memset(&ifr, 0, sizeof(ifr));
85 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
86 if (ioctl(sock, SIOCGIFHWADDR, &ifr)) {
87 wpa_printf(MSG_ERROR, "Could not get interface %s hwaddr: %s",
88 ifname, strerror(errno));
92 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) {
93 wpa_printf(MSG_ERROR, "%s: Invalid HW-addr family 0x%04x",
94 ifname, ifr.ifr_hwaddr.sa_family);
97 os_memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
103 int linux_set_ifhwaddr(int sock, const char *ifname, const u8 *addr)
107 os_memset(&ifr, 0, sizeof(ifr));
108 os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
109 os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
110 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
112 if (ioctl(sock, SIOCSIFHWADDR, &ifr)) {
113 wpa_printf(MSG_DEBUG, "Could not set interface %s hwaddr: %s",
114 ifname, strerror(errno));
123 #define SIOCBRADDBR 0x89a0
126 #define SIOCBRDELBR 0x89a1
129 #define SIOCBRADDIF 0x89a2
132 #define SIOCBRDELIF 0x89a3
136 int linux_br_add(int sock, const char *brname)
138 if (ioctl(sock, SIOCBRADDBR, brname) < 0) {
139 wpa_printf(MSG_DEBUG, "Could not add bridge %s: %s",
140 brname, strerror(errno));
148 int linux_br_del(int sock, const char *brname)
150 if (ioctl(sock, SIOCBRDELBR, brname) < 0) {
151 wpa_printf(MSG_DEBUG, "Could not remove bridge %s: %s",
152 brname, strerror(errno));
160 int linux_br_add_if(int sock, const char *brname, const char *ifname)
165 ifindex = if_nametoindex(ifname);
169 os_memset(&ifr, 0, sizeof(ifr));
170 os_strlcpy(ifr.ifr_name, brname, IFNAMSIZ);
171 ifr.ifr_ifindex = ifindex;
172 if (ioctl(sock, SIOCBRADDIF, &ifr) < 0) {
173 wpa_printf(MSG_DEBUG, "Could not add interface %s into bridge "
174 "%s: %s", ifname, brname, strerror(errno));
182 int linux_br_del_if(int sock, const char *brname, const char *ifname)
187 ifindex = if_nametoindex(ifname);
191 os_memset(&ifr, 0, sizeof(ifr));
192 os_strlcpy(ifr.ifr_name, brname, IFNAMSIZ);
193 ifr.ifr_ifindex = ifindex;
194 if (ioctl(sock, SIOCBRDELIF, &ifr) < 0) {
195 wpa_printf(MSG_DEBUG, "Could not remove interface %s from "
196 "bridge %s: %s", ifname, brname, strerror(errno));
204 int linux_br_get(char *brname, const char *ifname)
206 char path[128], brlink[128], *pos;
209 os_snprintf(path, sizeof(path), "/sys/class/net/%s/brport/bridge",
211 res = readlink(path, brlink, sizeof(brlink));
212 if (res < 0 || (size_t) res >= sizeof(brlink))
215 pos = os_strrchr(brlink, '/');
219 os_strlcpy(brname, pos, IFNAMSIZ);
224 int linux_master_get(char *master_ifname, const char *ifname)
226 char buf[128], masterlink[128], *pos;
229 /* check whether there is a master */
230 os_snprintf(buf, sizeof(buf), "/sys/class/net/%s/master", ifname);
232 res = readlink(buf, masterlink, sizeof(masterlink));
233 if (res < 0 || (size_t) res >= sizeof(masterlink))
236 masterlink[res] = '\0';
238 pos = os_strrchr(masterlink, '/');
242 os_strlcpy(master_ifname, pos, IFNAMSIZ);