driver_wext.c revision 1f69aa52ea2e0a73ac502565df8c666ee49cab6a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Driver interaction with generic Linux Wireless Extensions 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This program is free software; you can redistribute it and/or modify 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it under the terms of the GNU General Public License version 2 as 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * published by the Free Software Foundation. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, this software may be distributed under the terms of BSD 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * license. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See README and COPYING for more details. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * This file implements a driver interface for the Linux Wireless Extensions. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * When used with WE-18 or newer, this interface can be used as-is with number 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * of drivers. In addition to this, some of the common functions in this file 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * can be used by other driver interface implementations that use generic WE 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ioctls, but require private ioctls for some of the functionality. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "includes.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ioctl.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <net/if_arp.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "linux_wext.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "common.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "eloop.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "common/ieee802_11_defs.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "common/wpa_common.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "priv_netlink.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "netlink.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "linux_ioctl.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "rfkill.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "driver.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "driver_wext.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ANDROID 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "android_drv.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* ANDROID */ 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wpa_driver_wext_flush_pmkid(void *priv); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wpa_driver_wext_get_range(void *priv); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef ANDROID 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int wpa_driver_wext_driver_cmd(void *priv, char *cmd, char *buf, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t buf_len); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int wpa_driver_wext_combo_scan(void *priv, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpa_driver_scan_params *params); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int wpa_driver_signal_poll(void *priv, struct wpa_signal_info *si); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idx, u32 value) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iwreq iwr; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memset(&iwr, 0, sizeof(iwr)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iwr.u.param.flags = idx & IW_AUTH_INDEX; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iwr.u.param.value = value; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (errno != EOPNOTSUPP) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d " 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "value 0x%x) failed: %s)", 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idx, value, strerror(errno)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = errno == EOPNOTSUPP ? -2 : -1; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wpa_driver_wext_get_bssid - Get BSSID, SIOCGIWAP 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @priv: Pointer to private wext data from wpa_driver_wext_init() 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @bssid: Buffer for BSSID 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int wpa_driver_wext_get_bssid(void *priv, u8 *bssid) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpa_driver_wext_data *drv = priv; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iwreq iwr; 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int ret = 0; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memset(&iwr, 0, sizeof(iwr)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("ioctl[SIOCGIWAP]"); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = -1; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/** 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) * wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @priv: Pointer to private wext data from wpa_driver_wext_init() 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @bssid: BSSID 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: 0 on success, -1 on failure 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpa_driver_wext_data *drv = priv; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iwreq iwr; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memset(&iwr, 0, sizeof(iwr)); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iwr.u.ap_addr.sa_family = ARPHRD_ETHER; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bssid) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("ioctl[SIOCSIWAP]"); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = -1; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ret; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * wpa_driver_wext_get_ssid - Get SSID, SIOCGIWESSID 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @priv: Pointer to private wext data from wpa_driver_wext_init() 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ssid: Buffer for the SSID; must be at least 32 bytes long 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns: SSID length on success, -1 on failure 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int wpa_driver_wext_get_ssid(void *priv, u8 *ssid) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct wpa_driver_wext_data *drv = priv; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct iwreq iwr; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_memset(&iwr, 0, sizeof(iwr)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iwr.u.essid.pointer = (caddr_t) ssid; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iwr.u.essid.length = 32; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perror("ioctl[SIOCGIWESSID]"); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = -1; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = iwr.u.essid.length; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret > 32) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = 32; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Some drivers include nul termination in the SSID, so let's 160 * remove it here before further processing. WE-21 changes this 161 * to explicitly require the length _not_ to include nul 162 * termination. */ 163 if (ret > 0 && ssid[ret - 1] == '\0' && 164 drv->we_version_compiled < 21) 165 ret--; 166 } 167 168 return ret; 169} 170 171 172/** 173 * wpa_driver_wext_set_ssid - Set SSID, SIOCSIWESSID 174 * @priv: Pointer to private wext data from wpa_driver_wext_init() 175 * @ssid: SSID 176 * @ssid_len: Length of SSID (0..32) 177 * Returns: 0 on success, -1 on failure 178 */ 179int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len) 180{ 181 struct wpa_driver_wext_data *drv = priv; 182 struct iwreq iwr; 183 int ret = 0; 184 char buf[33]; 185 186 if (ssid_len > 32) 187 return -1; 188 189 os_memset(&iwr, 0, sizeof(iwr)); 190 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 191 /* flags: 1 = ESSID is active, 0 = not (promiscuous) */ 192 iwr.u.essid.flags = (ssid_len != 0); 193 os_memset(buf, 0, sizeof(buf)); 194 os_memcpy(buf, ssid, ssid_len); 195 iwr.u.essid.pointer = (caddr_t) buf; 196 if (drv->we_version_compiled < 21) { 197 /* For historic reasons, set SSID length to include one extra 198 * character, C string nul termination, even though SSID is 199 * really an octet string that should not be presented as a C 200 * string. Some Linux drivers decrement the length by one and 201 * can thus end up missing the last octet of the SSID if the 202 * length is not incremented here. WE-21 changes this to 203 * explicitly require the length _not_ to include nul 204 * termination. */ 205 if (ssid_len) 206 ssid_len++; 207 } 208 iwr.u.essid.length = ssid_len; 209 210 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 211 perror("ioctl[SIOCSIWESSID]"); 212 ret = -1; 213 } 214 215 return ret; 216} 217 218 219/** 220 * wpa_driver_wext_set_freq - Set frequency/channel, SIOCSIWFREQ 221 * @priv: Pointer to private wext data from wpa_driver_wext_init() 222 * @freq: Frequency in MHz 223 * Returns: 0 on success, -1 on failure 224 */ 225int wpa_driver_wext_set_freq(void *priv, int freq) 226{ 227 struct wpa_driver_wext_data *drv = priv; 228 struct iwreq iwr; 229 int ret = 0; 230 231 os_memset(&iwr, 0, sizeof(iwr)); 232 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 233 iwr.u.freq.m = freq * 100000; 234 iwr.u.freq.e = 1; 235 236 if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) { 237 perror("ioctl[SIOCSIWFREQ]"); 238 ret = -1; 239 } 240 241 return ret; 242} 243 244 245static void 246wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) 247{ 248 union wpa_event_data data; 249 250 wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'", 251 custom); 252 253 os_memset(&data, 0, sizeof(data)); 254 /* Host AP driver */ 255 if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 256 data.michael_mic_failure.unicast = 257 os_strstr(custom, " unicast ") != NULL; 258 /* TODO: parse parameters(?) */ 259 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 260 } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) { 261 char *spos; 262 int bytes; 263 u8 *req_ies = NULL, *resp_ies = NULL; 264 265 spos = custom + 17; 266 267 bytes = strspn(spos, "0123456789abcdefABCDEF"); 268 if (!bytes || (bytes & 1)) 269 return; 270 bytes /= 2; 271 272 req_ies = os_malloc(bytes); 273 if (req_ies == NULL || 274 hexstr2bin(spos, req_ies, bytes) < 0) 275 goto done; 276 data.assoc_info.req_ies = req_ies; 277 data.assoc_info.req_ies_len = bytes; 278 279 spos += bytes * 2; 280 281 data.assoc_info.resp_ies = NULL; 282 data.assoc_info.resp_ies_len = 0; 283 284 if (os_strncmp(spos, " RespIEs=", 9) == 0) { 285 spos += 9; 286 287 bytes = strspn(spos, "0123456789abcdefABCDEF"); 288 if (!bytes || (bytes & 1)) 289 goto done; 290 bytes /= 2; 291 292 resp_ies = os_malloc(bytes); 293 if (resp_ies == NULL || 294 hexstr2bin(spos, resp_ies, bytes) < 0) 295 goto done; 296 data.assoc_info.resp_ies = resp_ies; 297 data.assoc_info.resp_ies_len = bytes; 298 } 299 300 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); 301 302 done: 303 os_free(resp_ies); 304 os_free(req_ies); 305#ifdef CONFIG_PEERKEY 306 } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) { 307 if (hwaddr_aton(custom + 17, data.stkstart.peer)) { 308 wpa_printf(MSG_DEBUG, "WEXT: unrecognized " 309 "STKSTART.request '%s'", custom + 17); 310 return; 311 } 312 wpa_supplicant_event(ctx, EVENT_STKSTART, &data); 313#endif /* CONFIG_PEERKEY */ 314#ifdef ANDROID 315 } else if (os_strncmp(custom, "STOP", 4) == 0) { 316 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); 317 } else if (os_strncmp(custom, "START", 5) == 0) { 318 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); 319 } else if (os_strncmp(custom, "HANG", 4) == 0) { 320 wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED"); 321#endif /* ANDROID */ 322 } 323} 324 325 326static int wpa_driver_wext_event_wireless_michaelmicfailure( 327 void *ctx, const char *ev, size_t len) 328{ 329 const struct iw_michaelmicfailure *mic; 330 union wpa_event_data data; 331 332 if (len < sizeof(*mic)) 333 return -1; 334 335 mic = (const struct iw_michaelmicfailure *) ev; 336 337 wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: " 338 "flags=0x%x src_addr=" MACSTR, mic->flags, 339 MAC2STR(mic->src_addr.sa_data)); 340 341 os_memset(&data, 0, sizeof(data)); 342 data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP); 343 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 344 345 return 0; 346} 347 348 349static int wpa_driver_wext_event_wireless_pmkidcand( 350 struct wpa_driver_wext_data *drv, const char *ev, size_t len) 351{ 352 const struct iw_pmkid_cand *cand; 353 union wpa_event_data data; 354 const u8 *addr; 355 356 if (len < sizeof(*cand)) 357 return -1; 358 359 cand = (const struct iw_pmkid_cand *) ev; 360 addr = (const u8 *) cand->bssid.sa_data; 361 362 wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: " 363 "flags=0x%x index=%d bssid=" MACSTR, cand->flags, 364 cand->index, MAC2STR(addr)); 365 366 os_memset(&data, 0, sizeof(data)); 367 os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN); 368 data.pmkid_candidate.index = cand->index; 369 data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH; 370 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data); 371 372 return 0; 373} 374 375 376static int wpa_driver_wext_event_wireless_assocreqie( 377 struct wpa_driver_wext_data *drv, const char *ev, int len) 378{ 379 if (len < 0) 380 return -1; 381 382 wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev, 383 len); 384 os_free(drv->assoc_req_ies); 385 drv->assoc_req_ies = os_malloc(len); 386 if (drv->assoc_req_ies == NULL) { 387 drv->assoc_req_ies_len = 0; 388 return -1; 389 } 390 os_memcpy(drv->assoc_req_ies, ev, len); 391 drv->assoc_req_ies_len = len; 392 393 return 0; 394} 395 396 397static int wpa_driver_wext_event_wireless_assocrespie( 398 struct wpa_driver_wext_data *drv, const char *ev, int len) 399{ 400 if (len < 0) 401 return -1; 402 403 wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev, 404 len); 405 os_free(drv->assoc_resp_ies); 406 drv->assoc_resp_ies = os_malloc(len); 407 if (drv->assoc_resp_ies == NULL) { 408 drv->assoc_resp_ies_len = 0; 409 return -1; 410 } 411 os_memcpy(drv->assoc_resp_ies, ev, len); 412 drv->assoc_resp_ies_len = len; 413 414 return 0; 415} 416 417 418static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv) 419{ 420 union wpa_event_data data; 421 422 if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL) 423 return; 424 425 os_memset(&data, 0, sizeof(data)); 426 if (drv->assoc_req_ies) { 427 data.assoc_info.req_ies = drv->assoc_req_ies; 428 data.assoc_info.req_ies_len = drv->assoc_req_ies_len; 429 } 430 if (drv->assoc_resp_ies) { 431 data.assoc_info.resp_ies = drv->assoc_resp_ies; 432 data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len; 433 } 434 435 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); 436 437 os_free(drv->assoc_req_ies); 438 drv->assoc_req_ies = NULL; 439 os_free(drv->assoc_resp_ies); 440 drv->assoc_resp_ies = NULL; 441} 442 443 444static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv, 445 char *data, int len) 446{ 447 struct iw_event iwe_buf, *iwe = &iwe_buf; 448 char *pos, *end, *custom, *buf; 449 450 pos = data; 451 end = data + len; 452 453 while (pos + IW_EV_LCP_LEN <= end) { 454 /* Event data may be unaligned, so make a local, aligned copy 455 * before processing. */ 456 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 457 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", 458 iwe->cmd, iwe->len); 459 if (iwe->len <= IW_EV_LCP_LEN) 460 return; 461 462 custom = pos + IW_EV_POINT_LEN; 463 if (drv->we_version_compiled > 18 && 464 (iwe->cmd == IWEVMICHAELMICFAILURE || 465 iwe->cmd == IWEVCUSTOM || 466 iwe->cmd == IWEVASSOCREQIE || 467 iwe->cmd == IWEVASSOCRESPIE || 468 iwe->cmd == IWEVPMKIDCAND)) { 469 /* WE-19 removed the pointer from struct iw_point */ 470 char *dpos = (char *) &iwe_buf.u.data.length; 471 int dlen = dpos - (char *) &iwe_buf; 472 os_memcpy(dpos, pos + IW_EV_LCP_LEN, 473 sizeof(struct iw_event) - dlen); 474 } else { 475 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 476 custom += IW_EV_POINT_OFF; 477 } 478 479 switch (iwe->cmd) { 480 case SIOCGIWAP: 481 wpa_printf(MSG_DEBUG, "Wireless event: new AP: " 482 MACSTR, 483 MAC2STR((u8 *) iwe->u.ap_addr.sa_data)); 484 if (is_zero_ether_addr( 485 (const u8 *) iwe->u.ap_addr.sa_data) || 486 os_memcmp(iwe->u.ap_addr.sa_data, 487 "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 488 0) { 489 os_free(drv->assoc_req_ies); 490 drv->assoc_req_ies = NULL; 491 os_free(drv->assoc_resp_ies); 492 drv->assoc_resp_ies = NULL; 493#ifdef ANDROID 494 if (!drv->skip_disconnect) { 495 drv->skip_disconnect = 1; 496#endif 497 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, 498 NULL); 499#ifdef ANDROID 500 } 501#endif 502 } else { 503#ifdef ANDROID 504 drv->skip_disconnect = 0; 505#endif 506 wpa_driver_wext_event_assoc_ies(drv); 507 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, 508 NULL); 509 } 510 break; 511 case IWEVMICHAELMICFAILURE: 512 if (custom + iwe->u.data.length > end) { 513 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 514 "IWEVMICHAELMICFAILURE length"); 515 return; 516 } 517 wpa_driver_wext_event_wireless_michaelmicfailure( 518 drv->ctx, custom, iwe->u.data.length); 519 break; 520 case IWEVCUSTOM: 521 if (custom + iwe->u.data.length > end) { 522 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 523 "IWEVCUSTOM length"); 524 return; 525 } 526 buf = os_malloc(iwe->u.data.length + 1); 527 if (buf == NULL) 528 return; 529 os_memcpy(buf, custom, iwe->u.data.length); 530 buf[iwe->u.data.length] = '\0'; 531 wpa_driver_wext_event_wireless_custom(drv->ctx, buf); 532 os_free(buf); 533 break; 534 case SIOCGIWSCAN: 535 drv->scan_complete_events = 1; 536 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, 537 drv, drv->ctx); 538 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, 539 NULL); 540 break; 541 case IWEVASSOCREQIE: 542 if (custom + iwe->u.data.length > end) { 543 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 544 "IWEVASSOCREQIE length"); 545 return; 546 } 547 wpa_driver_wext_event_wireless_assocreqie( 548 drv, custom, iwe->u.data.length); 549 break; 550 case IWEVASSOCRESPIE: 551 if (custom + iwe->u.data.length > end) { 552 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 553 "IWEVASSOCRESPIE length"); 554 return; 555 } 556 wpa_driver_wext_event_wireless_assocrespie( 557 drv, custom, iwe->u.data.length); 558 break; 559 case IWEVPMKIDCAND: 560 if (custom + iwe->u.data.length > end) { 561 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 562 "IWEVPMKIDCAND length"); 563 return; 564 } 565 wpa_driver_wext_event_wireless_pmkidcand( 566 drv, custom, iwe->u.data.length); 567 break; 568 } 569 570 pos += iwe->len; 571 } 572} 573 574 575static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv, 576 char *buf, size_t len, int del) 577{ 578 union wpa_event_data event; 579 580 os_memset(&event, 0, sizeof(event)); 581 if (len > sizeof(event.interface_status.ifname)) 582 len = sizeof(event.interface_status.ifname) - 1; 583 os_memcpy(event.interface_status.ifname, buf, len); 584 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED : 585 EVENT_INTERFACE_ADDED; 586 587 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s", 588 del ? "DEL" : "NEW", 589 event.interface_status.ifname, 590 del ? "removed" : "added"); 591 592 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) { 593 if (del) 594 drv->if_removed = 1; 595 else 596 drv->if_removed = 0; 597 } 598 599 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 600} 601 602 603static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv, 604 u8 *buf, size_t len) 605{ 606 int attrlen, rta_len; 607 struct rtattr *attr; 608 609 attrlen = len; 610 attr = (struct rtattr *) buf; 611 612 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 613 while (RTA_OK(attr, attrlen)) { 614 if (attr->rta_type == IFLA_IFNAME) { 615 if (os_strcmp(((char *) attr) + rta_len, drv->ifname) 616 == 0) 617 return 1; 618 else 619 break; 620 } 621 attr = RTA_NEXT(attr, attrlen); 622 } 623 624 return 0; 625} 626 627 628static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv, 629 int ifindex, u8 *buf, size_t len) 630{ 631 if (drv->ifindex == ifindex || drv->ifindex2 == ifindex) 632 return 1; 633 634 if (drv->if_removed && wpa_driver_wext_own_ifname(drv, buf, len)) { 635 drv->ifindex = if_nametoindex(drv->ifname); 636 wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed " 637 "interface"); 638 wpa_driver_wext_finish_drv_init(drv); 639 return 1; 640 } 641 642 return 0; 643} 644 645 646static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, 647 u8 *buf, size_t len) 648{ 649 struct wpa_driver_wext_data *drv = ctx; 650 int attrlen, rta_len; 651 struct rtattr *attr; 652 653 if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) { 654 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d", 655 ifi->ifi_index); 656 return; 657 } 658 659 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x " 660 "(%s%s%s%s)", 661 drv->operstate, ifi->ifi_flags, 662 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", 663 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", 664 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", 665 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); 666 667 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { 668 wpa_printf(MSG_DEBUG, "WEXT: Interface down"); 669 drv->if_disabled = 1; 670 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); 671 } 672 673 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) { 674 wpa_printf(MSG_DEBUG, "WEXT: Interface up"); 675 drv->if_disabled = 0; 676 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL); 677 } 678 679 /* 680 * Some drivers send the association event before the operup event--in 681 * this case, lifting operstate in wpa_driver_wext_set_operstate() 682 * fails. This will hit us when wpa_supplicant does not need to do 683 * IEEE 802.1X authentication 684 */ 685 if (drv->operstate == 1 && 686 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP && 687 !(ifi->ifi_flags & IFF_RUNNING)) 688 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 689 -1, IF_OPER_UP); 690 691 attrlen = len; 692 attr = (struct rtattr *) buf; 693 694 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 695 while (RTA_OK(attr, attrlen)) { 696 if (attr->rta_type == IFLA_WIRELESS) { 697 wpa_driver_wext_event_wireless( 698 drv, ((char *) attr) + rta_len, 699 attr->rta_len - rta_len); 700 } else if (attr->rta_type == IFLA_IFNAME) { 701 wpa_driver_wext_event_link(drv, 702 ((char *) attr) + rta_len, 703 attr->rta_len - rta_len, 0); 704 } 705 attr = RTA_NEXT(attr, attrlen); 706 } 707} 708 709 710static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi, 711 u8 *buf, size_t len) 712{ 713 struct wpa_driver_wext_data *drv = ctx; 714 int attrlen, rta_len; 715 struct rtattr *attr; 716 717 attrlen = len; 718 attr = (struct rtattr *) buf; 719 720 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 721 while (RTA_OK(attr, attrlen)) { 722 if (attr->rta_type == IFLA_IFNAME) { 723 wpa_driver_wext_event_link(drv, 724 ((char *) attr) + rta_len, 725 attr->rta_len - rta_len, 1); 726 } 727 attr = RTA_NEXT(attr, attrlen); 728 } 729} 730 731 732static void wpa_driver_wext_rfkill_blocked(void *ctx) 733{ 734 wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); 735 /* 736 * This may be for any interface; use ifdown event to disable 737 * interface. 738 */ 739} 740 741 742static void wpa_driver_wext_rfkill_unblocked(void *ctx) 743{ 744 struct wpa_driver_wext_data *drv = ctx; 745 wpa_printf(MSG_DEBUG, "WEXT: RFKILL unblocked"); 746 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) { 747 wpa_printf(MSG_DEBUG, "WEXT: Could not set interface UP " 748 "after rfkill unblock"); 749 return; 750 } 751 /* rtnetlink ifup handler will report interface as enabled */ 752} 753 754 755static void wext_get_phy_name(struct wpa_driver_wext_data *drv) 756{ 757 /* Find phy (radio) to which this interface belongs */ 758 char buf[90], *pos; 759 int f, rv; 760 761 drv->phyname[0] = '\0'; 762 snprintf(buf, sizeof(buf) - 1, "/sys/class/net/%s/phy80211/name", 763 drv->ifname); 764 f = open(buf, O_RDONLY); 765 if (f < 0) { 766 wpa_printf(MSG_DEBUG, "Could not open file %s: %s", 767 buf, strerror(errno)); 768 return; 769 } 770 771 rv = read(f, drv->phyname, sizeof(drv->phyname) - 1); 772 close(f); 773 if (rv < 0) { 774 wpa_printf(MSG_DEBUG, "Could not read file %s: %s", 775 buf, strerror(errno)); 776 return; 777 } 778 779 drv->phyname[rv] = '\0'; 780 pos = os_strchr(drv->phyname, '\n'); 781 if (pos) 782 *pos = '\0'; 783 wpa_printf(MSG_DEBUG, "wext: interface %s phy: %s", 784 drv->ifname, drv->phyname); 785} 786 787 788/** 789 * wpa_driver_wext_init - Initialize WE driver interface 790 * @ctx: context to be used when calling wpa_supplicant functions, 791 * e.g., wpa_supplicant_event() 792 * @ifname: interface name, e.g., wlan0 793 * Returns: Pointer to private data, %NULL on failure 794 */ 795void * wpa_driver_wext_init(void *ctx, const char *ifname) 796{ 797 struct wpa_driver_wext_data *drv; 798 struct netlink_config *cfg; 799 struct rfkill_config *rcfg; 800 char path[128]; 801 struct stat buf; 802 803 drv = os_zalloc(sizeof(*drv)); 804 if (drv == NULL) 805 return NULL; 806 drv->ctx = ctx; 807 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 808 809 os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname); 810 if (stat(path, &buf) == 0) { 811 wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected"); 812 drv->cfg80211 = 1; 813 wext_get_phy_name(drv); 814 } 815 816 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 817 if (drv->ioctl_sock < 0) { 818 perror("socket(PF_INET,SOCK_DGRAM)"); 819 goto err1; 820 } 821 822 cfg = os_zalloc(sizeof(*cfg)); 823 if (cfg == NULL) 824 goto err1; 825 cfg->ctx = drv; 826 cfg->newlink_cb = wpa_driver_wext_event_rtm_newlink; 827 cfg->dellink_cb = wpa_driver_wext_event_rtm_dellink; 828 drv->netlink = netlink_init(cfg); 829 if (drv->netlink == NULL) { 830 os_free(cfg); 831 goto err2; 832 } 833 834 rcfg = os_zalloc(sizeof(*rcfg)); 835 if (rcfg == NULL) 836 goto err3; 837 rcfg->ctx = drv; 838 os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname)); 839 rcfg->blocked_cb = wpa_driver_wext_rfkill_blocked; 840 rcfg->unblocked_cb = wpa_driver_wext_rfkill_unblocked; 841 drv->rfkill = rfkill_init(rcfg); 842 if (drv->rfkill == NULL) { 843 wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available"); 844 os_free(rcfg); 845 } 846 847 drv->mlme_sock = -1; 848 849#ifdef ANDROID 850 drv->errors = 0; 851 drv->driver_is_started = TRUE; 852 drv->skip_disconnect = 0; 853 drv->bgscan_enabled = 0; 854#endif /* ANDROID */ 855 856 if (wpa_driver_wext_finish_drv_init(drv) < 0) 857 goto err3; 858 859 wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1); 860 861 return drv; 862 863err3: 864 rfkill_deinit(drv->rfkill); 865 netlink_deinit(drv->netlink); 866err2: 867 close(drv->ioctl_sock); 868err1: 869 os_free(drv); 870 return NULL; 871} 872 873 874static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx) 875{ 876 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); 877} 878 879 880static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) 881{ 882 int send_rfkill_event = 0; 883 884 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) { 885 if (rfkill_is_blocked(drv->rfkill)) { 886 wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable " 887 "interface '%s' due to rfkill", 888 drv->ifname); 889 drv->if_disabled = 1; 890 send_rfkill_event = 1; 891 } else { 892 wpa_printf(MSG_ERROR, "WEXT: Could not set " 893 "interface '%s' UP", drv->ifname); 894 return -1; 895 } 896 } 897 898 /* 899 * Make sure that the driver does not have any obsolete PMKID entries. 900 */ 901 wpa_driver_wext_flush_pmkid(drv); 902 903 if (wpa_driver_wext_set_mode(drv, 0) < 0) { 904 wpa_printf(MSG_DEBUG, "Could not configure driver to use " 905 "managed mode"); 906 /* Try to use it anyway */ 907 } 908 909 wpa_driver_wext_get_range(drv); 910 911 /* 912 * Unlock the driver's BSSID and force to a random SSID to clear any 913 * previous association the driver might have when the supplicant 914 * starts up. 915 */ 916 wpa_driver_wext_disconnect(drv); 917 918 drv->ifindex = if_nametoindex(drv->ifname); 919 920 if (os_strncmp(drv->ifname, "wlan", 4) == 0) { 921 /* 922 * Host AP driver may use both wlan# and wifi# interface in 923 * wireless events. Since some of the versions included WE-18 924 * support, let's add the alternative ifindex also from 925 * driver_wext.c for the time being. This may be removed at 926 * some point once it is believed that old versions of the 927 * driver are not in use anymore. 928 */ 929 char ifname2[IFNAMSIZ + 1]; 930 os_strlcpy(ifname2, drv->ifname, sizeof(ifname2)); 931 os_memcpy(ifname2, "wifi", 4); 932 wpa_driver_wext_alternative_ifindex(drv, ifname2); 933 } 934 935 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 936 1, IF_OPER_DORMANT); 937 938 if (send_rfkill_event) { 939 eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill, 940 drv, drv->ctx); 941 } 942 943 return 0; 944} 945 946 947/** 948 * wpa_driver_wext_deinit - Deinitialize WE driver interface 949 * @priv: Pointer to private wext data from wpa_driver_wext_init() 950 * 951 * Shut down driver interface and processing of driver events. Free 952 * private data buffer if one was allocated in wpa_driver_wext_init(). 953 */ 954void wpa_driver_wext_deinit(void *priv) 955{ 956 struct wpa_driver_wext_data *drv = priv; 957 958 wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0); 959 960 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); 961 962 /* 963 * Clear possibly configured driver parameters in order to make it 964 * easier to use the driver after wpa_supplicant has been terminated. 965 */ 966 wpa_driver_wext_disconnect(drv); 967 968 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP); 969 netlink_deinit(drv->netlink); 970 rfkill_deinit(drv->rfkill); 971 972 if (drv->mlme_sock >= 0) 973 eloop_unregister_read_sock(drv->mlme_sock); 974 975 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); 976 977 close(drv->ioctl_sock); 978 if (drv->mlme_sock >= 0) 979 close(drv->mlme_sock); 980 os_free(drv->assoc_req_ies); 981 os_free(drv->assoc_resp_ies); 982 os_free(drv); 983} 984 985 986/** 987 * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion 988 * @eloop_ctx: Unused 989 * @timeout_ctx: ctx argument given to wpa_driver_wext_init() 990 * 991 * This function can be used as registered timeout when starting a scan to 992 * generate a scan completed event if the driver does not report this. 993 */ 994void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx) 995{ 996 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 997 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 998} 999 1000 1001/** 1002 * wpa_driver_wext_scan - Request the driver to initiate scan 1003 * @priv: Pointer to private wext data from wpa_driver_wext_init() 1004 * @param: Scan parameters (specific SSID to scan for (ProbeReq), etc.) 1005 * Returns: 0 on success, -1 on failure 1006 */ 1007int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params) 1008{ 1009 struct wpa_driver_wext_data *drv = priv; 1010 struct iwreq iwr; 1011 int ret = 0, timeout; 1012 struct iw_scan_req req; 1013 const u8 *ssid = params->ssids[0].ssid; 1014 size_t ssid_len = params->ssids[0].ssid_len; 1015 1016#ifdef ANDROID 1017 if (drv->capa.max_scan_ssids > 1) { 1018 ret = wpa_driver_wext_combo_scan(priv, params); 1019 goto scan_out; 1020 } 1021#endif 1022 1023 if (ssid_len > IW_ESSID_MAX_SIZE) { 1024 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)", 1025 __FUNCTION__, (unsigned long) ssid_len); 1026 return -1; 1027 } 1028 1029 os_memset(&iwr, 0, sizeof(iwr)); 1030 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1031 1032 if (ssid && ssid_len) { 1033 os_memset(&req, 0, sizeof(req)); 1034 req.essid_len = ssid_len; 1035 req.bssid.sa_family = ARPHRD_ETHER; 1036 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN); 1037 os_memcpy(req.essid, ssid, ssid_len); 1038 iwr.u.data.pointer = (caddr_t) &req; 1039 iwr.u.data.length = sizeof(req); 1040 iwr.u.data.flags = IW_SCAN_THIS_ESSID; 1041 } 1042 1043 if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) { 1044 perror("ioctl[SIOCSIWSCAN]"); 1045 ret = -1; 1046 } 1047 1048#ifdef ANDROID 1049scan_out: 1050#endif 1051 /* Not all drivers generate "scan completed" wireless event, so try to 1052 * read results after a timeout. */ 1053 timeout = 10; 1054 if (drv->scan_complete_events) { 1055 /* 1056 * The driver seems to deliver SIOCGIWSCAN events to notify 1057 * when scan is complete, so use longer timeout to avoid race 1058 * conditions with scanning and following association request. 1059 */ 1060 timeout = 30; 1061 } 1062 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d " 1063 "seconds", ret, timeout); 1064 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); 1065 eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv, 1066 drv->ctx); 1067 1068 return ret; 1069} 1070 1071 1072static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv, 1073 size_t *len) 1074{ 1075 struct iwreq iwr; 1076 u8 *res_buf; 1077 size_t res_buf_len; 1078 1079 res_buf_len = IW_SCAN_MAX_DATA; 1080 for (;;) { 1081 res_buf = os_malloc(res_buf_len); 1082 if (res_buf == NULL) 1083 return NULL; 1084 os_memset(&iwr, 0, sizeof(iwr)); 1085 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1086 iwr.u.data.pointer = res_buf; 1087 iwr.u.data.length = res_buf_len; 1088 1089 if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0) 1090 break; 1091 1092 if (errno == E2BIG && res_buf_len < 65535) { 1093 os_free(res_buf); 1094 res_buf = NULL; 1095 res_buf_len *= 2; 1096 if (res_buf_len > 65535) 1097 res_buf_len = 65535; /* 16-bit length field */ 1098 wpa_printf(MSG_DEBUG, "Scan results did not fit - " 1099 "trying larger buffer (%lu bytes)", 1100 (unsigned long) res_buf_len); 1101 } else { 1102 perror("ioctl[SIOCGIWSCAN]"); 1103 os_free(res_buf); 1104 return NULL; 1105 } 1106 } 1107 1108 if (iwr.u.data.length > res_buf_len) { 1109 os_free(res_buf); 1110 return NULL; 1111 } 1112 *len = iwr.u.data.length; 1113 1114 return res_buf; 1115} 1116 1117 1118/* 1119 * Data structure for collecting WEXT scan results. This is needed to allow 1120 * the various methods of reporting IEs to be combined into a single IE buffer. 1121 */ 1122struct wext_scan_data { 1123 struct wpa_scan_res res; 1124 u8 *ie; 1125 size_t ie_len; 1126 u8 ssid[32]; 1127 size_t ssid_len; 1128 int maxrate; 1129}; 1130 1131 1132static void wext_get_scan_mode(struct iw_event *iwe, 1133 struct wext_scan_data *res) 1134{ 1135 if (iwe->u.mode == IW_MODE_ADHOC) 1136 res->res.caps |= IEEE80211_CAP_IBSS; 1137 else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA) 1138 res->res.caps |= IEEE80211_CAP_ESS; 1139} 1140 1141 1142static void wext_get_scan_ssid(struct iw_event *iwe, 1143 struct wext_scan_data *res, char *custom, 1144 char *end) 1145{ 1146 int ssid_len = iwe->u.essid.length; 1147 if (custom + ssid_len > end) 1148 return; 1149 if (iwe->u.essid.flags && 1150 ssid_len > 0 && 1151 ssid_len <= IW_ESSID_MAX_SIZE) { 1152 os_memcpy(res->ssid, custom, ssid_len); 1153 res->ssid_len = ssid_len; 1154 } 1155} 1156 1157 1158static void wext_get_scan_freq(struct iw_event *iwe, 1159 struct wext_scan_data *res) 1160{ 1161 int divi = 1000000, i; 1162 1163 if (iwe->u.freq.e == 0) { 1164 /* 1165 * Some drivers do not report frequency, but a channel. 1166 * Try to map this to frequency by assuming they are using 1167 * IEEE 802.11b/g. But don't overwrite a previously parsed 1168 * frequency if the driver sends both frequency and channel, 1169 * since the driver may be sending an A-band channel that we 1170 * don't handle here. 1171 */ 1172 1173 if (res->res.freq) 1174 return; 1175 1176 if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) { 1177 res->res.freq = 2407 + 5 * iwe->u.freq.m; 1178 return; 1179 } else if (iwe->u.freq.m == 14) { 1180 res->res.freq = 2484; 1181 return; 1182 } 1183 } 1184 1185 if (iwe->u.freq.e > 6) { 1186 wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID=" 1187 MACSTR " m=%d e=%d)", 1188 MAC2STR(res->res.bssid), iwe->u.freq.m, 1189 iwe->u.freq.e); 1190 return; 1191 } 1192 1193 for (i = 0; i < iwe->u.freq.e; i++) 1194 divi /= 10; 1195 res->res.freq = iwe->u.freq.m / divi; 1196} 1197 1198 1199static void wext_get_scan_qual(struct wpa_driver_wext_data *drv, 1200 struct iw_event *iwe, 1201 struct wext_scan_data *res) 1202{ 1203 res->res.qual = iwe->u.qual.qual; 1204 res->res.noise = iwe->u.qual.noise; 1205 res->res.level = iwe->u.qual.level; 1206 if (iwe->u.qual.updated & IW_QUAL_QUAL_INVALID) 1207 res->res.flags |= WPA_SCAN_QUAL_INVALID; 1208 if (iwe->u.qual.updated & IW_QUAL_LEVEL_INVALID) 1209 res->res.flags |= WPA_SCAN_LEVEL_INVALID; 1210 if (iwe->u.qual.updated & IW_QUAL_NOISE_INVALID) 1211 res->res.flags |= WPA_SCAN_NOISE_INVALID; 1212 if (iwe->u.qual.updated & IW_QUAL_DBM) 1213 res->res.flags |= WPA_SCAN_LEVEL_DBM; 1214 if ((iwe->u.qual.updated & IW_QUAL_DBM) || 1215 ((iwe->u.qual.level != 0) && 1216 (iwe->u.qual.level > drv->max_level))) { 1217 if (iwe->u.qual.level >= 64) 1218 res->res.level -= 0x100; 1219 if (iwe->u.qual.noise >= 64) 1220 res->res.noise -= 0x100; 1221 } 1222} 1223 1224 1225static void wext_get_scan_encode(struct iw_event *iwe, 1226 struct wext_scan_data *res) 1227{ 1228 if (!(iwe->u.data.flags & IW_ENCODE_DISABLED)) 1229 res->res.caps |= IEEE80211_CAP_PRIVACY; 1230} 1231 1232 1233static void wext_get_scan_rate(struct iw_event *iwe, 1234 struct wext_scan_data *res, char *pos, 1235 char *end) 1236{ 1237 int maxrate; 1238 char *custom = pos + IW_EV_LCP_LEN; 1239 struct iw_param p; 1240 size_t clen; 1241 1242 clen = iwe->len; 1243 if (custom + clen > end) 1244 return; 1245 maxrate = 0; 1246 while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) { 1247 /* Note: may be misaligned, make a local, aligned copy */ 1248 os_memcpy(&p, custom, sizeof(struct iw_param)); 1249 if (p.value > maxrate) 1250 maxrate = p.value; 1251 clen -= sizeof(struct iw_param); 1252 custom += sizeof(struct iw_param); 1253 } 1254 1255 /* Convert the maxrate from WE-style (b/s units) to 1256 * 802.11 rates (500000 b/s units). 1257 */ 1258 res->maxrate = maxrate / 500000; 1259} 1260 1261 1262static void wext_get_scan_iwevgenie(struct iw_event *iwe, 1263 struct wext_scan_data *res, char *custom, 1264 char *end) 1265{ 1266 char *genie, *gpos, *gend; 1267 u8 *tmp; 1268 1269 if (iwe->u.data.length == 0) 1270 return; 1271 1272 gpos = genie = custom; 1273 gend = genie + iwe->u.data.length; 1274 if (gend > end) { 1275 wpa_printf(MSG_INFO, "IWEVGENIE overflow"); 1276 return; 1277 } 1278 1279 tmp = os_realloc(res->ie, res->ie_len + gend - gpos); 1280 if (tmp == NULL) 1281 return; 1282 os_memcpy(tmp + res->ie_len, gpos, gend - gpos); 1283 res->ie = tmp; 1284 res->ie_len += gend - gpos; 1285} 1286 1287 1288static void wext_get_scan_custom(struct iw_event *iwe, 1289 struct wext_scan_data *res, char *custom, 1290 char *end) 1291{ 1292 size_t clen; 1293 u8 *tmp; 1294 1295 clen = iwe->u.data.length; 1296 if (custom + clen > end) 1297 return; 1298 1299 if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) { 1300 char *spos; 1301 int bytes; 1302 spos = custom + 7; 1303 bytes = custom + clen - spos; 1304 if (bytes & 1 || bytes == 0) 1305 return; 1306 bytes /= 2; 1307 tmp = os_realloc(res->ie, res->ie_len + bytes); 1308 if (tmp == NULL) 1309 return; 1310 res->ie = tmp; 1311 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0) 1312 return; 1313 res->ie_len += bytes; 1314 } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) { 1315 char *spos; 1316 int bytes; 1317 spos = custom + 7; 1318 bytes = custom + clen - spos; 1319 if (bytes & 1 || bytes == 0) 1320 return; 1321 bytes /= 2; 1322 tmp = os_realloc(res->ie, res->ie_len + bytes); 1323 if (tmp == NULL) 1324 return; 1325 res->ie = tmp; 1326 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0) 1327 return; 1328 res->ie_len += bytes; 1329 } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) { 1330 char *spos; 1331 int bytes; 1332 u8 bin[8]; 1333 spos = custom + 4; 1334 bytes = custom + clen - spos; 1335 if (bytes != 16) { 1336 wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes); 1337 return; 1338 } 1339 bytes /= 2; 1340 if (hexstr2bin(spos, bin, bytes) < 0) { 1341 wpa_printf(MSG_DEBUG, "WEXT: Invalid TSF value"); 1342 return; 1343 } 1344 res->res.tsf += WPA_GET_BE64(bin); 1345 } 1346} 1347 1348 1349static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd) 1350{ 1351 return drv->we_version_compiled > 18 && 1352 (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE || 1353 cmd == IWEVGENIE || cmd == IWEVCUSTOM); 1354} 1355 1356 1357static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res, 1358 struct wext_scan_data *data) 1359{ 1360 struct wpa_scan_res **tmp; 1361 struct wpa_scan_res *r; 1362 size_t extra_len; 1363 u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL; 1364 1365 /* Figure out whether we need to fake any IEs */ 1366 pos = data->ie; 1367 end = pos + data->ie_len; 1368 while (pos && pos + 1 < end) { 1369 if (pos + 2 + pos[1] > end) 1370 break; 1371 if (pos[0] == WLAN_EID_SSID) 1372 ssid_ie = pos; 1373 else if (pos[0] == WLAN_EID_SUPP_RATES) 1374 rate_ie = pos; 1375 else if (pos[0] == WLAN_EID_EXT_SUPP_RATES) 1376 rate_ie = pos; 1377 pos += 2 + pos[1]; 1378 } 1379 1380 extra_len = 0; 1381 if (ssid_ie == NULL) 1382 extra_len += 2 + data->ssid_len; 1383 if (rate_ie == NULL && data->maxrate) 1384 extra_len += 3; 1385 1386 r = os_zalloc(sizeof(*r) + extra_len + data->ie_len); 1387 if (r == NULL) 1388 return; 1389 os_memcpy(r, &data->res, sizeof(*r)); 1390 r->ie_len = extra_len + data->ie_len; 1391 pos = (u8 *) (r + 1); 1392 if (ssid_ie == NULL) { 1393 /* 1394 * Generate a fake SSID IE since the driver did not report 1395 * a full IE list. 1396 */ 1397 *pos++ = WLAN_EID_SSID; 1398 *pos++ = data->ssid_len; 1399 os_memcpy(pos, data->ssid, data->ssid_len); 1400 pos += data->ssid_len; 1401 } 1402 if (rate_ie == NULL && data->maxrate) { 1403 /* 1404 * Generate a fake Supported Rates IE since the driver did not 1405 * report a full IE list. 1406 */ 1407 *pos++ = WLAN_EID_SUPP_RATES; 1408 *pos++ = 1; 1409 *pos++ = data->maxrate; 1410 } 1411 if (data->ie) 1412 os_memcpy(pos, data->ie, data->ie_len); 1413 1414 tmp = os_realloc(res->res, 1415 (res->num + 1) * sizeof(struct wpa_scan_res *)); 1416 if (tmp == NULL) { 1417 os_free(r); 1418 return; 1419 } 1420 tmp[res->num++] = r; 1421 res->res = tmp; 1422} 1423 1424 1425/** 1426 * wpa_driver_wext_get_scan_results - Fetch the latest scan results 1427 * @priv: Pointer to private wext data from wpa_driver_wext_init() 1428 * Returns: Scan results on success, -1 on failure 1429 */ 1430struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv) 1431{ 1432 struct wpa_driver_wext_data *drv = priv; 1433 size_t len; 1434 int first; 1435 u8 *res_buf; 1436 struct iw_event iwe_buf, *iwe = &iwe_buf; 1437 char *pos, *end, *custom; 1438 struct wpa_scan_results *res; 1439 struct wext_scan_data data; 1440 1441 res_buf = wpa_driver_wext_giwscan(drv, &len); 1442 if (res_buf == NULL) 1443 return NULL; 1444 1445 first = 1; 1446 1447 res = os_zalloc(sizeof(*res)); 1448 if (res == NULL) { 1449 os_free(res_buf); 1450 return NULL; 1451 } 1452 1453 pos = (char *) res_buf; 1454 end = (char *) res_buf + len; 1455 os_memset(&data, 0, sizeof(data)); 1456 1457 while (pos + IW_EV_LCP_LEN <= end) { 1458 /* Event data may be unaligned, so make a local, aligned copy 1459 * before processing. */ 1460 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 1461 if (iwe->len <= IW_EV_LCP_LEN) 1462 break; 1463 1464 custom = pos + IW_EV_POINT_LEN; 1465 if (wext_19_iw_point(drv, iwe->cmd)) { 1466 /* WE-19 removed the pointer from struct iw_point */ 1467 char *dpos = (char *) &iwe_buf.u.data.length; 1468 int dlen = dpos - (char *) &iwe_buf; 1469 os_memcpy(dpos, pos + IW_EV_LCP_LEN, 1470 sizeof(struct iw_event) - dlen); 1471 } else { 1472 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 1473 custom += IW_EV_POINT_OFF; 1474 } 1475 1476 switch (iwe->cmd) { 1477 case SIOCGIWAP: 1478 if (!first) 1479 wpa_driver_wext_add_scan_entry(res, &data); 1480 first = 0; 1481 os_free(data.ie); 1482 os_memset(&data, 0, sizeof(data)); 1483 os_memcpy(data.res.bssid, 1484 iwe->u.ap_addr.sa_data, ETH_ALEN); 1485 break; 1486 case SIOCGIWMODE: 1487 wext_get_scan_mode(iwe, &data); 1488 break; 1489 case SIOCGIWESSID: 1490 wext_get_scan_ssid(iwe, &data, custom, end); 1491 break; 1492 case SIOCGIWFREQ: 1493 wext_get_scan_freq(iwe, &data); 1494 break; 1495 case IWEVQUAL: 1496 wext_get_scan_qual(drv, iwe, &data); 1497 break; 1498 case SIOCGIWENCODE: 1499 wext_get_scan_encode(iwe, &data); 1500 break; 1501 case SIOCGIWRATE: 1502 wext_get_scan_rate(iwe, &data, pos, end); 1503 break; 1504 case IWEVGENIE: 1505 wext_get_scan_iwevgenie(iwe, &data, custom, end); 1506 break; 1507 case IWEVCUSTOM: 1508 wext_get_scan_custom(iwe, &data, custom, end); 1509 break; 1510 } 1511 1512 pos += iwe->len; 1513 } 1514 os_free(res_buf); 1515 res_buf = NULL; 1516 if (!first) 1517 wpa_driver_wext_add_scan_entry(res, &data); 1518 os_free(data.ie); 1519 1520 wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)", 1521 (unsigned long) len, (unsigned long) res->num); 1522 1523 return res; 1524} 1525 1526 1527static int wpa_driver_wext_get_range(void *priv) 1528{ 1529 struct wpa_driver_wext_data *drv = priv; 1530 struct iw_range *range; 1531 struct iwreq iwr; 1532 int minlen; 1533 size_t buflen; 1534 1535 /* 1536 * Use larger buffer than struct iw_range in order to allow the 1537 * structure to grow in the future. 1538 */ 1539 buflen = sizeof(struct iw_range) + 500; 1540 range = os_zalloc(buflen); 1541 if (range == NULL) 1542 return -1; 1543 1544 os_memset(&iwr, 0, sizeof(iwr)); 1545 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1546 iwr.u.data.pointer = (caddr_t) range; 1547 iwr.u.data.length = buflen; 1548 1549 minlen = ((char *) &range->enc_capa) - (char *) range + 1550 sizeof(range->enc_capa); 1551 1552 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1553 perror("ioctl[SIOCGIWRANGE]"); 1554 os_free(range); 1555 return -1; 1556 } else if (iwr.u.data.length >= minlen && 1557 range->we_version_compiled >= 18) { 1558 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1559 "WE(source)=%d enc_capa=0x%x", 1560 range->we_version_compiled, 1561 range->we_version_source, 1562 range->enc_capa); 1563 drv->has_capability = 1; 1564 drv->we_version_compiled = range->we_version_compiled; 1565 if (range->enc_capa & IW_ENC_CAPA_WPA) { 1566 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1567 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 1568 } 1569 if (range->enc_capa & IW_ENC_CAPA_WPA2) { 1570 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1571 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 1572 } 1573 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | 1574 WPA_DRIVER_CAPA_ENC_WEP104; 1575 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) 1576 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 1577 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) 1578 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 1579 if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) 1580 drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; 1581 drv->capa.auth = WPA_DRIVER_AUTH_OPEN | 1582 WPA_DRIVER_AUTH_SHARED | 1583 WPA_DRIVER_AUTH_LEAP; 1584#ifdef ANDROID 1585 drv->capa.max_scan_ssids = WEXT_CSCAN_AMOUNT; 1586#else 1587 drv->capa.max_scan_ssids = 1; 1588#endif 1589 1590 wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x " 1591 "flags 0x%x", 1592 drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags); 1593 } else { 1594 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - " 1595 "assuming WPA is not supported"); 1596 } 1597 1598 drv->max_level = range->max_qual.level; 1599 1600 os_free(range); 1601 return 0; 1602} 1603 1604 1605static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv, 1606 const u8 *psk) 1607{ 1608 struct iw_encode_ext *ext; 1609 struct iwreq iwr; 1610 int ret; 1611 1612 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1613 1614 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) 1615 return 0; 1616 1617 if (!psk) 1618 return 0; 1619 1620 os_memset(&iwr, 0, sizeof(iwr)); 1621 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1622 1623 ext = os_zalloc(sizeof(*ext) + PMK_LEN); 1624 if (ext == NULL) 1625 return -1; 1626 1627 iwr.u.encoding.pointer = (caddr_t) ext; 1628 iwr.u.encoding.length = sizeof(*ext) + PMK_LEN; 1629 ext->key_len = PMK_LEN; 1630 os_memcpy(&ext->key, psk, ext->key_len); 1631 ext->alg = IW_ENCODE_ALG_PMK; 1632 1633 ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr); 1634 if (ret < 0) 1635 perror("ioctl[SIOCSIWENCODEEXT] PMK"); 1636 os_free(ext); 1637 1638 return ret; 1639} 1640 1641 1642static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg, 1643 const u8 *addr, int key_idx, 1644 int set_tx, const u8 *seq, 1645 size_t seq_len, 1646 const u8 *key, size_t key_len) 1647{ 1648 struct wpa_driver_wext_data *drv = priv; 1649 struct iwreq iwr; 1650 int ret = 0; 1651 struct iw_encode_ext *ext; 1652 1653 if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) { 1654 wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu", 1655 __FUNCTION__, (unsigned long) seq_len); 1656 return -1; 1657 } 1658 1659 ext = os_zalloc(sizeof(*ext) + key_len); 1660 if (ext == NULL) 1661 return -1; 1662 os_memset(&iwr, 0, sizeof(iwr)); 1663 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1664 iwr.u.encoding.flags = key_idx + 1; 1665 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1666 if (alg == WPA_ALG_NONE) 1667 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 1668 iwr.u.encoding.pointer = (caddr_t) ext; 1669 iwr.u.encoding.length = sizeof(*ext) + key_len; 1670 1671 if (addr == NULL || is_broadcast_ether_addr(addr)) 1672 ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY; 1673 if (set_tx) 1674 ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY; 1675 1676 ext->addr.sa_family = ARPHRD_ETHER; 1677 if (addr) 1678 os_memcpy(ext->addr.sa_data, addr, ETH_ALEN); 1679 else 1680 os_memset(ext->addr.sa_data, 0xff, ETH_ALEN); 1681 if (key && key_len) { 1682 os_memcpy(ext + 1, key, key_len); 1683 ext->key_len = key_len; 1684 } 1685 switch (alg) { 1686 case WPA_ALG_NONE: 1687 ext->alg = IW_ENCODE_ALG_NONE; 1688 break; 1689 case WPA_ALG_WEP: 1690 ext->alg = IW_ENCODE_ALG_WEP; 1691 break; 1692 case WPA_ALG_TKIP: 1693 ext->alg = IW_ENCODE_ALG_TKIP; 1694 break; 1695 case WPA_ALG_CCMP: 1696 ext->alg = IW_ENCODE_ALG_CCMP; 1697 break; 1698 case WPA_ALG_PMK: 1699 ext->alg = IW_ENCODE_ALG_PMK; 1700 break; 1701#ifdef CONFIG_IEEE80211W 1702 case WPA_ALG_IGTK: 1703 ext->alg = IW_ENCODE_ALG_AES_CMAC; 1704 break; 1705#endif /* CONFIG_IEEE80211W */ 1706 default: 1707 wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d", 1708 __FUNCTION__, alg); 1709 os_free(ext); 1710 return -1; 1711 } 1712 1713 if (seq && seq_len) { 1714 ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID; 1715 os_memcpy(ext->rx_seq, seq, seq_len); 1716 } 1717 1718 if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) { 1719 ret = errno == EOPNOTSUPP ? -2 : -1; 1720 if (errno == ENODEV) { 1721 /* 1722 * ndiswrapper seems to be returning incorrect error 1723 * code.. */ 1724 ret = -2; 1725 } 1726 1727 perror("ioctl[SIOCSIWENCODEEXT]"); 1728 } 1729 1730 os_free(ext); 1731 return ret; 1732} 1733 1734 1735/** 1736 * wpa_driver_wext_set_key - Configure encryption key 1737 * @priv: Pointer to private wext data from wpa_driver_wext_init() 1738 * @priv: Private driver interface data 1739 * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, 1740 * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key. 1741 * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for 1742 * broadcast/default keys 1743 * @key_idx: key index (0..3), usually 0 for unicast keys 1744 * @set_tx: Configure this key as the default Tx key (only used when 1745 * driver does not support separate unicast/individual key 1746 * @seq: Sequence number/packet number, seq_len octets, the next 1747 * packet number to be used for in replay protection; configured 1748 * for Rx keys (in most cases, this is only used with broadcast 1749 * keys and set to zero for unicast keys) 1750 * @seq_len: Length of the seq, depends on the algorithm: 1751 * TKIP: 6 octets, CCMP: 6 octets 1752 * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 1753 * 8-byte Rx Mic Key 1754 * @key_len: Length of the key buffer in octets (WEP: 5 or 13, 1755 * TKIP: 32, CCMP: 16) 1756 * Returns: 0 on success, -1 on failure 1757 * 1758 * This function uses SIOCSIWENCODEEXT by default, but tries to use 1759 * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. 1760 */ 1761int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg, 1762 const u8 *addr, int key_idx, 1763 int set_tx, const u8 *seq, size_t seq_len, 1764 const u8 *key, size_t key_len) 1765{ 1766 struct wpa_driver_wext_data *drv = priv; 1767 struct iwreq iwr; 1768 int ret = 0; 1769 1770 wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " 1771 "key_len=%lu", 1772 __FUNCTION__, alg, key_idx, set_tx, 1773 (unsigned long) seq_len, (unsigned long) key_len); 1774 1775 ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx, 1776 seq, seq_len, key, key_len); 1777 if (ret == 0) 1778 return 0; 1779 1780 if (ret == -2 && 1781 (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) { 1782 wpa_printf(MSG_DEBUG, "Driver did not support " 1783 "SIOCSIWENCODEEXT, trying SIOCSIWENCODE"); 1784 ret = 0; 1785 } else { 1786 wpa_printf(MSG_DEBUG, "Driver did not support " 1787 "SIOCSIWENCODEEXT"); 1788 return ret; 1789 } 1790 1791 os_memset(&iwr, 0, sizeof(iwr)); 1792 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1793 iwr.u.encoding.flags = key_idx + 1; 1794 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1795 if (alg == WPA_ALG_NONE) 1796 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 1797 iwr.u.encoding.pointer = (caddr_t) key; 1798 iwr.u.encoding.length = key_len; 1799 1800 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 1801 perror("ioctl[SIOCSIWENCODE]"); 1802 ret = -1; 1803 } 1804 1805 if (set_tx && alg != WPA_ALG_NONE) { 1806 os_memset(&iwr, 0, sizeof(iwr)); 1807 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1808 iwr.u.encoding.flags = key_idx + 1; 1809 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1810 iwr.u.encoding.pointer = (caddr_t) NULL; 1811 iwr.u.encoding.length = 0; 1812 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 1813 perror("ioctl[SIOCSIWENCODE] (set_tx)"); 1814 ret = -1; 1815 } 1816 } 1817 1818 return ret; 1819} 1820 1821 1822static int wpa_driver_wext_set_countermeasures(void *priv, 1823 int enabled) 1824{ 1825 struct wpa_driver_wext_data *drv = priv; 1826 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1827 return wpa_driver_wext_set_auth_param(drv, 1828 IW_AUTH_TKIP_COUNTERMEASURES, 1829 enabled); 1830} 1831 1832 1833static int wpa_driver_wext_set_drop_unencrypted(void *priv, 1834 int enabled) 1835{ 1836 struct wpa_driver_wext_data *drv = priv; 1837 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1838 drv->use_crypt = enabled; 1839 return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, 1840 enabled); 1841} 1842 1843 1844static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv, 1845 const u8 *addr, int cmd, int reason_code) 1846{ 1847 struct iwreq iwr; 1848 struct iw_mlme mlme; 1849 int ret = 0; 1850 1851 os_memset(&iwr, 0, sizeof(iwr)); 1852 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1853 os_memset(&mlme, 0, sizeof(mlme)); 1854 mlme.cmd = cmd; 1855 mlme.reason_code = reason_code; 1856 mlme.addr.sa_family = ARPHRD_ETHER; 1857 os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN); 1858 iwr.u.data.pointer = (caddr_t) &mlme; 1859 iwr.u.data.length = sizeof(mlme); 1860 1861 if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) { 1862 perror("ioctl[SIOCSIWMLME]"); 1863 ret = -1; 1864 } 1865 1866 return ret; 1867} 1868 1869 1870static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv) 1871{ 1872 struct iwreq iwr; 1873 const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; 1874#ifndef ANDROID 1875 u8 ssid[32]; 1876 int i; 1877#endif /* ANDROID */ 1878 1879 /* 1880 * Only force-disconnect when the card is in infrastructure mode, 1881 * otherwise the driver might interpret the cleared BSSID and random 1882 * SSID as an attempt to create a new ad-hoc network. 1883 */ 1884 os_memset(&iwr, 0, sizeof(iwr)); 1885 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1886 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { 1887 perror("ioctl[SIOCGIWMODE]"); 1888 iwr.u.mode = IW_MODE_INFRA; 1889 } 1890 1891 if (iwr.u.mode == IW_MODE_INFRA) { 1892 /* Clear the BSSID selection */ 1893 if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0) { 1894 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear BSSID " 1895 "selection on disconnect"); 1896 } 1897 1898#ifndef ANDROID 1899 if (drv->cfg80211) { 1900 /* 1901 * cfg80211 supports SIOCSIWMLME commands, so there is 1902 * no need for the random SSID hack, but clear the 1903 * SSID. 1904 */ 1905 if (wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) { 1906 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear " 1907 "SSID on disconnect"); 1908 } 1909 return; 1910 } 1911 1912 /* 1913 * Set a random SSID to make sure the driver will not be trying 1914 * to associate with something even if it does not understand 1915 * SIOCSIWMLME commands (or tries to associate automatically 1916 * after deauth/disassoc). 1917 */ 1918 for (i = 0; i < 32; i++) 1919 ssid[i] = rand() & 0xFF; 1920 if (wpa_driver_wext_set_ssid(drv, ssid, 32) < 0) { 1921 wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus " 1922 "SSID to disconnect"); 1923 } 1924#endif /* ANDROID */ 1925 } 1926} 1927 1928 1929static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr, 1930 int reason_code) 1931{ 1932 struct wpa_driver_wext_data *drv = priv; 1933 int ret; 1934 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1935 ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code); 1936 wpa_driver_wext_disconnect(drv); 1937 return ret; 1938} 1939 1940 1941static int wpa_driver_wext_disassociate(void *priv, const u8 *addr, 1942 int reason_code) 1943{ 1944 struct wpa_driver_wext_data *drv = priv; 1945 int ret; 1946 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1947 ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code); 1948 wpa_driver_wext_disconnect(drv); 1949 return ret; 1950} 1951 1952 1953static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie, 1954 size_t ie_len) 1955{ 1956 struct wpa_driver_wext_data *drv = priv; 1957 struct iwreq iwr; 1958 int ret = 0; 1959 1960 os_memset(&iwr, 0, sizeof(iwr)); 1961 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1962 iwr.u.data.pointer = (caddr_t) ie; 1963 iwr.u.data.length = ie_len; 1964 1965 if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) { 1966 perror("ioctl[SIOCSIWGENIE]"); 1967 ret = -1; 1968 } 1969 1970 return ret; 1971} 1972 1973 1974int wpa_driver_wext_cipher2wext(int cipher) 1975{ 1976 switch (cipher) { 1977 case CIPHER_NONE: 1978 return IW_AUTH_CIPHER_NONE; 1979 case CIPHER_WEP40: 1980 return IW_AUTH_CIPHER_WEP40; 1981 case CIPHER_TKIP: 1982 return IW_AUTH_CIPHER_TKIP; 1983 case CIPHER_CCMP: 1984 return IW_AUTH_CIPHER_CCMP; 1985 case CIPHER_WEP104: 1986 return IW_AUTH_CIPHER_WEP104; 1987 default: 1988 return 0; 1989 } 1990} 1991 1992 1993int wpa_driver_wext_keymgmt2wext(int keymgmt) 1994{ 1995 switch (keymgmt) { 1996 case KEY_MGMT_802_1X: 1997 case KEY_MGMT_802_1X_NO_WPA: 1998 return IW_AUTH_KEY_MGMT_802_1X; 1999 case KEY_MGMT_PSK: 2000 return IW_AUTH_KEY_MGMT_PSK; 2001 default: 2002 return 0; 2003 } 2004} 2005 2006 2007static int 2008wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv, 2009 struct wpa_driver_associate_params *params) 2010{ 2011 struct iwreq iwr; 2012 int ret = 0; 2013 2014 wpa_printf(MSG_DEBUG, "WEXT: Driver did not support " 2015 "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE"); 2016 2017 os_memset(&iwr, 0, sizeof(iwr)); 2018 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2019 /* Just changing mode, not actual keys */ 2020 iwr.u.encoding.flags = 0; 2021 iwr.u.encoding.pointer = (caddr_t) NULL; 2022 iwr.u.encoding.length = 0; 2023 2024 /* 2025 * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two 2026 * different things. Here they are used to indicate Open System vs. 2027 * Shared Key authentication algorithm. However, some drivers may use 2028 * them to select between open/restricted WEP encrypted (open = allow 2029 * both unencrypted and encrypted frames; restricted = only allow 2030 * encrypted frames). 2031 */ 2032 2033 if (!drv->use_crypt) { 2034 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 2035 } else { 2036 if (params->auth_alg & WPA_AUTH_ALG_OPEN) 2037 iwr.u.encoding.flags |= IW_ENCODE_OPEN; 2038 if (params->auth_alg & WPA_AUTH_ALG_SHARED) 2039 iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; 2040 } 2041 2042 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 2043 perror("ioctl[SIOCSIWENCODE]"); 2044 ret = -1; 2045 } 2046 2047 return ret; 2048} 2049 2050 2051int wpa_driver_wext_associate(void *priv, 2052 struct wpa_driver_associate_params *params) 2053{ 2054 struct wpa_driver_wext_data *drv = priv; 2055 int ret = 0; 2056 int allow_unencrypted_eapol; 2057 int value; 2058 2059 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 2060#ifdef ANDROID 2061 drv->skip_disconnect = 0; 2062#endif 2063 if (drv->cfg80211) { 2064 /* 2065 * Stop cfg80211 from trying to associate before we are done 2066 * with all parameters. 2067 */ 2068 wpa_driver_wext_set_ssid(drv, (u8 *) "", 0); 2069 } 2070 2071 if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted) 2072 < 0) 2073 ret = -1; 2074 if (wpa_driver_wext_set_auth_alg(drv, params->auth_alg) < 0) 2075 ret = -1; 2076 if (wpa_driver_wext_set_mode(drv, params->mode) < 0) 2077 ret = -1; 2078 2079 /* 2080 * If the driver did not support SIOCSIWAUTH, fallback to 2081 * SIOCSIWENCODE here. 2082 */ 2083 if (drv->auth_alg_fallback && 2084 wpa_driver_wext_auth_alg_fallback(drv, params) < 0) 2085 ret = -1; 2086 2087 if (!params->bssid && 2088 wpa_driver_wext_set_bssid(drv, NULL) < 0) 2089 ret = -1; 2090 2091 /* TODO: should consider getting wpa version and cipher/key_mgmt suites 2092 * from configuration, not from here, where only the selected suite is 2093 * available */ 2094 if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len) 2095 < 0) 2096 ret = -1; 2097 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) 2098 value = IW_AUTH_WPA_VERSION_DISABLED; 2099 else if (params->wpa_ie[0] == WLAN_EID_RSN) 2100 value = IW_AUTH_WPA_VERSION_WPA2; 2101 else 2102 value = IW_AUTH_WPA_VERSION_WPA; 2103 if (wpa_driver_wext_set_auth_param(drv, 2104 IW_AUTH_WPA_VERSION, value) < 0) 2105 ret = -1; 2106 value = wpa_driver_wext_cipher2wext(params->pairwise_suite); 2107 if (wpa_driver_wext_set_auth_param(drv, 2108 IW_AUTH_CIPHER_PAIRWISE, value) < 0) 2109 ret = -1; 2110 value = wpa_driver_wext_cipher2wext(params->group_suite); 2111 if (wpa_driver_wext_set_auth_param(drv, 2112 IW_AUTH_CIPHER_GROUP, value) < 0) 2113 ret = -1; 2114 value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite); 2115 if (wpa_driver_wext_set_auth_param(drv, 2116 IW_AUTH_KEY_MGMT, value) < 0) 2117 ret = -1; 2118 value = params->key_mgmt_suite != KEY_MGMT_NONE || 2119 params->pairwise_suite != CIPHER_NONE || 2120 params->group_suite != CIPHER_NONE || 2121 params->wpa_ie_len; 2122 if (wpa_driver_wext_set_auth_param(drv, 2123 IW_AUTH_PRIVACY_INVOKED, value) < 0) 2124 ret = -1; 2125 2126 /* Allow unencrypted EAPOL messages even if pairwise keys are set when 2127 * not using WPA. IEEE 802.1X specifies that these frames are not 2128 * encrypted, but WPA encrypts them when pairwise keys are in use. */ 2129 if (params->key_mgmt_suite == KEY_MGMT_802_1X || 2130 params->key_mgmt_suite == KEY_MGMT_PSK) 2131 allow_unencrypted_eapol = 0; 2132 else 2133 allow_unencrypted_eapol = 1; 2134 2135 if (wpa_driver_wext_set_psk(drv, params->psk) < 0) 2136 ret = -1; 2137 if (wpa_driver_wext_set_auth_param(drv, 2138 IW_AUTH_RX_UNENCRYPTED_EAPOL, 2139 allow_unencrypted_eapol) < 0) 2140 ret = -1; 2141#ifdef CONFIG_IEEE80211W 2142 switch (params->mgmt_frame_protection) { 2143 case NO_MGMT_FRAME_PROTECTION: 2144 value = IW_AUTH_MFP_DISABLED; 2145 break; 2146 case MGMT_FRAME_PROTECTION_OPTIONAL: 2147 value = IW_AUTH_MFP_OPTIONAL; 2148 break; 2149 case MGMT_FRAME_PROTECTION_REQUIRED: 2150 value = IW_AUTH_MFP_REQUIRED; 2151 break; 2152 }; 2153 if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0) 2154 ret = -1; 2155#endif /* CONFIG_IEEE80211W */ 2156 if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0) 2157 ret = -1; 2158 if (!drv->cfg80211 && 2159 wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) 2160 ret = -1; 2161 if (params->bssid && 2162 wpa_driver_wext_set_bssid(drv, params->bssid) < 0) 2163 ret = -1; 2164 if (drv->cfg80211 && 2165 wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) 2166 ret = -1; 2167 2168 return ret; 2169} 2170 2171 2172static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg) 2173{ 2174 struct wpa_driver_wext_data *drv = priv; 2175 int algs = 0, res; 2176 2177 if (auth_alg & WPA_AUTH_ALG_OPEN) 2178 algs |= IW_AUTH_ALG_OPEN_SYSTEM; 2179 if (auth_alg & WPA_AUTH_ALG_SHARED) 2180 algs |= IW_AUTH_ALG_SHARED_KEY; 2181 if (auth_alg & WPA_AUTH_ALG_LEAP) 2182 algs |= IW_AUTH_ALG_LEAP; 2183 if (algs == 0) { 2184 /* at least one algorithm should be set */ 2185 algs = IW_AUTH_ALG_OPEN_SYSTEM; 2186 } 2187 2188 res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, 2189 algs); 2190 drv->auth_alg_fallback = res == -2; 2191 return res; 2192} 2193 2194 2195/** 2196 * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE 2197 * @priv: Pointer to private wext data from wpa_driver_wext_init() 2198 * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS 2199 * Returns: 0 on success, -1 on failure 2200 */ 2201int wpa_driver_wext_set_mode(void *priv, int mode) 2202{ 2203 struct wpa_driver_wext_data *drv = priv; 2204 struct iwreq iwr; 2205 int ret = -1; 2206 unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA; 2207 2208 os_memset(&iwr, 0, sizeof(iwr)); 2209 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2210 iwr.u.mode = new_mode; 2211 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) { 2212 ret = 0; 2213 goto done; 2214 } 2215 2216 if (errno != EBUSY) { 2217 perror("ioctl[SIOCSIWMODE]"); 2218 goto done; 2219 } 2220 2221 /* mac80211 doesn't allow mode changes while the device is up, so if 2222 * the device isn't in the mode we're about to change to, take device 2223 * down, try to set the mode again, and bring it back up. 2224 */ 2225 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { 2226 perror("ioctl[SIOCGIWMODE]"); 2227 goto done; 2228 } 2229 2230 if (iwr.u.mode == new_mode) { 2231 ret = 0; 2232 goto done; 2233 } 2234 2235 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) { 2236 /* Try to set the mode again while the interface is down */ 2237 iwr.u.mode = new_mode; 2238 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) 2239 perror("ioctl[SIOCSIWMODE]"); 2240 else 2241 ret = 0; 2242 2243 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1); 2244 } 2245 2246done: 2247 return ret; 2248} 2249 2250 2251static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv, 2252 u32 cmd, const u8 *bssid, const u8 *pmkid) 2253{ 2254 struct iwreq iwr; 2255 struct iw_pmksa pmksa; 2256 int ret = 0; 2257 2258 os_memset(&iwr, 0, sizeof(iwr)); 2259 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2260 os_memset(&pmksa, 0, sizeof(pmksa)); 2261 pmksa.cmd = cmd; 2262 pmksa.bssid.sa_family = ARPHRD_ETHER; 2263 if (bssid) 2264 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); 2265 if (pmkid) 2266 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); 2267 iwr.u.data.pointer = (caddr_t) &pmksa; 2268 iwr.u.data.length = sizeof(pmksa); 2269 2270 if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { 2271 if (errno != EOPNOTSUPP) 2272 perror("ioctl[SIOCSIWPMKSA]"); 2273 ret = -1; 2274 } 2275 2276 return ret; 2277} 2278 2279 2280static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid, 2281 const u8 *pmkid) 2282{ 2283 struct wpa_driver_wext_data *drv = priv; 2284 return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid); 2285} 2286 2287 2288static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid, 2289 const u8 *pmkid) 2290{ 2291 struct wpa_driver_wext_data *drv = priv; 2292 return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid); 2293} 2294 2295 2296static int wpa_driver_wext_flush_pmkid(void *priv) 2297{ 2298 struct wpa_driver_wext_data *drv = priv; 2299 return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL); 2300} 2301 2302 2303int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa) 2304{ 2305 struct wpa_driver_wext_data *drv = priv; 2306 if (!drv->has_capability) 2307 return -1; 2308 os_memcpy(capa, &drv->capa, sizeof(*capa)); 2309 return 0; 2310} 2311 2312 2313int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, 2314 const char *ifname) 2315{ 2316 if (ifname == NULL) { 2317 drv->ifindex2 = -1; 2318 return 0; 2319 } 2320 2321 drv->ifindex2 = if_nametoindex(ifname); 2322 if (drv->ifindex2 <= 0) 2323 return -1; 2324 2325 wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for " 2326 "wireless events", drv->ifindex2, ifname); 2327 2328 return 0; 2329} 2330 2331 2332int wpa_driver_wext_set_operstate(void *priv, int state) 2333{ 2334 struct wpa_driver_wext_data *drv = priv; 2335 2336 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)", 2337 __func__, drv->operstate, state, state ? "UP" : "DORMANT"); 2338 drv->operstate = state; 2339 return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1, 2340 state ? IF_OPER_UP : IF_OPER_DORMANT); 2341} 2342 2343 2344int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv) 2345{ 2346 return drv->we_version_compiled; 2347} 2348 2349 2350static const char * wext_get_radio_name(void *priv) 2351{ 2352 struct wpa_driver_wext_data *drv = priv; 2353 return drv->phyname; 2354} 2355 2356 2357#ifdef ANDROID 2358 2359static int android_wext_cmd(struct wpa_driver_wext_data *drv, const char *cmd) 2360{ 2361 struct iwreq iwr; 2362 char buf[MAX_DRV_CMD_SIZE]; 2363 int ret; 2364 2365 os_memset(&iwr, 0, sizeof(iwr)); 2366 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2367 2368 os_memset(buf, 0, sizeof(buf)); 2369 os_strlcpy(buf, cmd, sizeof(buf)); 2370 2371 iwr.u.data.pointer = buf; 2372 iwr.u.data.length = sizeof(buf); 2373 2374 ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr); 2375 2376 if (ret < 0) { 2377 wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, 2378 cmd); 2379 drv->errors++; 2380 if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) { 2381 drv->errors = 0; 2382 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE 2383 "HANGED"); 2384 } 2385 return ret; 2386 } 2387 2388 drv->errors = 0; 2389 return 0; 2390} 2391 2392 2393static int wext_sched_scan(void *priv, struct wpa_driver_scan_params *params, 2394 u32 interval) 2395{ 2396 struct wpa_driver_wext_data *drv = priv; 2397 struct iwreq iwr; 2398 int ret = 0, i = 0, bp; 2399 char buf[WEXT_PNO_MAX_COMMAND_SIZE]; 2400 2401 bp = WEXT_PNOSETUP_HEADER_SIZE; 2402 os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp); 2403 buf[bp++] = WEXT_PNO_TLV_PREFIX; 2404 buf[bp++] = WEXT_PNO_TLV_VERSION; 2405 buf[bp++] = WEXT_PNO_TLV_SUBVERSION; 2406 buf[bp++] = WEXT_PNO_TLV_RESERVED; 2407 2408 while (i < WEXT_PNO_AMOUNT && (size_t) i < params->num_ssids) { 2409 /* 2410 * Check that there is enough space needed for 1 more SSID, the 2411 * other sections and null termination. 2412 */ 2413 if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE + 2414 WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int) sizeof(buf)) 2415 break; 2416 2417 wpa_hexdump_ascii(MSG_DEBUG, "For PNO Scan", 2418 params->ssids[i].ssid, 2419 params->ssids[i].ssid_len); 2420 buf[bp++] = WEXT_PNO_SSID_SECTION; 2421 buf[bp++] = params->ssids[i].ssid_len; 2422 os_memcpy(&buf[bp], params->ssids[i].ssid, 2423 params->ssids[i].ssid_len); 2424 bp += params->ssids[i].ssid_len; 2425 i++; 2426 } 2427 2428 buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION; 2429 /* TODO: consider using interval parameter (interval in msec) instead 2430 * of hardcoded value here */ 2431 os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", 2432 WEXT_PNO_SCAN_INTERVAL); 2433 bp += WEXT_PNO_SCAN_INTERVAL_LENGTH; 2434 2435 buf[bp++] = WEXT_PNO_REPEAT_SECTION; 2436 os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", 2437 WEXT_PNO_REPEAT); 2438 bp += WEXT_PNO_REPEAT_LENGTH; 2439 2440 buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION; 2441 os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", 2442 WEXT_PNO_MAX_REPEAT); 2443 bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1; 2444 2445 os_memset(&iwr, 0, sizeof(iwr)); 2446 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2447 iwr.u.data.pointer = buf; 2448 iwr.u.data.length = bp; 2449 2450 ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr); 2451 if (ret < 0) { 2452 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", 2453 ret); 2454 drv->errors++; 2455 if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) { 2456 drv->errors = 0; 2457 wpa_msg(drv->ctx, MSG_INFO, 2458 WPA_EVENT_DRIVER_STATE "HANGED"); 2459 } 2460 return ret; 2461 } 2462 2463 drv->errors = 0; 2464 drv->bgscan_enabled = 1; 2465 2466 return android_wext_cmd(drv, "PNOFORCE 1"); 2467} 2468 2469 2470static int wext_stop_sched_scan(void *priv) 2471{ 2472 struct wpa_driver_wext_data *drv = priv; 2473 drv->bgscan_enabled = 0; 2474 return android_wext_cmd(drv, "PNOFORCE 0"); 2475} 2476 2477#endif /* ANDROID */ 2478 2479 2480const struct wpa_driver_ops wpa_driver_wext_ops = { 2481 .name = "wext", 2482 .desc = "Linux wireless extensions (generic)", 2483 .get_bssid = wpa_driver_wext_get_bssid, 2484 .get_ssid = wpa_driver_wext_get_ssid, 2485 .set_key = wpa_driver_wext_set_key, 2486 .set_countermeasures = wpa_driver_wext_set_countermeasures, 2487 .scan2 = wpa_driver_wext_scan, 2488 .get_scan_results2 = wpa_driver_wext_get_scan_results, 2489 .deauthenticate = wpa_driver_wext_deauthenticate, 2490 .disassociate = wpa_driver_wext_disassociate, 2491 .associate = wpa_driver_wext_associate, 2492 .init = wpa_driver_wext_init, 2493 .deinit = wpa_driver_wext_deinit, 2494 .add_pmkid = wpa_driver_wext_add_pmkid, 2495 .remove_pmkid = wpa_driver_wext_remove_pmkid, 2496 .flush_pmkid = wpa_driver_wext_flush_pmkid, 2497 .get_capa = wpa_driver_wext_get_capa, 2498 .set_operstate = wpa_driver_wext_set_operstate, 2499 .get_radio_name = wext_get_radio_name, 2500#ifdef ANDROID 2501 .sched_scan = wext_sched_scan, 2502 .stop_sched_scan = wext_stop_sched_scan, 2503#endif /* ANDROID */ 2504}; 2505