diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2010-06-14 15:52:50 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2010-06-14 15:52:50 +0000 |
commit | 9a3eca9b9f363c4853b4000c9f00ab61bdaacbdb (patch) | |
tree | 9db1edb6bd72e76be7e632a6252628a0bb472c43 | |
parent | d466ac1cf2084770f3d402fc59bbe919c835999e (diff) | |
download | FreeBSD-src-9a3eca9b9f363c4853b4000c9f00ab61bdaacbdb.zip FreeBSD-src-9a3eca9b9f363c4853b4000c9f00ab61bdaacbdb.tar.gz |
Remove unused files.
27 files changed, 0 insertions, 16422 deletions
diff --git a/contrib/wpa/src/drivers/Apple80211.h b/contrib/wpa/src/drivers/Apple80211.h deleted file mode 100644 index 2a612e7..0000000 --- a/contrib/wpa/src/drivers/Apple80211.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef APPLE80211_H -#define APPLE80211_H - -/* - * Apple80211 framework definitions - * This is an undocumented interface and the definitions here are based on - * information from MacStumbler (http://www.macstumbler.com/Apple80211.h) and - * whatever related information can be found with google and experiments ;-). - */ - -typedef struct __WirelessRef *WirelessRef; -typedef SInt32 WirelessError; -#define errWirelessNoError 0 - -typedef struct WirelessInfo { - UInt16 link_qual; - UInt16 comms_qual; - UInt16 signal; - UInt16 noise; - UInt16 port_stat; - UInt16 client_mode; - UInt16 res1; - UInt16 power; - UInt16 res2; - UInt8 bssID[6]; - UInt8 ssid[34]; -} WirelessInfo; - -typedef struct WirelessInfo2 { - /* TODO - these are probably not in correct order or complete */ - WirelessInfo info1; - UInt8 macAddress[6]; -} WirelessInfo2; - -typedef struct WirelessNetworkInfo { - UInt16 channel; - UInt16 noise; - UInt16 signal; - UInt8 bssid[6]; - UInt16 beacon_int; - UInt16 capability; - UInt16 ssid_len; - UInt8 ssid[32]; -} WirelessNetworkInfo; - -typedef int wirelessKeyType; /* TODO */ - -int WirelessIsAvailable(void); -WirelessError WirelessAttach(WirelessRef *ref, UInt32 res); -WirelessError WirelessDetach(WirelessRef ref); -WirelessError WirelessPrivate(WirelessRef ref, void *in_ptr, int in_bytes, - void *out_ptr, int out_bytes); -WirelessError WirelessSetEnabled(WirelessRef ref, UInt8 enabled); -WirelessError WirelessGetEnabled(WirelessRef ref, UInt8 *enabled); -WirelessError WirelessSetPower(WirelessRef ref, UInt8 power); -WirelessError WirelessGetPower(WirelessRef ref, UInt8 *power); -WirelessError WirelessGetInfo(WirelessRef ref, WirelessInfo *info); -WirelessError WirelessGetInfo2(WirelessRef ref, WirelessInfo2 *info); -WirelessError WirelessScan(WirelessRef ref, CFArrayRef *results, - UInt32 strip_dups); -WirelessError WirelessScanSplit(WirelessRef ref, CFArrayRef *ap_results, - CFArrayRef *ibss_results, UInt32 strip_dups); -WirelessError WirelessDirectedScan(WirelessRef ref, CFArrayRef *results, - UInt32 strip_dups, CFStringRef ssid); -WirelessError WirelessDirectedScan2(WirelessRef ref, CFDataRef ssid, - UInt32 strip_dups, CFArrayRef *results); -WirelessError WirelessJoin(WirelessRef ref, CFStringRef ssid); -WirelessError WirelessJoinWEP(WirelessRef ref, CFStringRef ssid, - CFStringRef passwd); -WirelessError WirelessJoin8021x(WirelessRef ref, CFStringRef ssid); -/* - * Set WEP key - * ref: wireless reference from WirelessAttach() - * type: ? - * key_idx: 0..3 - * key_len: 13 for WEP-104 or 0 for clearing the key - * key: Pointer to the key or %NULL if key_len = 0 - */ -WirelessError WirelessSetKey(WirelessRef ref, wirelessKeyType type, - int key_idx, int key_len, - const unsigned char *key); -/* - * Set WPA key (e.g., PMK for 4-way handshake) - * ref: wireless reference from WirelessAttach() - * type: 0..4; 1 = PMK - * key_len: 16, 32, or 0 - * key: Pointer to the key or %NULL if key_len = 0 - */ -WirelessError WirelessSetWPAKey(WirelessRef ref, wirelessKeyType type, - int key_len, const unsigned char *key); -WirelessError WirelessAssociate(WirelessRef ref, int type, CFDataRef ssid, - CFStringRef key); -WirelessError WirelessAssociate2(WirelessRef ref, CFDictionaryRef scan_res, - CFStringRef key); -WirelessError WirelessDisassociate(WirelessRef ref); - -/* - * Get a copy of scan results for the given SSID - * The returned dictionary includes following entries: - * beaconInterval: CFNumber(kCFNumberSInt32Type) - * SSID: CFData buffer of the SSID - * isWPA: CFNumber(kCFNumberSInt32Type); 0 = not used, 1 = WPA, -128 = WPA2 - * name: Name of the network (SSID string) - * BSSID: CFData buffer of the BSSID - * channel: CFNumber(kCFNumberSInt32Type) - * signal: CFNumber(kCFNumberSInt32Type) - * appleIE: CFData - * WPSNOPINRequired: CFBoolean - * noise: CFNumber(kCFNumberSInt32Type) - * capability: CFNumber(kCFNumberSInt32Type) - * uniCipher: CFArray of CFNumber(kCFNumberSInt32Type) - * appleIE_Version: CFNumber(kCFNumberSInt32Type) - * appleIE_Robust: CFBoolean - * WPSConfigured: CFBoolean - * scanWasDirected: CFBoolean - * appleIE_Product: CFNumber(kCFNumberSInt32Type) - * authModes: CFArray of CFNumber(kCFNumberSInt32Type) - * multiCipher: CFNumber(kCFNumberSInt32Type) - */ -CFDictionaryRef WirelessSafeDirectedScanCopy(WirelessRef ref, CFDataRef ssid); - -/* - * Get information about the current association - * The returned dictionary includes following entries: - * keyData: CFData buffer of the key (e.g., 32-octet PSK) - * multiCipher: CFNumber(kCFNumberSInt32Type); 0 = none, 5 = CCMP? - * channel: CFNumber(kCFNumberSInt32Type) - * isIBSS: CFBoolean - * authMode: CFNumber(kCFNumberSInt32Type); 2 = WPA-Personal; 3 = open, - * 129 = WPA2-Enterprise - * isWPA: CFNumber(kCFNumberSInt32Type); 0 = not used, 1 = WPA, -128 == WPA2 - * SSID: CFData buffer of the SSID - * cipherMode: CFNumber(kCFNumberSInt32Type); 0 = none, 4 = CCMP? - */ -CFDictionaryRef WirelessGetAssociationInfo(WirelessRef ref); - -WirelessError WirelessConfigure(WirelessRef ref); - -/* - * Get ASP information - * The returned dictionary includes following entries: - * Version: version number (e.g., 3.0) - * Channel: channel (e.g., 1) - * Vendor: vendor (e.g., 2) - */ -CFDictionaryRef WirelessGetInfoASP(void); - -/* - * Get a copy of the interface dictionary - * The returned dictionary has a key,value pairs for wireless interfaces. - * The key is the interface name and the value is the driver identifier, e.g., - * en1: com.apple.driver.AirPort.Atheros - */ -CFDictionaryRef WirelessCopyInterfaceDict(void); - -#endif /* APPLE80211_H */ diff --git a/contrib/wpa/src/drivers/MobileApple80211.c b/contrib/wpa/src/drivers/MobileApple80211.c deleted file mode 100644 index ce004fe..0000000 --- a/contrib/wpa/src/drivers/MobileApple80211.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "includes.h" -#include <dlfcn.h> - -#include "common.h" - -#include <CoreFoundation/CoreFoundation.h> -#include "MobileApple80211.h" - -/* - * Code for dynamically loading Apple80211 functions from Aeropuerto to avoid - * having to link with full Preferences.framework. - */ - -static void *aeropuerto = NULL; - - -int _Apple80211Initialized(void) -{ - return aeropuerto ? 1 : 0; -} - - -static int (*__Apple80211Open)(Apple80211Ref *ctx) = NULL; - -int Apple80211Open(Apple80211Ref *ctx) -{ - return __Apple80211Open(ctx); -} - - -static int (*__Apple80211Close)(Apple80211Ref ctx) = NULL; - -int Apple80211Close(Apple80211Ref ctx) -{ - return __Apple80211Close(ctx); -} - - -static int (*__Apple80211GetIfListCopy)(Apple80211Ref handle, CFArrayRef *list) - = NULL; - -int Apple80211GetIfListCopy(Apple80211Ref handle, CFArrayRef *list) -{ - return __Apple80211GetIfListCopy(handle, list); -} - - -static int (*__Apple80211BindToInterface)(Apple80211Ref handle, - CFStringRef interface) = NULL; - -int Apple80211BindToInterface(Apple80211Ref handle, - CFStringRef interface) -{ - return __Apple80211BindToInterface(handle, interface); -} - - -static int (*__Apple80211GetInterfaceNameCopy)(Apple80211Ref handle, - CFStringRef *name) = NULL; - -int Apple80211GetInterfaceNameCopy(Apple80211Ref handle, - CFStringRef *name) -{ - return __Apple80211GetInterfaceNameCopy(handle, name); -} - - -static int (*__Apple80211GetInfoCopy)(Apple80211Ref handle, - CFDictionaryRef *info) = NULL; - -int Apple80211GetInfoCopy(Apple80211Ref handle, - CFDictionaryRef *info) -{ - return __Apple80211GetInfoCopy(handle, info); -} - - -static int (*__Apple80211GetPower)(Apple80211Ref handle, char *pwr) = NULL; - -int Apple80211GetPower(Apple80211Ref handle, char *pwr) -{ - return __Apple80211GetPower(handle, pwr); -} - - -static int (*__Apple80211SetPower)(Apple80211Ref handle, char pwr) = NULL; - -int Apple80211SetPower(Apple80211Ref handle, char pwr) -{ - return __Apple80211SetPower(handle, pwr); -} - - -static int (*__Apple80211Scan)(Apple80211Ref handle, CFArrayRef *list, - CFDictionaryRef parameters) = NULL; - -int Apple80211Scan(Apple80211Ref handle, CFArrayRef *list, - CFDictionaryRef parameters) -{ - return __Apple80211Scan(handle, list, parameters); -} - - -static int (*__Apple80211Associate)(Apple80211Ref handle, CFDictionaryRef bss, - CFStringRef password) = NULL; - -int Apple80211Associate(Apple80211Ref handle, CFDictionaryRef bss, - CFStringRef password) -{ - return __Apple80211Associate(handle, bss, password); -} - - -static int (*__Apple80211AssociateAndCopyInfo)(Apple80211Ref handle, - CFDictionaryRef bss, - CFStringRef password, - CFDictionaryRef *info) = - NULL; - -int Apple80211AssociateAndCopyInfo(Apple80211Ref handle, CFDictionaryRef bss, - CFStringRef password, CFDictionaryRef *info) -{ - return __Apple80211AssociateAndCopyInfo(handle, bss, password, info); -} - - -static int (*__Apple80211CopyValue)(Apple80211Ref handle, int field, - CFDictionaryRef arg2, void *value) = NULL; - -int Apple80211CopyValue(Apple80211Ref handle, int field, CFDictionaryRef arg2, - void *value) -{ - return __Apple80211CopyValue(handle, field, arg2, value); -} - - -#define DLSYM(s) \ -do { \ - __ ## s = dlsym(aeropuerto, #s); \ - if (__ ## s == NULL) { \ - wpa_printf(MSG_ERROR, "MobileApple80211: Could not resolve " \ - "symbol '" #s "' (%s)", dlerror()); \ - err = 1; \ - } \ -} while (0) - - -__attribute__ ((constructor)) -void _Apple80211_constructor(void) -{ - const char *fname = "/System/Library/SystemConfiguration/" - "Aeropuerto.bundle/Aeropuerto"; - int err = 0; - - aeropuerto = dlopen(fname, RTLD_LAZY); - if (!aeropuerto) { - wpa_printf(MSG_ERROR, "MobileApple80211: Failed to open %s " - "for symbols", fname); - return; - } - - DLSYM(Apple80211Open); - DLSYM(Apple80211Close); - DLSYM(Apple80211GetIfListCopy); - DLSYM(Apple80211BindToInterface); - DLSYM(Apple80211GetInterfaceNameCopy); - DLSYM(Apple80211GetInfoCopy); - DLSYM(Apple80211GetPower); - DLSYM(Apple80211SetPower); - DLSYM(Apple80211Scan); - DLSYM(Apple80211Associate); - DLSYM(Apple80211AssociateAndCopyInfo); - DLSYM(Apple80211CopyValue); - - if (err) { - dlclose(aeropuerto); - aeropuerto = NULL; - } -} - - -__attribute__ ((destructor)) -void _Apple80211_destructor(void) -{ - if (aeropuerto) { - dlclose(aeropuerto); - aeropuerto = NULL; - } -} diff --git a/contrib/wpa/src/drivers/MobileApple80211.h b/contrib/wpa/src/drivers/MobileApple80211.h deleted file mode 100644 index 64d439d..0000000 --- a/contrib/wpa/src/drivers/MobileApple80211.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef MOBILEAPPLE80211_H -#define MOBILEAPPLE80211_H - -/* - * MobileApple80211 interface for iPhone/iPod touch - * These functions are available from Aeropuerto. - */ - -struct Apple80211; -typedef struct Apple80211 *Apple80211Ref; - -int Apple80211Open(Apple80211Ref *ctx); -int Apple80211Close(Apple80211Ref ctx); -int Apple80211GetIfListCopy(Apple80211Ref handle, CFArrayRef *list); -int Apple80211BindToInterface(Apple80211Ref handle, - CFStringRef interface); -int Apple80211GetInterfaceNameCopy(Apple80211Ref handle, - CFStringRef *name); -int Apple80211GetInfoCopy(Apple80211Ref handle, - CFDictionaryRef *info); -int Apple80211GetPower(Apple80211Ref handle, char *pwr); -int Apple80211SetPower(Apple80211Ref handle, char pwr); - -/* parameters can be NULL; returns scan results in CFArrayRef *list; - * caller will need to free with CFRelease() */ -int Apple80211Scan(Apple80211Ref handle, CFArrayRef *list, - CFDictionaryRef parameters); - -int Apple80211Associate(Apple80211Ref handle, CFDictionaryRef bss, - CFStringRef password); -int Apple80211AssociateAndCopyInfo(Apple80211Ref handle, CFDictionaryRef bss, - CFStringRef password, - CFDictionaryRef *info); - -enum { - APPLE80211_VALUE_SSID = 1, - APPLE80211_VALUE_BSSID = 9 -}; - -int Apple80211CopyValue(Apple80211Ref handle, int field, CFDictionaryRef arg2, - void *value); - -#endif /* MOBILEAPPLE80211_H */ diff --git a/contrib/wpa/src/drivers/driver_atmel.c b/contrib/wpa/src/drivers/driver_atmel.c deleted file mode 100644 index 0a7a66d..0000000 --- a/contrib/wpa/src/drivers/driver_atmel.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * WPA Supplicant - Driver interaction with Atmel Wireless LAN drivers - * Copyright (c) 2000-2005, ATMEL Corporation - * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -/****************************************************************************** - Copyright 2000-2001 ATMEL Corporation. - - WPA Supplicant - driver interaction with Atmel Wireless lan drivers. - - This is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Atmel wireless lan drivers; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -******************************************************************************/ - -/* - * Alternatively, this software may be distributed under the terms of BSD - * license. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "driver_wext.h" - -struct wpa_driver_atmel_data { - void *wext; /* private data for driver_wext */ - void *ctx; - char ifname[IFNAMSIZ + 1]; - int sock; -}; - - -#define ATMEL_WPA_IOCTL (SIOCIWFIRSTPRIV + 2) -#define ATMEL_WPA_IOCTL_PARAM (SIOCIWFIRSTPRIV + 3) -#define ATMEL_WPA_IOCTL_GET_PARAM (SIOCIWFIRSTPRIV + 4) - - -/* ATMEL_WPA_IOCTL ioctl() cmd: */ -enum { - SET_WPA_ENCRYPTION = 1, - SET_CIPHER_SUITES = 2, - MLME_STA_DEAUTH = 3, - MLME_STA_DISASSOC = 4 -}; - -/* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */ -enum { - ATMEL_PARAM_WPA = 1, - ATMEL_PARAM_PRIVACY_INVOKED = 2, - ATMEL_PARAM_WPA_TYPE = 3 -}; - -#define MAX_KEY_LENGTH 40 - -struct atmel_param{ - unsigned char sta_addr[6]; - int cmd; - u8 alg; - u8 key_idx; - u8 set_tx; - u8 seq[8]; - u8 seq_len; - u16 key_len; - u8 key[MAX_KEY_LENGTH]; - struct{ - int reason_code; - u8 state; - }mlme; - u8 pairwise_suite; - u8 group_suite; - u8 key_mgmt_suite; -}; - - - -static int atmel_ioctl(struct wpa_driver_atmel_data *drv, - struct atmel_param *param, - int len, int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) param; - iwr.u.data.length = len; - - if (ioctl(drv->sock, ATMEL_WPA_IOCTL, &iwr) < 0) { - int ret; - ret = errno; - if (show_err) - perror("ioctl[ATMEL_WPA_IOCTL]"); - return ret; - } - - return 0; -} - - -static int atmel2param(struct wpa_driver_atmel_data *drv, int param, int value) -{ - struct iwreq iwr; - int *i, ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - i = (int *) iwr.u.name; - *i++ = param; - *i++ = value; - - if (ioctl(drv->sock, ATMEL_WPA_IOCTL_PARAM, &iwr) < 0) { - perror("ioctl[ATMEL_WPA_IOCTL_PARAM]"); - ret = -1; - } - return ret; -} - - -#if 0 -static int wpa_driver_atmel_set_wpa_ie(struct wpa_driver_atmel_data *drv, - const char *wpa_ie, size_t wpa_ie_len) -{ - struct atmel_param *param; - int res; - size_t blen = ATMEL_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; - if (blen < sizeof(*param)) - blen = sizeof(*param); - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = ATMEL_SET_GENERIC_ELEMENT; - param->u.generic_elem.len = wpa_ie_len; - os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); - res = atmel_ioctl(drv, param, blen, 1); - - os_free(param); - - return res; -} -#endif - - -static int wpa_driver_atmel_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_atmel_data *drv = priv; - int ret = 0; - - printf("wpa_driver_atmel_set_wpa %s\n", drv->ifname); - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - -#if 0 - if (!enabled && wpa_driver_atmel_set_wpa_ie(drv, NULL, 0) < 0) - ret = -1; -#endif - if (atmel2param(drv, ATMEL_PARAM_PRIVACY_INVOKED, enabled) < 0) - ret = -1; - if (atmel2param(drv, ATMEL_PARAM_WPA, enabled) < 0) - ret = -1; - - return ret; -} - - -static int wpa_driver_atmel_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_atmel_data *drv = priv; - int ret = 0; - struct atmel_param *param; - u8 *buf; - u8 alg_type; - - size_t blen; - char *alg_name; - - switch (alg) { - case WPA_ALG_NONE: - alg_name = "none"; - alg_type = 0; - break; - case WPA_ALG_WEP: - alg_name = "WEP"; - alg_type = 1; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - alg_type = 2; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - alg_type = 3; - break; - default: - return -1; - } - - wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - if (seq_len > 8) - return -2; - - blen = sizeof(*param) + key_len; - buf = os_zalloc(blen); - if (buf == NULL) - return -1; - - param = (struct atmel_param *) buf; - - param->cmd = SET_WPA_ENCRYPTION; - - if (addr == NULL) - os_memset(param->sta_addr, 0xff, ETH_ALEN); - else - os_memcpy(param->sta_addr, addr, ETH_ALEN); - - param->alg = alg_type; - param->key_idx = key_idx; - param->set_tx = set_tx; - os_memcpy(param->seq, seq, seq_len); - param->seq_len = seq_len; - param->key_len = key_len; - os_memcpy((u8 *)param->key, key, key_len); - - if (atmel_ioctl(drv, param, blen, 1)) { - wpa_printf(MSG_WARNING, "Failed to set encryption."); - /* TODO: show key error*/ - ret = -1; - } - os_free(buf); - - return ret; -} - - -static int wpa_driver_atmel_set_countermeasures(void *priv, - int enabled) -{ - /* FIX */ - printf("wpa_driver_atmel_set_countermeasures - not yet " - "implemented\n"); - return 0; -} - - -static int wpa_driver_atmel_set_drop_unencrypted(void *priv, - int enabled) -{ - /* FIX */ - printf("wpa_driver_atmel_set_drop_unencrypted - not yet " - "implemented\n"); - return 0; -} - - -static int wpa_driver_atmel_mlme(void *priv, const u8 *addr, int cmd, - int reason_code) -{ - struct wpa_driver_atmel_data *drv = priv; - struct atmel_param param; - int ret; - int mgmt_error = 0xaa; - - os_memset(¶m, 0, sizeof(param)); - os_memcpy(param.sta_addr, addr, ETH_ALEN); - param.cmd = cmd; - param.mlme.reason_code = reason_code; - param.mlme.state = mgmt_error; - ret = atmel_ioctl(drv, ¶m, sizeof(param), 1); - return ret; -} - - -#if 0 -static int wpa_driver_atmel_set_suites(struct wpa_driver_atmel_data *drv, - u8 pairwise_suite, u8 group_suite, - u8 key_mgmt_suite) -{ - struct atmel_param param; - int ret; - - os_memset(¶m, 0, sizeof(param)); - param.cmd = SET_CIPHER_SUITES; - param.pairwise_suite = pairwise_suite; - param.group_suite = group_suite; - param.key_mgmt_suite = key_mgmt_suite; - - ret = atmel_ioctl(drv, ¶m, sizeof(param), 1); - return ret; -} -#endif - - -static int wpa_driver_atmel_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_atmel_data *drv = priv; - printf("wpa_driver_atmel_deauthenticate\n"); - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DEAUTH, - reason_code); - -} - - -static int wpa_driver_atmel_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_atmel_data *drv = priv; - printf("wpa_driver_atmel_disassociate\n"); - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DISASSOC, - reason_code); - -} - - -#if 0 -/* Atmel driver uses specific values for each cipher suite */ -static int convertSuiteToDriver(wpa_cipher suite) -{ - u8 suite_type; - - switch(suite) { - case CIPHER_NONE: - suite_type = 0; - break; - case CIPHER_WEP40: - suite_type = 1; - break; - case CIPHER_TKIP: - suite_type = 2; - break; - case CIPHER_WEP104: - suite_type = 5; - break; - case CIPHER_CCMP: - suite_type = 3; - break; - default: - suite_type = 2; - } - - return suite_type; - -} -#endif - -static int -wpa_driver_atmel_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_atmel_data *drv = priv; - int ret = 0; -#if 0 - u8 pairwise_suite_driver; - u8 group_suite_driver; - u8 key_mgmt_suite_driver; - - pairwise_suite_driver = convertSuiteToDriver(params->pairwise_suite); - group_suite_driver = convertSuiteToDriver(params->group_suite); - key_mgmt_suite_driver = convertSuiteToDriver(params->key_mgmt_suite); - - if (wpa_driver_atmel_set_suites(drv, pairwise_suite_driver, - group_suite_driver, - key_mgmt_suite_driver) < 0){ - printf("wpa_driver_atmel_set_suites.\n"); - ret = -1; - } - if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) { - printf("wpa_driver_atmel_set_freq.\n"); - ret = -1; - } -#endif - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) - < 0) { - printf("FAILED : wpa_driver_atmel_set_ssid.\n"); - ret = -1; - } - if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) { - printf("FAILED : wpa_driver_atmel_set_bssid.\n"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_atmel_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_atmel_data *drv = priv; - return wpa_driver_wext_get_bssid(drv->wext, bssid); -} - - -static int wpa_driver_atmel_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_atmel_data *drv = priv; - return wpa_driver_wext_get_ssid(drv->wext, ssid); -} - - -static int wpa_driver_atmel_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_atmel_data *drv = priv; - return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); -} - - -static struct wpa_scan_results * wpa_driver_atmel_get_scan_results(void *priv) -{ - struct wpa_driver_atmel_data *drv = priv; - return wpa_driver_wext_get_scan_results(drv->wext); -} - - -static int wpa_driver_atmel_set_operstate(void *priv, int state) -{ - struct wpa_driver_atmel_data *drv = priv; - return wpa_driver_wext_set_operstate(drv->wext, state); -} - - -static void * wpa_driver_atmel_init(void *ctx, const char *ifname) -{ - struct wpa_driver_atmel_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->wext = wpa_driver_wext_init(ctx, ifname); - if (drv->wext == NULL) { - os_free(drv); - return NULL; - } - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) { - wpa_driver_wext_deinit(drv->wext); - os_free(drv); - return NULL; - } - - return drv; -} - - -static void wpa_driver_atmel_deinit(void *priv) -{ - struct wpa_driver_atmel_data *drv = priv; - wpa_driver_wext_deinit(drv->wext); - close(drv->sock); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_atmel_ops = { - .name = "atmel", - .desc = "ATMEL AT76C5XXx (USB, PCMCIA)", - .get_bssid = wpa_driver_atmel_get_bssid, - .get_ssid = wpa_driver_atmel_get_ssid, - .set_wpa = wpa_driver_atmel_set_wpa, - .set_key = wpa_driver_atmel_set_key, - .init = wpa_driver_atmel_init, - .deinit = wpa_driver_atmel_deinit, - .set_countermeasures = wpa_driver_atmel_set_countermeasures, - .set_drop_unencrypted = wpa_driver_atmel_set_drop_unencrypted, - .scan = wpa_driver_atmel_scan, - .get_scan_results2 = wpa_driver_atmel_get_scan_results, - .deauthenticate = wpa_driver_atmel_deauthenticate, - .disassociate = wpa_driver_atmel_disassociate, - .associate = wpa_driver_atmel_associate, - .set_operstate = wpa_driver_atmel_set_operstate, -}; diff --git a/contrib/wpa/src/drivers/driver_broadcom.c b/contrib/wpa/src/drivers/driver_broadcom.c deleted file mode 100644 index 3600dae..0000000 --- a/contrib/wpa/src/drivers/driver_broadcom.c +++ /dev/null @@ -1,604 +0,0 @@ -/* - * WPA Supplicant - driver interaction with old Broadcom wl.o driver - * Copyright (c) 2004, Nikki Chumkov <nikki@gattaca.ru> - * Copyright (c) 2004, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * Please note that the newer Broadcom driver ("hybrid Linux driver") supports - * Linux wireless extensions and does not need (or even work) with this old - * driver wrapper. Use driver_wext.c with that driver. - */ - -#include "includes.h" - -#include <sys/ioctl.h> - -#include "common.h" - -#if 0 -#include <netpacket/packet.h> -#include <net/ethernet.h> /* the L2 protocols */ -#else -#include <linux/if_packet.h> -#include <linux/if_ether.h> /* The L2 protocols */ -#endif -#include <net/if.h> -#include <typedefs.h> - -/* wlioctl.h is a Broadcom header file and it is available, e.g., from Linksys - * WRT54G GPL tarball. */ -#include <wlioctl.h> - -#include "driver.h" -#include "eloop.h" - -struct wpa_driver_broadcom_data { - void *ctx; - int ioctl_sock; - int event_sock; - char ifname[IFNAMSIZ + 1]; -}; - - -#ifndef WLC_DEAUTHENTICATE -#define WLC_DEAUTHENTICATE 143 -#endif -#ifndef WLC_DEAUTHENTICATE_WITH_REASON -#define WLC_DEAUTHENTICATE_WITH_REASON 201 -#endif -#ifndef WLC_SET_TKIP_COUNTERMEASURES -#define WLC_SET_TKIP_COUNTERMEASURES 202 -#endif - -#if !defined(PSK_ENABLED) /* NEW driver interface */ -#define WL_VERSION 360130 -/* wireless authentication bit vector */ -#define WPA_ENABLED 1 -#define PSK_ENABLED 2 - -#define WAUTH_WPA_ENABLED(wauth) ((wauth) & WPA_ENABLED) -#define WAUTH_PSK_ENABLED(wauth) ((wauth) & PSK_ENABLED) -#define WAUTH_ENABLED(wauth) ((wauth) & (WPA_ENABLED | PSK_ENABLED)) - -#define WSEC_PRIMARY_KEY WL_PRIMARY_KEY - -typedef wl_wsec_key_t wsec_key_t; -#endif - -typedef struct { - uint32 val; - struct ether_addr ea; - uint16 res; -} wlc_deauth_t; - - -static void wpa_driver_broadcom_scan_timeout(void *eloop_ctx, - void *timeout_ctx); - -static int broadcom_ioctl(struct wpa_driver_broadcom_data *drv, int cmd, - void *buf, int len) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - int ret = 0; - - wpa_printf(MSG_MSGDUMP, "BROADCOM: wlioctl(%s,%d,len=%d,val=%p)", - drv->ifname, cmd, len, buf); - /* wpa_hexdump(MSG_MSGDUMP, "BROADCOM: wlioctl buf", buf, len); */ - - ioc.cmd = cmd; - ioc.buf = buf; - ioc.len = len; - os_strlcpy(ifr.ifr_name, drv->ifname, IFNAMSIZ); - ifr.ifr_data = (caddr_t) &ioc; - if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE, &ifr)) < 0) { - if (cmd != WLC_GET_MAGIC) - perror(ifr.ifr_name); - wpa_printf(MSG_MSGDUMP, "BROADCOM: wlioctl cmd=%d res=%d", - cmd, ret); - } - - return ret; -} - -static int wpa_driver_broadcom_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_broadcom_data *drv = priv; - if (broadcom_ioctl(drv, WLC_GET_BSSID, bssid, ETH_ALEN) == 0) - return 0; - - os_memset(bssid, 0, ETH_ALEN); - return -1; -} - -static int wpa_driver_broadcom_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_broadcom_data *drv = priv; - wlc_ssid_t s; - - if (broadcom_ioctl(drv, WLC_GET_SSID, &s, sizeof(s)) == -1) - return -1; - - os_memcpy(ssid, s.SSID, s.SSID_len); - return s.SSID_len; -} - -static int wpa_driver_broadcom_set_wpa(void *priv, int enable) -{ - struct wpa_driver_broadcom_data *drv = priv; - unsigned int wauth, wsec; - struct ether_addr ea; - - os_memset(&ea, enable ? 0xff : 0, sizeof(ea)); - if (broadcom_ioctl(drv, WLC_GET_WPA_AUTH, &wauth, sizeof(wauth)) == - -1 || - broadcom_ioctl(drv, WLC_GET_WSEC, &wsec, sizeof(wsec)) == -1) - return -1; - - if (enable) { - wauth = PSK_ENABLED; - wsec = TKIP_ENABLED; - } else { - wauth = 255; - wsec &= ~(TKIP_ENABLED | AES_ENABLED); - } - - if (broadcom_ioctl(drv, WLC_SET_WPA_AUTH, &wauth, sizeof(wauth)) == - -1 || - broadcom_ioctl(drv, WLC_SET_WSEC, &wsec, sizeof(wsec)) == -1) - return -1; - - /* FIX: magic number / error handling? */ - broadcom_ioctl(drv, 122, &ea, sizeof(ea)); - - return 0; -} - -static int wpa_driver_broadcom_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_broadcom_data *drv = priv; - int ret; - wsec_key_t wkt; - - os_memset(&wkt, 0, sizeof wkt); - wpa_printf(MSG_MSGDUMP, "BROADCOM: SET %sKEY[%d] alg=%d", - set_tx ? "PRIMARY " : "", key_idx, alg); - if (key && key_len > 0) - wpa_hexdump_key(MSG_MSGDUMP, "BROADCOM: key", key, key_len); - - switch (alg) { - case WPA_ALG_NONE: - wkt.algo = CRYPTO_ALGO_OFF; - break; - case WPA_ALG_WEP: - wkt.algo = CRYPTO_ALGO_WEP128; /* CRYPTO_ALGO_WEP1? */ - break; - case WPA_ALG_TKIP: - wkt.algo = 0; /* CRYPTO_ALGO_TKIP? */ - break; - case WPA_ALG_CCMP: - wkt.algo = 0; /* CRYPTO_ALGO_AES_CCM; - * AES_OCB_MSDU, AES_OCB_MPDU? */ - break; - default: - wkt.algo = CRYPTO_ALGO_NALG; - break; - } - - if (seq && seq_len > 0) - wpa_hexdump(MSG_MSGDUMP, "BROADCOM: SEQ", seq, seq_len); - - if (addr) - wpa_hexdump(MSG_MSGDUMP, "BROADCOM: addr", addr, ETH_ALEN); - - wkt.index = key_idx; - wkt.len = key_len; - if (key && key_len > 0) { - os_memcpy(wkt.data, key, key_len); - if (key_len == 32) { - /* hack hack hack XXX */ - os_memcpy(&wkt.data[16], &key[24], 8); - os_memcpy(&wkt.data[24], &key[16], 8); - } - } - /* wkt.algo = CRYPTO_ALGO_...; */ - wkt.flags = set_tx ? 0 : WSEC_PRIMARY_KEY; - if (addr && set_tx) - os_memcpy(&wkt.ea, addr, sizeof(wkt.ea)); - ret = broadcom_ioctl(drv, WLC_SET_KEY, &wkt, sizeof(wkt)); - if (addr && set_tx) { - /* FIX: magic number / error handling? */ - broadcom_ioctl(drv, 121, &wkt.ea, sizeof(wkt.ea)); - } - return ret; -} - - -static void wpa_driver_broadcom_event_receive(int sock, void *ctx, - void *sock_ctx) -{ - char buf[8192]; - int left; - wl_wpa_header_t *wwh; - union wpa_event_data data; - - if ((left = recv(sock, buf, sizeof buf, 0)) < 0) - return; - - wpa_hexdump(MSG_DEBUG, "RECEIVE EVENT", (u8 *) buf, left); - - if ((size_t) left < sizeof(wl_wpa_header_t)) - return; - - wwh = (wl_wpa_header_t *) buf; - - if (wwh->snap.type != WL_WPA_ETHER_TYPE) - return; - if (os_memcmp(&wwh->snap, wl_wpa_snap_template, 6) != 0) - return; - - os_memset(&data, 0, sizeof(data)); - - switch (wwh->type) { - case WLC_ASSOC_MSG: - left -= WL_WPA_HEADER_LEN; - wpa_printf(MSG_DEBUG, "BROADCOM: ASSOC MESSAGE (left: %d)", - left); - if (left > 0) { - data.assoc_info.resp_ies = os_malloc(left); - if (data.assoc_info.resp_ies == NULL) - return; - os_memcpy(data.assoc_info.resp_ies, - buf + WL_WPA_HEADER_LEN, left); - data.assoc_info.resp_ies_len = left; - wpa_hexdump(MSG_MSGDUMP, "BROADCOM: copying %d bytes " - "into resp_ies", - data.assoc_info.resp_ies, left); - } - /* data.assoc_info.req_ies = NULL; */ - /* data.assoc_info.req_ies_len = 0; */ - - wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - break; - case WLC_DISASSOC_MSG: - wpa_printf(MSG_DEBUG, "BROADCOM: DISASSOC MESSAGE"); - wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); - break; - case WLC_PTK_MIC_MSG: - wpa_printf(MSG_DEBUG, "BROADCOM: PTK MIC MSG MESSAGE"); - data.michael_mic_failure.unicast = 1; - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - break; - case WLC_GTK_MIC_MSG: - wpa_printf(MSG_DEBUG, "BROADCOM: GTK MIC MSG MESSAGE"); - data.michael_mic_failure.unicast = 0; - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - break; - default: - wpa_printf(MSG_DEBUG, "BROADCOM: UNKNOWN MESSAGE (%d)", - wwh->type); - break; - } - os_free(data.assoc_info.resp_ies); -} - -static void * wpa_driver_broadcom_init(void *ctx, const char *ifname) -{ - int s; - struct sockaddr_ll ll; - struct wpa_driver_broadcom_data *drv; - struct ifreq ifr; - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return NULL; - } - /* do it */ - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - perror(ifr.ifr_name); - return NULL; - } - - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->ioctl_sock = s; - - s = socket(PF_PACKET, SOCK_RAW, ntohs(ETH_P_802_2)); - if (s < 0) { - perror("socket(PF_PACKET, SOCK_RAW, ntohs(ETH_P_802_2))"); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - os_memset(&ll, 0, sizeof(ll)); - ll.sll_family = AF_PACKET; - ll.sll_protocol = ntohs(ETH_P_802_2); - ll.sll_ifindex = ifr.ifr_ifindex; - ll.sll_hatype = 0; - ll.sll_pkttype = PACKET_HOST; - ll.sll_halen = 0; - - if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) { - perror("bind(netlink)"); - close(s); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - eloop_register_read_sock(s, wpa_driver_broadcom_event_receive, ctx, - NULL); - drv->event_sock = s; - - return drv; -} - -static void wpa_driver_broadcom_deinit(void *priv) -{ - struct wpa_driver_broadcom_data *drv = priv; - eloop_cancel_timeout(wpa_driver_broadcom_scan_timeout, drv, drv->ctx); - eloop_unregister_read_sock(drv->event_sock); - close(drv->event_sock); - close(drv->ioctl_sock); - os_free(drv); -} - -static int wpa_driver_broadcom_set_countermeasures(void *priv, - int enabled) -{ -#if 0 - struct wpa_driver_broadcom_data *drv = priv; - /* FIX: ? */ - return broadcom_ioctl(drv, WLC_SET_TKIP_COUNTERMEASURES, &enabled, - sizeof(enabled)); -#else - return 0; -#endif -} - -static int wpa_driver_broadcom_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_broadcom_data *drv = priv; - /* SET_EAP_RESTRICT, SET_WEP_RESTRICT */ - int restrict = (enabled ? 1 : 0); - - if (broadcom_ioctl(drv, WLC_SET_WEP_RESTRICT, - &restrict, sizeof(restrict)) < 0 || - broadcom_ioctl(drv, WLC_SET_EAP_RESTRICT, - &restrict, sizeof(restrict)) < 0) - return -1; - - return 0; -} - -static void wpa_driver_broadcom_scan_timeout(void *eloop_ctx, - void *timeout_ctx) -{ - wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - -static int wpa_driver_broadcom_scan(void *priv, const u8 *ssid, - size_t ssid_len) -{ - struct wpa_driver_broadcom_data *drv = priv; - wlc_ssid_t wst = { 0, "" }; - - if (ssid && ssid_len > 0 && ssid_len <= sizeof(wst.SSID)) { - wst.SSID_len = ssid_len; - os_memcpy(wst.SSID, ssid, ssid_len); - } - - if (broadcom_ioctl(drv, WLC_SCAN, &wst, sizeof(wst)) < 0) - return -1; - - eloop_cancel_timeout(wpa_driver_broadcom_scan_timeout, drv, drv->ctx); - eloop_register_timeout(3, 0, wpa_driver_broadcom_scan_timeout, drv, - drv->ctx); - return 0; -} - - -static const int frequency_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 -}; - -struct bss_ie_hdr { - u8 elem_id; - u8 len; - u8 oui[3]; - /* u8 oui_type; */ - /* u16 version; */ -} __attribute__ ((packed)); - -static int -wpa_driver_broadcom_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ - struct wpa_driver_broadcom_data *drv = priv; - char *buf; - wl_scan_results_t *wsr; - wl_bss_info_t *wbi; - size_t ap_num; - - buf = os_malloc(WLC_IOCTL_MAXLEN); - if (buf == NULL) - return -1; - - wsr = (wl_scan_results_t *) buf; - - wsr->buflen = WLC_IOCTL_MAXLEN - sizeof(wsr); - wsr->version = 107; - wsr->count = 0; - - if (broadcom_ioctl(drv, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0) { - os_free(buf); - return -1; - } - - os_memset(results, 0, max_size * sizeof(struct wpa_scan_result)); - - for (ap_num = 0, wbi = wsr->bss_info; ap_num < wsr->count; ++ap_num) { - int left; - struct bss_ie_hdr *ie; - - os_memcpy(results[ap_num].bssid, &wbi->BSSID, ETH_ALEN); - os_memcpy(results[ap_num].ssid, wbi->SSID, wbi->SSID_len); - results[ap_num].ssid_len = wbi->SSID_len; - results[ap_num].freq = frequency_list[wbi->channel - 1]; - /* get ie's */ - wpa_hexdump(MSG_MSGDUMP, "BROADCOM: AP IEs", - (u8 *) wbi + sizeof(*wbi), wbi->ie_length); - ie = (struct bss_ie_hdr *) ((u8 *) wbi + sizeof(*wbi)); - for (left = wbi->ie_length; left > 0; - left -= (ie->len + 2), ie = (struct bss_ie_hdr *) - ((u8 *) ie + 2 + ie->len)) { - wpa_printf(MSG_MSGDUMP, "BROADCOM: IE: id:%x, len:%d", - ie->elem_id, ie->len); - if (ie->len >= 3) - wpa_printf(MSG_MSGDUMP, - "BROADCOM: oui:%02x%02x%02x", - ie->oui[0], ie->oui[1], ie->oui[2]); - if (ie->elem_id != 0xdd || - ie->len < 6 || - os_memcmp(ie->oui, WPA_OUI, 3) != 0) - continue; - os_memcpy(results[ap_num].wpa_ie, ie, ie->len + 2); - results[ap_num].wpa_ie_len = ie->len + 2; - break; - } - - wbi = (wl_bss_info_t *) ((u8 *) wbi + wbi->length); - } - - wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%lu " - "BSSes)", - wsr->buflen, (unsigned long) ap_num); - - os_free(buf); - return ap_num; -} - -static int wpa_driver_broadcom_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_broadcom_data *drv = priv; - wlc_deauth_t wdt; - wdt.val = reason_code; - os_memcpy(&wdt.ea, addr, sizeof wdt.ea); - wdt.res = 0x7fff; - return broadcom_ioctl(drv, WLC_DEAUTHENTICATE_WITH_REASON, &wdt, - sizeof(wdt)); -} - -static int wpa_driver_broadcom_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_broadcom_data *drv = priv; - return broadcom_ioctl(drv, WLC_DISASSOC, 0, 0); -} - -static int -wpa_driver_broadcom_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_broadcom_data *drv = priv; - wlc_ssid_t s; - int infra = 1; - int auth = 0; - int wsec = 4; - int dummy; - int wpa_auth; - - s.SSID_len = params->ssid_len; - os_memcpy(s.SSID, params->ssid, params->ssid_len); - - switch (params->pairwise_suite) { - case CIPHER_WEP40: - case CIPHER_WEP104: - wsec = 1; - break; - - case CIPHER_TKIP: - wsec = 2; - break; - - case CIPHER_CCMP: - wsec = 4; - break; - - default: - wsec = 0; - break; - } - - switch (params->key_mgmt_suite) { - case KEY_MGMT_802_1X: - wpa_auth = 1; - break; - - case KEY_MGMT_PSK: - wpa_auth = 2; - break; - - default: - wpa_auth = 255; - break; - } - - /* printf("broadcom_associate: %u %u %u\n", pairwise_suite, - * group_suite, key_mgmt_suite); - * broadcom_ioctl(ifname, WLC_GET_WSEC, &wsec, sizeof(wsec)); - * wl join uses wlc_sec_wep here, not wlc_set_wsec */ - - if (broadcom_ioctl(drv, WLC_SET_WSEC, &wsec, sizeof(wsec)) < 0 || - broadcom_ioctl(drv, WLC_SET_WPA_AUTH, &wpa_auth, - sizeof(wpa_auth)) < 0 || - broadcom_ioctl(drv, WLC_GET_WEP, &dummy, sizeof(dummy)) < 0 || - broadcom_ioctl(drv, WLC_SET_INFRA, &infra, sizeof(infra)) < 0 || - broadcom_ioctl(drv, WLC_SET_AUTH, &auth, sizeof(auth)) < 0 || - broadcom_ioctl(drv, WLC_SET_WEP, &wsec, sizeof(wsec)) < 0 || - broadcom_ioctl(drv, WLC_SET_SSID, &s, sizeof(s)) < 0) - return -1; - - return 0; -} - -const struct wpa_driver_ops wpa_driver_broadcom_ops = { - .name = "broadcom", - .desc = "Broadcom wl.o driver", - .get_bssid = wpa_driver_broadcom_get_bssid, - .get_ssid = wpa_driver_broadcom_get_ssid, - .set_wpa = wpa_driver_broadcom_set_wpa, - .set_key = wpa_driver_broadcom_set_key, - .init = wpa_driver_broadcom_init, - .deinit = wpa_driver_broadcom_deinit, - .set_countermeasures = wpa_driver_broadcom_set_countermeasures, - .set_drop_unencrypted = wpa_driver_broadcom_set_drop_unencrypted, - .scan = wpa_driver_broadcom_scan, - .get_scan_results = wpa_driver_broadcom_get_scan_results, - .deauthenticate = wpa_driver_broadcom_deauthenticate, - .disassociate = wpa_driver_broadcom_disassociate, - .associate = wpa_driver_broadcom_associate, -}; diff --git a/contrib/wpa/src/drivers/driver_bsd.c b/contrib/wpa/src/drivers/driver_bsd.c deleted file mode 100644 index da57852..0000000 --- a/contrib/wpa/src/drivers/driver_bsd.c +++ /dev/null @@ -1,795 +0,0 @@ -/* - * WPA Supplicant - driver interaction with BSD net80211 layer - * Copyright (c) 2004, Sam Leffler <sam@errno.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "ieee802_11_defs.h" - -#include <net/if.h> - -#ifdef __NetBSD__ -#include <net/if_ether.h> -#define COMPAT_FREEBSD_NET80211 -#else -#include <net/ethernet.h> -#endif - -#include <net80211/_ieee80211.h> -#include <net80211/ieee80211.h> -#include <net80211/ieee80211_crypto.h> -#include <net80211/ieee80211_ioctl.h> - -struct wpa_driver_bsd_data { - int sock; /* open socket for 802.11 ioctls */ - int route; /* routing socket for events */ - char ifname[IFNAMSIZ+1]; /* interface name */ - unsigned int ifindex; /* interface index */ - void *ctx; - int prev_roaming; /* roaming state to restore on deinit */ - int prev_privacy; /* privacy state to restore on deinit */ - int prev_wpa; /* wpa state to restore on deinit */ -}; - -static int -set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len) -{ - struct ieee80211req ireq; - - os_memset(&ireq, 0, sizeof(ireq)); - os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_len = arg_len; - ireq.i_data = (void *) arg; - - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n", - op, arg_len, strerror(errno)); - return -1; - } - return 0; -} - -static int -get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len) -{ - struct ieee80211req ireq; - - os_memset(&ireq, 0, sizeof(ireq)); - os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_len = arg_len; - ireq.i_data = arg; - - if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n", - op, arg_len, strerror(errno)); - return -1; - } - return ireq.i_len; -} - -static int -set80211param(struct wpa_driver_bsd_data *drv, int op, int arg) -{ - struct ieee80211req ireq; - - os_memset(&ireq, 0, sizeof(ireq)); - os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_val = arg; - - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n", - op, arg, strerror(errno)); - return -1; - } - return 0; -} - -static int -get80211param(struct wpa_driver_bsd_data *drv, int op) -{ - struct ieee80211req ireq; - - os_memset(&ireq, 0, sizeof(ireq)); - os_strlcpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - - if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n", - op, strerror(errno)); - return -1; - } - return ireq.i_val; -} - -static int -getifflags(struct wpa_driver_bsd_data *drv, int *flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); - if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { - perror("SIOCGIFFLAGS"); - return errno; - } - *flags = ifr.ifr_flags & 0xffff; - return 0; -} - -static int -setifflags(struct wpa_driver_bsd_data *drv, int flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); - ifr.ifr_flags = flags & 0xffff; - if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { - perror("SIOCSIFFLAGS"); - return errno; - } - return 0; -} - -static int -wpa_driver_bsd_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return get80211var(drv, IEEE80211_IOC_BSSID, - bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0; -} - -#if 0 -static int -wpa_driver_bsd_set_bssid(void *priv, const char *bssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return set80211var(drv, IEEE80211_IOC_BSSID, - bssid, IEEE80211_ADDR_LEN); -} -#endif - -static int -wpa_driver_bsd_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return get80211var(drv, IEEE80211_IOC_SSID, - ssid, IEEE80211_NWID_LEN); -} - -static int -wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid, - size_t ssid_len) -{ - struct wpa_driver_bsd_data *drv = priv; - - return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); -} - -static int -wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, - const u8 *wpa_ie, size_t wpa_ie_len) -{ - return set80211var(drv, IEEE80211_IOC_APPIE, wpa_ie, wpa_ie_len); -} - -static int -wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) -{ - struct wpa_driver_bsd_data *drv = priv; - int ret = 0; - - wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", - __FUNCTION__, wpa, privacy); - - if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) - ret = -1; - if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) - ret = -1; - if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0) - ret = -1; - - return ret; -} - -static int -wpa_driver_bsd_set_wpa(void *priv, int enabled) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - - return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled); -} - -static int -wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, - const unsigned char *addr) -{ - struct ieee80211req_del_key wk; - - os_memset(&wk, 0, sizeof(wk)); - if (addr != NULL && - bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) { - struct ether_addr ea; - - os_memcpy(&ea, addr, IEEE80211_ADDR_LEN); - wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d", - __func__, ether_ntoa(&ea), key_idx); - os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); - wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE; - } else { - wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx); - wk.idk_keyix = key_idx; - } - return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); -} - -static int -wpa_driver_bsd_set_key(void *priv, wpa_alg alg, - const unsigned char *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_key wk; - struct ether_addr ea; - char *alg_name; - u_int8_t cipher; - - if (alg == WPA_ALG_NONE) - return wpa_driver_bsd_del_key(drv, key_idx, addr); - - switch (alg) { - case WPA_ALG_WEP: - alg_name = "WEP"; - cipher = IEEE80211_CIPHER_WEP; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - cipher = IEEE80211_CIPHER_TKIP; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - cipher = IEEE80211_CIPHER_AES_CCM; - break; - default: - wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", - __func__, alg); - return -1; - } - - os_memcpy(&ea, addr, IEEE80211_ADDR_LEN); - wpa_printf(MSG_DEBUG, - "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", - __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, - seq_len, key_len); - - if (seq_len > sizeof(u_int64_t)) { - wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", - __func__, seq_len); - return -2; - } - if (key_len > sizeof(wk.ik_keydata)) { - wpa_printf(MSG_DEBUG, "%s: key length %zu too big", - __func__, key_len); - return -3; - } - - os_memset(&wk, 0, sizeof(wk)); - wk.ik_type = cipher; - wk.ik_flags = IEEE80211_KEY_RECV; - if (set_tx) - wk.ik_flags |= IEEE80211_KEY_XMIT; - os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); - /* - * Deduce whether group/global or unicast key by checking - * the address (yech). Note also that we can only mark global - * keys default; doing this for a unicast key is an error. - */ - if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) { - wk.ik_flags |= IEEE80211_KEY_GROUP; - wk.ik_keyix = key_idx; - } else { - wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx); - } - if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) - wk.ik_flags |= IEEE80211_KEY_DEFAULT; - wk.ik_keylen = key_len; - os_memcpy(&wk.ik_keyrsc, seq, seq_len); - os_memcpy(wk.ik_keydata, key, key_len); - - return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); -} - -static int -wpa_driver_bsd_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_bsd_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); -} - - -static int -wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_bsd_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled); -} - -static int -wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - - wpa_printf(MSG_DEBUG, "%s", __func__); - os_memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DEAUTH; - mlme.im_reason = reason_code; - os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - - wpa_printf(MSG_DEBUG, "%s", __func__); - os_memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DISASSOC; - mlme.im_reason = reason_code; - os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - int privacy; - - wpa_printf(MSG_DEBUG, - "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" - , __func__ - , params->ssid_len, params->ssid - , params->wpa_ie_len - , params->pairwise_suite - , params->group_suite - , params->key_mgmt_suite - ); - - /* XXX error handling is wrong but unclear what to do... */ - if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) - return -1; - - privacy = !(params->pairwise_suite == CIPHER_NONE && - params->group_suite == CIPHER_NONE && - params->key_mgmt_suite == KEY_MGMT_NONE && - params->wpa_ie_len == 0); - wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy); - - if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) - return -1; - - if (params->wpa_ie_len && - set80211param(drv, IEEE80211_IOC_WPA, - params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) - return -1; - - os_memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_ASSOC; - if (params->ssid != NULL) - os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len); - mlme.im_ssid_len = params->ssid_len; - if (params->bssid != NULL) - os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); - if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) - return -1; - return 0; -} - -static int -wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_bsd_data *drv = priv; - int authmode; - - if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) && - (auth_alg & AUTH_ALG_SHARED_KEY)) - authmode = IEEE80211_AUTH_AUTO; - else if (auth_alg & AUTH_ALG_SHARED_KEY) - authmode = IEEE80211_AUTH_SHARED; - else - authmode = IEEE80211_AUTH_OPEN; - - return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); -} - -static int -wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_bsd_data *drv = priv; - int flags; - - /* NB: interface must be marked UP to do a scan */ - if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0) - return -1; - - /* set desired ssid before scan */ - if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0) - return -1; - - /* NB: net80211 delivers a scan complete event so no need to poll */ - return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0); -} - -#include <net/route.h> -#if __FreeBSD__ -#include <net80211/ieee80211_freebsd.h> -#endif -#if __NetBSD__ -#include <net80211/ieee80211_netbsd.h> -#endif - -static void -wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) -{ - struct wpa_driver_bsd_data *drv = sock_ctx; - char buf[2048]; - struct if_announcemsghdr *ifan; - struct if_msghdr *ifm; - struct rt_msghdr *rtm; - union wpa_event_data event; - struct ieee80211_michael_event *mic; - int n; - - n = read(sock, buf, sizeof(buf)); - if (n < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("read(PF_ROUTE)"); - return; - } - - rtm = (struct rt_msghdr *) buf; - if (rtm->rtm_version != RTM_VERSION) { - wpa_printf(MSG_DEBUG, "Routing message version %d not " - "understood\n", rtm->rtm_version); - return; - } - os_memset(&event, 0, sizeof(event)); - switch (rtm->rtm_type) { - case RTM_IFANNOUNCE: - ifan = (struct if_announcemsghdr *) rtm; - if (ifan->ifan_index != drv->ifindex) - break; - strlcpy(event.interface_status.ifname, drv->ifname, - sizeof(event.interface_status.ifname)); - switch (ifan->ifan_what) { - case IFAN_DEPARTURE: - event.interface_status.ievent = EVENT_INTERFACE_REMOVED; - default: - return; - } - wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s", - event.interface_status.ifname, - ifan->ifan_what == IFAN_DEPARTURE ? - "removed" : "added"); - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); - break; - case RTM_IEEE80211: - ifan = (struct if_announcemsghdr *) rtm; - if (ifan->ifan_index != drv->ifindex) - break; - switch (ifan->ifan_what) { - case RTM_IEEE80211_ASSOC: - case RTM_IEEE80211_REASSOC: - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - break; - case RTM_IEEE80211_DISASSOC: - wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); - break; - case RTM_IEEE80211_SCAN: - wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); - break; - case RTM_IEEE80211_REPLAY: - /* ignore */ - break; - case RTM_IEEE80211_MICHAEL: - mic = (struct ieee80211_michael_event *) &ifan[1]; - wpa_printf(MSG_DEBUG, - "Michael MIC failure wireless event: " - "keyix=%u src_addr=" MACSTR, mic->iev_keyix, - MAC2STR(mic->iev_src)); - - os_memset(&event, 0, sizeof(event)); - event.michael_mic_failure.unicast = - !IEEE80211_IS_MULTICAST(mic->iev_dst); - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, - &event); - break; - } - break; - case RTM_IFINFO: - ifm = (struct if_msghdr *) rtm; - if (ifm->ifm_index != drv->ifindex) - break; - if ((rtm->rtm_flags & RTF_UP) == 0) { - strlcpy(event.interface_status.ifname, drv->ifname, - sizeof(event.interface_status.ifname)); - event.interface_status.ievent = EVENT_INTERFACE_REMOVED; - wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN", - event.interface_status.ifname); - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); - } - break; - } -} - -/* Compare function for sorting scan results. Return >0 if @b is consider - * better. */ -static int -wpa_scan_result_compar(const void *a, const void *b) -{ - const struct wpa_scan_result *wa = a; - const struct wpa_scan_result *wb = b; - - /* WPA/WPA2 support preferred */ - if ((wb->wpa_ie_len || wb->rsn_ie_len) && - !(wa->wpa_ie_len || wa->rsn_ie_len)) - return 1; - if (!(wb->wpa_ie_len || wb->rsn_ie_len) && - (wa->wpa_ie_len || wa->rsn_ie_len)) - return -1; - - /* privacy support preferred */ - if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) && - (wb->caps & IEEE80211_CAPINFO_PRIVACY) == 0) - return 1; - if ((wa->caps & IEEE80211_CAPINFO_PRIVACY) == 0 && - (wb->caps & IEEE80211_CAPINFO_PRIVACY)) - return -1; - - /* best/max rate preferred if signal level close enough XXX */ - if (wa->maxrate != wb->maxrate && abs(wb->level - wa->level) < 5) - return wb->maxrate - wa->maxrate; - - /* use freq for channel preference */ - - /* all things being equal, use signal level */ - return wb->level - wa->level; -} - -static int -getmaxrate(uint8_t rates[15], uint8_t nrates) -{ - int i, maxrate = -1; - - for (i = 0; i < nrates; i++) { - int rate = rates[i] & IEEE80211_RATE_VAL; - if (rate > maxrate) - rate = maxrate; - } - return maxrate; -} - -/* unalligned little endian access */ -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - -static int __inline -iswpaoui(const u_int8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); -} - -static int -wpa_driver_bsd_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ -#define min(a,b) ((a)>(b)?(b):(a)) - struct wpa_driver_bsd_data *drv = priv; - uint8_t buf[24*1024]; - uint8_t *cp, *vp; - struct ieee80211req_scan_result *sr; - struct wpa_scan_result *wsr; - int len, ielen; - - os_memset(results, 0, max_size * sizeof(struct wpa_scan_result)); - - len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf)); - if (len < 0) - return -1; - cp = buf; - wsr = results; - while (len >= sizeof(struct ieee80211req_scan_result)) { - sr = (struct ieee80211req_scan_result *) cp; - os_memcpy(wsr->bssid, sr->isr_bssid, IEEE80211_ADDR_LEN); - wsr->ssid_len = sr->isr_ssid_len; - wsr->freq = sr->isr_freq; - wsr->noise = sr->isr_noise; - wsr->qual = sr->isr_rssi; - wsr->level = 0; /* XXX? */ - wsr->caps = sr->isr_capinfo; - wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates); - vp = (u_int8_t *)(sr+1); - os_memcpy(wsr->ssid, vp, sr->isr_ssid_len); - if (sr->isr_ie_len > 0) { - vp += sr->isr_ssid_len; - ielen = sr->isr_ie_len; - while (ielen > 0) { - switch (vp[0]) { - case IEEE80211_ELEMID_VENDOR: - if (!iswpaoui(vp)) - break; - wsr->wpa_ie_len = - min(2+vp[1], SSID_MAX_WPA_IE_LEN); - os_memcpy(wsr->wpa_ie, vp, - wsr->wpa_ie_len); - break; - case IEEE80211_ELEMID_RSN: - wsr->rsn_ie_len = - min(2+vp[1], SSID_MAX_WPA_IE_LEN); - os_memcpy(wsr->rsn_ie, vp, - wsr->rsn_ie_len); - break; - } - ielen -= 2+vp[1]; - vp += 2+vp[1]; - } - } - - cp += sr->isr_len, len -= sr->isr_len; - wsr++; - } - qsort(results, wsr - results, sizeof(struct wpa_scan_result), - wpa_scan_result_compar); - - wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%d BSSes)", - len, wsr - results); - - return wsr - results; -#undef min -} - -static void * -wpa_driver_bsd_init(void *ctx, const char *ifname) -{ -#define GETPARAM(drv, param, v) \ - (((v) = get80211param(drv, param)) != -1) - struct wpa_driver_bsd_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - /* - * NB: We require the interface name be mappable to an index. - * This implies we do not support having wpa_supplicant - * wait for an interface to appear. This seems ok; that - * doesn't belong here; it's really the job of devd. - */ - drv->ifindex = if_nametoindex(ifname); - if (drv->ifindex == 0) { - wpa_printf(MSG_DEBUG, "%s: interface %s does not exist", - __func__, ifname); - goto fail1; - } - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) - goto fail1; - drv->route = socket(PF_ROUTE, SOCK_RAW, 0); - if (drv->route < 0) - goto fail; - eloop_register_read_sock(drv->route, - wpa_driver_bsd_event_receive, ctx, drv); - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - - if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { - wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", - __func__, strerror(errno)); - goto fail; - } - if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { - wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", - __func__, strerror(errno)); - goto fail; - } - if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { - wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", - __func__, strerror(errno)); - goto fail; - } - if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " - "roaming: %s", __func__, strerror(errno)); - goto fail; - } - - if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", - __func__, strerror(errno)); - goto fail; - } - - return drv; -fail: - close(drv->sock); -fail1: - os_free(drv); - return NULL; -#undef GETPARAM -} - -static void -wpa_driver_bsd_deinit(void *priv) -{ - struct wpa_driver_bsd_data *drv = priv; - int flags; - - eloop_unregister_read_sock(drv->route); - - /* NB: mark interface down */ - if (getifflags(drv, &flags) == 0) - (void) setifflags(drv, flags &~ IFF_UP); - - wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); - if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) - wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state", - __func__); - - (void) close(drv->route); /* ioctl socket */ - (void) close(drv->sock); /* event socket */ - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_bsd_ops = { - .name = "bsd", - .desc = "BSD 802.11 support (Atheros, etc.)", - .init = wpa_driver_bsd_init, - .deinit = wpa_driver_bsd_deinit, - .get_bssid = wpa_driver_bsd_get_bssid, - .get_ssid = wpa_driver_bsd_get_ssid, - .set_wpa = wpa_driver_bsd_set_wpa, - .set_key = wpa_driver_bsd_set_key, - .set_countermeasures = wpa_driver_bsd_set_countermeasures, - .set_drop_unencrypted = wpa_driver_bsd_set_drop_unencrypted, - .scan = wpa_driver_bsd_scan, - .get_scan_results = wpa_driver_bsd_get_scan_results, - .deauthenticate = wpa_driver_bsd_deauthenticate, - .disassociate = wpa_driver_bsd_disassociate, - .associate = wpa_driver_bsd_associate, - .set_auth_alg = wpa_driver_bsd_set_auth_alg, -}; diff --git a/contrib/wpa/src/drivers/driver_hostap.c b/contrib/wpa/src/drivers/driver_hostap.c deleted file mode 100644 index 84ef3bd..0000000 --- a/contrib/wpa/src/drivers/driver_hostap.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Linux Host AP driver - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "driver_wext.h" -#include "eloop.h" -#include "driver_hostap.h" - - -struct wpa_driver_hostap_data { - void *wext; /* private data for driver_wext */ - void *ctx; - char ifname[IFNAMSIZ + 1]; - int sock; - int current_mode; /* infra/adhoc */ -}; - - -static int hostapd_ioctl(struct wpa_driver_hostap_data *drv, - struct prism2_hostapd_param *param, - int len, int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) param; - iwr.u.data.length = len; - - if (ioctl(drv->sock, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { - int ret = errno; - if (show_err) - perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); - return ret; - } - - return 0; -} - - -static int wpa_driver_hostap_set_wpa_ie(struct wpa_driver_hostap_data *drv, - const u8 *wpa_ie, size_t wpa_ie_len) -{ - struct prism2_hostapd_param *param; - int res; - size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; - if (blen < sizeof(*param)) - blen = sizeof(*param); - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT; - param->u.generic_elem.len = wpa_ie_len; - os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); - res = hostapd_ioctl(drv, param, blen, 1); - - os_free(param); - - return res; -} - - -static int prism2param(struct wpa_driver_hostap_data *drv, int param, - int value) -{ - struct iwreq iwr; - int *i, ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - i = (int *) iwr.u.name; - *i++ = param; - *i++ = value; - - if (ioctl(drv->sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) { - perror("ioctl[PRISM2_IOCTL_PRISM2_PARAM]"); - ret = -1; - } - return ret; -} - - -static int wpa_driver_hostap_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_hostap_data *drv = priv; - int ret = 0; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - - if (!enabled && wpa_driver_hostap_set_wpa_ie(drv, NULL, 0) < 0) - ret = -1; - if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING, enabled ? 2 : 0) < 0) - ret = -1; - if (prism2param(drv, PRISM2_PARAM_WPA, enabled) < 0) - ret = -1; - - return ret; -} - - -static void show_set_key_error(struct prism2_hostapd_param *param) -{ - switch (param->u.crypt.err) { - case HOSTAP_CRYPT_ERR_UNKNOWN_ALG: - wpa_printf(MSG_INFO, "Unknown algorithm '%s'.", - param->u.crypt.alg); - wpa_printf(MSG_INFO, "You may need to load kernel module to " - "register that algorithm."); - wpa_printf(MSG_INFO, "E.g., 'modprobe hostap_crypt_wep' for " - "WEP."); - break; - case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR: - wpa_printf(MSG_INFO, "Unknown address " MACSTR ".", - MAC2STR(param->sta_addr)); - break; - case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED: - wpa_printf(MSG_INFO, "Crypt algorithm initialization failed."); - break; - case HOSTAP_CRYPT_ERR_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "Key setting failed."); - break; - case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "TX key index setting failed."); - break; - case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED: - wpa_printf(MSG_INFO, "Card configuration failed."); - break; - } -} - - -static int wpa_driver_hostap_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_hostap_data *drv = priv; - struct prism2_hostapd_param *param; - u8 *buf; - size_t blen; - int ret = 0; - char *alg_name; - - switch (alg) { - case WPA_ALG_NONE: - alg_name = "none"; - break; - case WPA_ALG_WEP: - alg_name = "WEP"; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - break; - default: - return -1; - } - - wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - if (seq_len > 8) - return -2; - - blen = sizeof(*param) + key_len; - buf = os_zalloc(blen); - if (buf == NULL) - return -1; - - param = (struct prism2_hostapd_param *) buf; - param->cmd = PRISM2_SET_ENCRYPTION; - /* TODO: In theory, STA in client mode can use five keys; four default - * keys for receiving (with keyidx 0..3) and one individual key for - * both transmitting and receiving (keyidx 0) _unicast_ packets. Now, - * keyidx 0 is reserved for this unicast use and default keys can only - * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported). - * This should be fine for more or less all cases, but for completeness - * sake, the driver could be enhanced to support the missing key. */ -#if 0 - if (addr == NULL) - os_memset(param->sta_addr, 0xff, ETH_ALEN); - else - os_memcpy(param->sta_addr, addr, ETH_ALEN); -#else - os_memset(param->sta_addr, 0xff, ETH_ALEN); -#endif - os_strlcpy((char *) param->u.crypt.alg, alg_name, - HOSTAP_CRYPT_ALG_NAME_LEN); - param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; - param->u.crypt.idx = key_idx; - os_memcpy(param->u.crypt.seq, seq, seq_len); - param->u.crypt.key_len = key_len; - os_memcpy((u8 *) (param + 1), key, key_len); - - if (hostapd_ioctl(drv, param, blen, 1)) { - wpa_printf(MSG_WARNING, "Failed to set encryption."); - show_set_key_error(param); - ret = -1; - } - os_free(buf); - - return ret; -} - - -static int wpa_driver_hostap_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_hostap_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return prism2param(drv, PRISM2_PARAM_TKIP_COUNTERMEASURES, enabled); -} - - -static int wpa_driver_hostap_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_hostap_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return prism2param(drv, PRISM2_PARAM_DROP_UNENCRYPTED, enabled); -} - - -static int wpa_driver_hostap_reset(struct wpa_driver_hostap_data *drv, - int type) -{ - struct iwreq iwr; - int *i, ret = 0; - - wpa_printf(MSG_DEBUG, "%s: type=%d", __FUNCTION__, type); - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - i = (int *) iwr.u.name; - *i++ = type; - - if (ioctl(drv->sock, PRISM2_IOCTL_RESET, &iwr) < 0) { - perror("ioctl[PRISM2_IOCTL_RESET]"); - ret = -1; - } - return ret; -} - - -static int wpa_driver_hostap_mlme(struct wpa_driver_hostap_data *drv, - const u8 *addr, int cmd, int reason_code) -{ - struct prism2_hostapd_param param; - int ret; - - /* There does not seem to be a better way of deauthenticating or - * disassociating with Prism2/2.5/3 than sending the management frame - * and then resetting the Port0 to make sure both the AP and the STA - * end up in disconnected state. */ - os_memset(¶m, 0, sizeof(param)); - param.cmd = PRISM2_HOSTAPD_MLME; - os_memcpy(param.sta_addr, addr, ETH_ALEN); - param.u.mlme.cmd = cmd; - param.u.mlme.reason_code = reason_code; - ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1); - if (ret == 0) { - os_sleep(0, 100000); - ret = wpa_driver_hostap_reset(drv, 2); - } - return ret; -} - - -static int wpa_driver_hostap_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_hostap_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DEAUTH, - reason_code); -} - - -static int wpa_driver_hostap_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_hostap_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DISASSOC, - reason_code); -} - - -static int -wpa_driver_hostap_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_hostap_data *drv = priv; - int ret = 0; - int allow_unencrypted_eapol; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (params->mode != drv->current_mode) { - /* At the moment, Host AP driver requires host_roaming=2 for - * infrastructure mode and host_roaming=0 for adhoc. */ - if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING, - params->mode == IEEE80211_MODE_IBSS ? 0 : 2) < - 0) { - wpa_printf(MSG_DEBUG, "%s: failed to set host_roaming", - __func__); - } - drv->current_mode = params->mode; - } - - if (prism2param(drv, PRISM2_PARAM_PRIVACY_INVOKED, - params->key_mgmt_suite != KEY_MGMT_NONE) < 0) - ret = -1; - if (wpa_driver_hostap_set_wpa_ie(drv, params->wpa_ie, - params->wpa_ie_len) < 0) - ret = -1; - if (wpa_driver_wext_set_mode(drv->wext, params->mode) < 0) - ret = -1; - if (params->freq && - wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) - ret = -1; - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) - < 0) - ret = -1; - if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) - ret = -1; - - /* Allow unencrypted EAPOL messages even if pairwise keys are set when - * not using WPA. IEEE 802.1X specifies that these frames are not - * encrypted, but WPA encrypts them when pairwise keys are in use. */ - if (params->key_mgmt_suite == KEY_MGMT_802_1X || - params->key_mgmt_suite == KEY_MGMT_PSK) - allow_unencrypted_eapol = 0; - else - allow_unencrypted_eapol = 1; - - if (prism2param(drv, PRISM2_PARAM_IEEE_802_1X, - allow_unencrypted_eapol) < 0) { - wpa_printf(MSG_DEBUG, "hostap: Failed to configure " - "ieee_802_1x param"); - /* Ignore this error.. driver_hostap.c can also be used with - * other drivers that do not support this prism2_param. */ - } - - return ret; -} - - -static int wpa_driver_hostap_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_hostap_data *drv = priv; - struct prism2_hostapd_param param; - int ret; - - if (ssid == NULL) { - /* Use standard Linux Wireless Extensions ioctl if possible - * because some drivers using hostap code in wpa_supplicant - * might not support Host AP specific scan request (with SSID - * info). */ - return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); - } - - if (ssid_len > 32) - ssid_len = 32; - - os_memset(¶m, 0, sizeof(param)); - param.cmd = PRISM2_HOSTAPD_SCAN_REQ; - param.u.scan_req.ssid_len = ssid_len; - os_memcpy(param.u.scan_req.ssid, ssid, ssid_len); - ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1); - - /* Not all drivers generate "scan completed" wireless event, so try to - * read results after a timeout. */ - eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, - drv->ctx); - eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, drv->wext, - drv->ctx); - - return ret; -} - - -static int wpa_driver_hostap_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_hostap_data *drv = priv; - int algs = 0; - - if (auth_alg & AUTH_ALG_OPEN_SYSTEM) - algs |= 1; - if (auth_alg & AUTH_ALG_SHARED_KEY) - algs |= 2; - if (auth_alg & AUTH_ALG_LEAP) - algs |= 4; - if (algs == 0) - algs = 1; /* at least one algorithm should be set */ - - return prism2param(drv, PRISM2_PARAM_AP_AUTH_ALGS, algs); -} - - -static int wpa_driver_hostap_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_hostap_data *drv = priv; - return wpa_driver_wext_get_bssid(drv->wext, bssid); -} - - -static int wpa_driver_hostap_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_hostap_data *drv = priv; - return wpa_driver_wext_get_ssid(drv->wext, ssid); -} - - -static struct wpa_scan_results * wpa_driver_hostap_get_scan_results(void *priv) -{ - struct wpa_driver_hostap_data *drv = priv; - return wpa_driver_wext_get_scan_results(drv->wext); -} - - -static int wpa_driver_hostap_set_operstate(void *priv, int state) -{ - struct wpa_driver_hostap_data *drv = priv; - return wpa_driver_wext_set_operstate(drv->wext, state); -} - - -static void * wpa_driver_hostap_init(void *ctx, const char *ifname) -{ - struct wpa_driver_hostap_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->wext = wpa_driver_wext_init(ctx, ifname); - if (drv->wext == NULL) { - os_free(drv); - return NULL; - } - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) { - perror("socket"); - wpa_driver_wext_deinit(drv->wext); - os_free(drv); - return NULL; - } - - if (os_strncmp(ifname, "wlan", 4) == 0) { - /* - * Host AP driver may use both wlan# and wifi# interface in - * wireless events. - */ - char ifname2[IFNAMSIZ + 1]; - os_strlcpy(ifname2, ifname, sizeof(ifname2)); - os_memcpy(ifname2, "wifi", 4); - wpa_driver_wext_alternative_ifindex(drv->wext, ifname2); - } - - return drv; -} - - -static void wpa_driver_hostap_deinit(void *priv) -{ - struct wpa_driver_hostap_data *drv = priv; - wpa_driver_wext_deinit(drv->wext); - close(drv->sock); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_hostap_ops = { - .name = "hostap", - .desc = "Host AP driver (Intersil Prism2/2.5/3)", - .get_bssid = wpa_driver_hostap_get_bssid, - .get_ssid = wpa_driver_hostap_get_ssid, - .set_wpa = wpa_driver_hostap_set_wpa, - .set_key = wpa_driver_hostap_set_key, - .set_countermeasures = wpa_driver_hostap_set_countermeasures, - .set_drop_unencrypted = wpa_driver_hostap_set_drop_unencrypted, - .scan = wpa_driver_hostap_scan, - .get_scan_results2 = wpa_driver_hostap_get_scan_results, - .deauthenticate = wpa_driver_hostap_deauthenticate, - .disassociate = wpa_driver_hostap_disassociate, - .associate = wpa_driver_hostap_associate, - .set_auth_alg = wpa_driver_hostap_set_auth_alg, - .init = wpa_driver_hostap_init, - .deinit = wpa_driver_hostap_deinit, - .set_operstate = wpa_driver_hostap_set_operstate, -}; diff --git a/contrib/wpa/src/drivers/driver_hostap.h b/contrib/wpa/src/drivers/driver_hostap.h deleted file mode 100644 index a2508ed..0000000 --- a/contrib/wpa/src/drivers/driver_hostap.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Linux Host AP driver - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#ifndef HOSTAP_DRIVER_H -#define HOSTAP_DRIVER_H - -#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) -#define PRISM2_IOCTL_RESET (SIOCIWFIRSTPRIV + 6) -#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14) - -/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */ -enum { - /* PRISM2_PARAM_PTYPE = 1, */ /* REMOVED 2003-10-22 */ - PRISM2_PARAM_TXRATECTRL = 2, - PRISM2_PARAM_BEACON_INT = 3, - PRISM2_PARAM_PSEUDO_IBSS = 4, - PRISM2_PARAM_ALC = 5, - /* PRISM2_PARAM_TXPOWER = 6, */ /* REMOVED 2003-10-22 */ - PRISM2_PARAM_DUMP = 7, - PRISM2_PARAM_OTHER_AP_POLICY = 8, - PRISM2_PARAM_AP_MAX_INACTIVITY = 9, - PRISM2_PARAM_AP_BRIDGE_PACKETS = 10, - PRISM2_PARAM_DTIM_PERIOD = 11, - PRISM2_PARAM_AP_NULLFUNC_ACK = 12, - PRISM2_PARAM_MAX_WDS = 13, - PRISM2_PARAM_AP_AUTOM_AP_WDS = 14, - PRISM2_PARAM_AP_AUTH_ALGS = 15, - PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16, - PRISM2_PARAM_HOST_ENCRYPT = 17, - PRISM2_PARAM_HOST_DECRYPT = 18, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, - PRISM2_PARAM_HOST_ROAMING = 21, - PRISM2_PARAM_BCRX_STA_KEY = 22, - PRISM2_PARAM_IEEE_802_1X = 23, - PRISM2_PARAM_ANTSEL_TX = 24, - PRISM2_PARAM_ANTSEL_RX = 25, - PRISM2_PARAM_MONITOR_TYPE = 26, - PRISM2_PARAM_WDS_TYPE = 27, - PRISM2_PARAM_HOSTSCAN = 28, - PRISM2_PARAM_AP_SCAN = 29, - PRISM2_PARAM_ENH_SEC = 30, - PRISM2_PARAM_IO_DEBUG = 31, - PRISM2_PARAM_BASIC_RATES = 32, - PRISM2_PARAM_OPER_RATES = 33, - PRISM2_PARAM_HOSTAPD = 34, - PRISM2_PARAM_HOSTAPD_STA = 35, - PRISM2_PARAM_WPA = 36, - PRISM2_PARAM_PRIVACY_INVOKED = 37, - PRISM2_PARAM_TKIP_COUNTERMEASURES = 38, - PRISM2_PARAM_DROP_UNENCRYPTED = 39, - PRISM2_PARAM_SCAN_CHANNEL_MASK = 40, -}; - -/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */ -enum { - PRISM2_HOSTAPD_FLUSH = 1, - PRISM2_HOSTAPD_ADD_STA = 2, - PRISM2_HOSTAPD_REMOVE_STA = 3, - PRISM2_HOSTAPD_GET_INFO_STA = 4, - /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ - PRISM2_SET_ENCRYPTION = 6, - PRISM2_GET_ENCRYPTION = 7, - PRISM2_HOSTAPD_SET_FLAGS_STA = 8, - PRISM2_HOSTAPD_GET_RID = 9, - PRISM2_HOSTAPD_SET_RID = 10, - PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11, - PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12, - PRISM2_HOSTAPD_MLME = 13, - PRISM2_HOSTAPD_SCAN_REQ = 14, - PRISM2_HOSTAPD_STA_CLEAR_STATS = 15, -}; - -#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024 -#define PRISM2_HOSTAPD_RID_HDR_LEN \ -((size_t) (&((struct prism2_hostapd_param *) 0)->u.rid.data)) -#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \ -((size_t) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data)) - -/* Maximum length for algorithm names (-1 for nul termination) used in ioctl() - */ -#define HOSTAP_CRYPT_ALG_NAME_LEN 16 - - -struct prism2_hostapd_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u16 aid; - u16 capability; - u8 tx_supp_rates; - } add_sta; - struct { - u32 inactive_sec; - } get_info_sta; - struct { - u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN]; - u32 flags; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - struct { - u32 flags_and; - u32 flags_or; - } set_flags_sta; - struct { - u16 rid; - u16 len; - u8 data[0]; - } rid; - struct { - u8 len; - u8 data[0]; - } generic_elem; - struct { -#define MLME_STA_DEAUTH 0 -#define MLME_STA_DISASSOC 1 - u16 cmd; - u16 reason_code; - } mlme; - struct { - u8 ssid_len; - u8 ssid[32]; - } scan_req; - } u; -}; - -#define HOSTAP_CRYPT_FLAG_SET_TX_KEY 0x01 -#define HOSTAP_CRYPT_FLAG_PERMANENT 0x02 - -#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2 -#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 -#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 -#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7 - -#endif /* HOSTAP_DRIVER_H */ diff --git a/contrib/wpa/src/drivers/driver_iphone.m b/contrib/wpa/src/drivers/driver_iphone.m deleted file mode 100644 index 8e64ffd..0000000 --- a/contrib/wpa/src/drivers/driver_iphone.m +++ /dev/null @@ -1,466 +0,0 @@ -/* - * WPA Supplicant - iPhone/iPod touch Apple80211 driver interface - * Copyright (c) 2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#define Boolean __DummyBoolean -#include <CoreFoundation/CoreFoundation.h> -#undef Boolean - -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "ieee802_11_defs.h" - -#include "MobileApple80211.h" - -struct wpa_driver_iphone_data { - void *ctx; - Apple80211Ref wireless_ctx; - CFArrayRef scan_results; - int ctrl_power; -}; - - -static const void * cfdict_get_key_str(CFDictionaryRef dict, const char *key) -{ - const void *res; - CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, key, - kCFStringEncodingMacRoman); - if (str == NULL) - return NULL; - - res = CFDictionaryGetValue(dict, str); - CFRelease(str); - return res; -} - - -static int wpa_driver_iphone_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_iphone_data *drv = priv; - CFDataRef data; - int err, len; - - err = Apple80211CopyValue(drv->wireless_ctx, APPLE80211_VALUE_SSID, 0, - &data); - if (err != 0) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211CopyValue(SSID) " - "failed: %d", err); - return -1; - } - - len = CFDataGetLength(data); - if (len > 32) { - CFRelease(data); - return -1; - } - os_memcpy(ssid, CFDataGetBytePtr(data), len); - CFRelease(data); - - return len; -} - - -static int wpa_driver_iphone_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_iphone_data *drv = priv; - CFStringRef data; - int err; - int a1, a2, a3, a4, a5, a6; - - err = Apple80211CopyValue(drv->wireless_ctx, APPLE80211_VALUE_BSSID, 0, - &data); - if (err != 0) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211CopyValue(BSSID) " - "failed: %d", err); - return -1; - } - - sscanf(CFStringGetCStringPtr(data, kCFStringEncodingMacRoman), - "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6); - bssid[0] = a1; - bssid[1] = a2; - bssid[2] = a3; - bssid[3] = a4; - bssid[4] = a5; - bssid[5] = a6; - - CFRelease(data); - - return 0; -} - - -static void wpa_driver_iphone_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - - -static int wpa_driver_iphone_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_iphone_data *drv = priv; - int err; - - if (drv->scan_results) { - CFRelease(drv->scan_results); - drv->scan_results = NULL; - } - - err = Apple80211Scan(drv->wireless_ctx, &drv->scan_results, NULL); - if (err) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211Scan failed: %d", - err); - return -1; - } - - eloop_register_timeout(0, 0, wpa_driver_iphone_scan_timeout, drv, - drv->ctx); - return 0; -} - - -static int wpa_driver_iphone_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ - struct wpa_driver_iphone_data *drv = priv; - size_t i, num; - - if (drv->scan_results == NULL) - return 0; - - num = CFArrayGetCount(drv->scan_results); - if (num > max_size) - num = max_size; - os_memset(results, 0, num * sizeof(struct wpa_scan_result)); - - for (i = 0; i < num; i++) { - struct wpa_scan_result *res = &results[i]; - CFDictionaryRef dict = - CFArrayGetValueAtIndex(drv->scan_results, i); - CFDataRef data; - CFStringRef str; - CFNumberRef num; - int val; - - data = cfdict_get_key_str(dict, "SSID"); - if (data) { - res->ssid_len = CFDataGetLength(data); - if (res->ssid_len > 32) - res->ssid_len = 32; - os_memcpy(res->ssid, CFDataGetBytePtr(data), - res->ssid_len); - } - - str = cfdict_get_key_str(dict, "BSSID"); - if (str) { - int a1, a2, a3, a4, a5, a6; - sscanf(CFStringGetCStringPtr( - str, kCFStringEncodingMacRoman), - "%x:%x:%x:%x:%x:%x", - &a1, &a2, &a3, &a4, &a5, &a6); - res->bssid[0] = a1; - res->bssid[1] = a2; - res->bssid[2] = a3; - res->bssid[3] = a4; - res->bssid[4] = a5; - res->bssid[5] = a6; - } - - num = cfdict_get_key_str(dict, "CAPABILITIES"); - if (num) { - if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) - res->caps = val; - } - - num = cfdict_get_key_str(dict, "CHANNEL"); - if (num) { - if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) - res->freq = 2407 + val * 5; - } - - num = cfdict_get_key_str(dict, "RSSI"); - if (num) { - if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) - res->level = val; - } - - num = cfdict_get_key_str(dict, "NOISE"); - if (num) { - if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) - res->noise = val; - } - - data = cfdict_get_key_str(dict, "IE"); - if (data) { - u8 *ptr = (u8 *) CFDataGetBytePtr(data); - int len = CFDataGetLength(data); - u8 *pos = ptr, *end = ptr + len; - - while (pos + 2 < end) { - if (pos + 2 + pos[1] > end) - break; - if (pos[0] == WLAN_EID_RSN && - pos[1] <= SSID_MAX_WPA_IE_LEN) { - os_memcpy(res->rsn_ie, pos, - 2 + pos[1]); - res->rsn_ie_len = 2 + pos[1]; - } - if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && - pos[1] > 4 && pos[2] == 0x00 && - pos[3] == 0x50 && pos[4] == 0xf2 && - pos[5] == 0x01) { - os_memcpy(res->wpa_ie, pos, - 2 + pos[1]); - res->wpa_ie_len = 2 + pos[1]; - } - - pos = pos + 2 + pos[1]; - } - } - } - - return num; -} - - -static void wpa_driver_iphone_assoc_timeout(void *eloop_ctx, void *timeout_ctx) -{ - struct wpa_driver_iphone_data *drv = eloop_ctx; - u8 bssid[ETH_ALEN]; - - if (wpa_driver_iphone_get_bssid(drv, bssid) != 0) { - eloop_register_timeout(1, 0, wpa_driver_iphone_assoc_timeout, - drv, drv->ctx); - return; - } - - wpa_supplicant_event(timeout_ctx, EVENT_ASSOC, NULL); -} - - -static int wpa_driver_iphone_associate( - void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_iphone_data *drv = priv; - int i, num, err; - size_t ssid_len; - CFDictionaryRef bss = NULL; - - /* - * TODO: Consider generating parameters instead of just using an entry - * from scan results in order to support ap_scan=2. - */ - - if (drv->scan_results == NULL) { - wpa_printf(MSG_DEBUG, "iPhone: No scan results - cannot " - "associate"); - return -1; - } - - num = CFArrayGetCount(drv->scan_results); - - for (i = 0; i < num; i++) { - CFDictionaryRef dict = - CFArrayGetValueAtIndex(drv->scan_results, i); - CFDataRef data; - - data = cfdict_get_key_str(dict, "SSID"); - if (data == NULL) - continue; - - ssid_len = CFDataGetLength(data); - if (ssid_len != params->ssid_len || - os_memcmp(CFDataGetBytePtr(data), params->ssid, ssid_len) - != 0) - continue; - - bss = dict; - break; - } - - if (bss == NULL) { - wpa_printf(MSG_DEBUG, "iPhone: Could not find SSID from scan " - "results - cannot associate"); - return -1; - } - - wpa_printf(MSG_DEBUG, "iPhone: Trying to associate with a BSS found " - "from scan results"); - - err = Apple80211Associate(drv->wireless_ctx, bss, NULL); - if (err) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211Associate() failed: " - "%d", err); - return -1; - } - - /* - * Driver is actually already associated; report association from an - * eloop callback. - */ - eloop_cancel_timeout(wpa_driver_iphone_assoc_timeout, drv, drv->ctx); - eloop_register_timeout(0, 0, wpa_driver_iphone_assoc_timeout, drv, - drv->ctx); - - return 0; -} - - -static int wpa_driver_iphone_set_key(void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, const u8 *seq, - size_t seq_len, const u8 *key, - size_t key_len) -{ - /* - * TODO: Need to either support configuring PMK for 4-way handshake or - * PTK for TKIP/CCMP. - */ - return -1; -} - - -static int wpa_driver_iphone_get_capa(void *priv, struct wpa_driver_capa *capa) -{ - os_memset(capa, 0, sizeof(*capa)); - - capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; - capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104 | - WPA_DRIVER_CAPA_ENC_TKIP | WPA_DRIVER_CAPA_ENC_CCMP; - capa->auth = WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED | - WPA_DRIVER_AUTH_LEAP; - capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; - - return 0; -} - - -static void * wpa_driver_iphone_init(void *ctx, const char *ifname) -{ - struct wpa_driver_iphone_data *drv; - int err; - char power; - CFStringRef name; - CFDictionaryRef dict; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - err = Apple80211Open(&drv->wireless_ctx); - if (err) { - wpa_printf(MSG_ERROR, "iPhone: Apple80211Open failed: %d", - err); - os_free(drv); - return NULL; - } - - name = CFStringCreateWithCString(kCFAllocatorDefault, ifname, - kCFStringEncodingISOLatin1); - if (name == NULL) { - wpa_printf(MSG_ERROR, "iPhone: ifname -> CFString failed"); - Apple80211Close(drv->wireless_ctx); - os_free(drv); - return NULL; - } - - err = Apple80211BindToInterface(drv->wireless_ctx, name); - CFRelease(name); - - if (err) { - wpa_printf(MSG_ERROR, "iPhone: Apple80211BindToInterface " - "failed: %d", err); - Apple80211Close(drv->wireless_ctx); - os_free(drv); - return NULL; - } - - err = Apple80211GetPower(drv->wireless_ctx, &power); - if (err) - wpa_printf(MSG_DEBUG, "iPhone: Apple80211GetPower failed: %d", - err); - - wpa_printf(MSG_DEBUG, "iPhone: Power=%d", power); - - if (!power) { - drv->ctrl_power = 1; - err = Apple80211SetPower(drv->wireless_ctx, 1); - if (err) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211SetPower " - "failed: %d", err); - Apple80211Close(drv->wireless_ctx); - os_free(drv); - return NULL; - } - } - - err = Apple80211GetInfoCopy(drv->wireless_ctx, &dict); - if (err == 0) { - CFShow(dict); - CFRelease(dict); - } else { - printf("Apple80211GetInfoCopy: %d\n", err); - } - - return drv; -} - - -static void wpa_driver_iphone_deinit(void *priv) -{ - struct wpa_driver_iphone_data *drv = priv; - int err; - - eloop_cancel_timeout(wpa_driver_iphone_scan_timeout, drv, drv->ctx); - eloop_cancel_timeout(wpa_driver_iphone_assoc_timeout, drv, drv->ctx); - - if (drv->ctrl_power) { - wpa_printf(MSG_DEBUG, "iPhone: Power down the interface"); - err = Apple80211SetPower(drv->wireless_ctx, 0); - if (err) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211SetPower(0) " - "failed: %d", err); - } - } - - err = Apple80211Close(drv->wireless_ctx); - if (err) { - wpa_printf(MSG_DEBUG, "iPhone: Apple80211Close failed: %d", - err); - } - - if (drv->scan_results) - CFRelease(drv->scan_results); - - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_iphone_ops = { - .name = "iphone", - .desc = "iPhone/iPod touch Apple80211 driver", - .get_ssid = wpa_driver_iphone_get_ssid, - .get_bssid = wpa_driver_iphone_get_bssid, - .init = wpa_driver_iphone_init, - .deinit = wpa_driver_iphone_deinit, - .scan = wpa_driver_iphone_scan, - .get_scan_results = wpa_driver_iphone_get_scan_results, - .associate = wpa_driver_iphone_associate, - .set_key = wpa_driver_iphone_set_key, - .get_capa = wpa_driver_iphone_get_capa, -}; diff --git a/contrib/wpa/src/drivers/driver_ipw.c b/contrib/wpa/src/drivers/driver_ipw.c deleted file mode 100644 index 3c19ccc..0000000 --- a/contrib/wpa/src/drivers/driver_ipw.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Linux ipw2100/2200 drivers - * Copyright (c) 2005 Zhu Yi <yi.zhu@intel.com> - * Copyright (c) 2004 Lubomir Gelo <lgelo@cnc.sk> - * Copyright (c) 2003-2004, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * Please note that ipw2100/2200 drivers change to use generic Linux wireless - * extensions if the kernel includes support for WE-18 or newer (Linux 2.6.13 - * or newer). driver_wext.c should be used in those cases. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "driver_wext.h" - -struct wpa_driver_ipw_data { - void *wext; /* private data for driver_wext */ - void *ctx; - char ifname[IFNAMSIZ + 1]; - int sock; -}; - -/* following definitions must be kept in sync with ipw2100.c and ipw2200.c */ - -#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 - -#define IPW_CMD_SET_WPA_PARAM 1 -#define IPW_CMD_SET_WPA_IE 2 -#define IPW_CMD_SET_ENCRYPTION 3 -#define IPW_CMD_MLME 4 - -#define IPW_PARAM_WPA_ENABLED 1 -#define IPW_PARAM_TKIP_COUNTERMEASURES 2 -#define IPW_PARAM_DROP_UNENCRYPTED 3 -#define IPW_PARAM_PRIVACY_INVOKED 4 -#define IPW_PARAM_AUTH_ALGS 5 -#define IPW_PARAM_IEEE_802_1X 6 - -#define IPW_MLME_STA_DEAUTH 1 -#define IPW_MLME_STA_DISASSOC 2 - -#define IPW_CRYPT_ERR_UNKNOWN_ALG 2 -#define IPW_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IPW_CRYPT_ERR_KEY_SET_FAILED 5 -#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IPW_CRYPT_ERR_CARD_CONF_FAILED 7 - -#define IPW_CRYPT_ALG_NAME_LEN 16 - -struct ipw_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[0]; - } wpa_ie; - struct{ - u32 command; - u32 reason_code; - } mlme; - struct { - u8 alg[IPW_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; - u16 key_len; - u8 key[0]; - } crypt; - - } u; -}; - -/* end of ipw2100.c and ipw2200.c code */ - -static int ipw_ioctl(struct wpa_driver_ipw_data *drv, - struct ipw_param *param, int len, int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) param; - iwr.u.data.length = len; - - if (ioctl(drv->sock, IPW_IOCTL_WPA_SUPPLICANT, &iwr) < 0) { - int ret = errno; - if (show_err) - perror("ioctl[IPW_IOCTL_WPA_SUPPLICANT]"); - return ret; - } - - return 0; -} - - -static void ipw_show_set_key_error(struct ipw_param *param) -{ - switch (param->u.crypt.err) { - case IPW_CRYPT_ERR_UNKNOWN_ALG: - wpa_printf(MSG_INFO, "Unknown algorithm '%s'.", - param->u.crypt.alg); - wpa_printf(MSG_INFO, "You may need to load kernel module to " - "register that algorithm."); - wpa_printf(MSG_INFO, "E.g., 'modprobe ieee80211_crypt_wep' for" - " WEP."); - break; - case IPW_CRYPT_ERR_UNKNOWN_ADDR: - wpa_printf(MSG_INFO, "Unknown address " MACSTR ".", - MAC2STR(param->sta_addr)); - break; - case IPW_CRYPT_ERR_CRYPT_INIT_FAILED: - wpa_printf(MSG_INFO, "Crypt algorithm initialization failed."); - break; - case IPW_CRYPT_ERR_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "Key setting failed."); - break; - case IPW_CRYPT_ERR_TX_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "TX key index setting failed."); - break; - case IPW_CRYPT_ERR_CARD_CONF_FAILED: - wpa_printf(MSG_INFO, "Card configuration failed."); - break; - } -} - - -static int ipw_set_wpa_ie(struct wpa_driver_ipw_data *drv, - const u8 *wpa_ie, size_t wpa_ie_len) -{ - struct ipw_param *param; - int ret; - size_t blen = sizeof(*param) + wpa_ie_len; - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = IPW_CMD_SET_WPA_IE; - param->u.wpa_ie.len = wpa_ie_len; - os_memcpy(param->u.wpa_ie.data, wpa_ie, wpa_ie_len); - - ret = ipw_ioctl(drv, param, blen, 1); - - os_free(param); - return ret; -} - - -static int ipw_set_wpa_param(struct wpa_driver_ipw_data *drv, u8 name, - u32 value) -{ - struct ipw_param param; - - os_memset(¶m, 0, sizeof(param)); - param.cmd = IPW_CMD_SET_WPA_PARAM; - param.u.wpa_param.name = name; - param.u.wpa_param.value = value; - - return ipw_ioctl(drv, ¶m, sizeof(param), 1); -} - - -static int ipw_mlme(struct wpa_driver_ipw_data *drv, const u8 *addr, - int cmd, int reason) -{ - struct ipw_param param; - - os_memset(¶m, 0, sizeof(param)); - os_memcpy(param.sta_addr, addr, ETH_ALEN); - param.cmd = IPW_CMD_MLME; - param.u.mlme.command = cmd; - param.u.mlme.reason_code = reason; - - return ipw_ioctl(drv, ¶m, sizeof(param), 1); -} - - -static int wpa_driver_ipw_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_ipw_data *drv = priv; - int ret = 0; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - - if (!enabled && ipw_set_wpa_ie(drv, NULL, 0) < 0) - ret = -1; - - if (ipw_set_wpa_param(drv, IPW_PARAM_WPA_ENABLED, enabled) < 0) - ret = -1; - - return ret; -} - - -static int wpa_driver_ipw_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_ipw_data *drv = priv; - struct ipw_param *param; - u8 *buf; - size_t blen; - int ret = 0; - char *alg_name; - - switch (alg) { - case WPA_ALG_NONE: - alg_name = "none"; - break; - case WPA_ALG_WEP: - alg_name = "WEP"; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - break; - default: - return -1; - } - - wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - if (seq_len > 8) - return -2; - - blen = sizeof(*param) + key_len; - buf = os_zalloc(blen); - if (buf == NULL) - return -1; - - param = (struct ipw_param *) buf; - param->cmd = IPW_CMD_SET_ENCRYPTION; - os_memset(param->sta_addr, 0xff, ETH_ALEN); - os_strlcpy((char *) param->u.crypt.alg, alg_name, - IPW_CRYPT_ALG_NAME_LEN); - param->u.crypt.set_tx = set_tx ? 1 : 0; - param->u.crypt.idx = key_idx; - os_memcpy(param->u.crypt.seq, seq, seq_len); - param->u.crypt.key_len = key_len; - os_memcpy((u8 *) (param + 1), key, key_len); - - if (ipw_ioctl(drv, param, blen, 1)) { - wpa_printf(MSG_WARNING, "Failed to set encryption."); - ipw_show_set_key_error(param); - ret = -1; - } - os_free(buf); - - return ret; -} - - -static int wpa_driver_ipw_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_ipw_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return ipw_set_wpa_param(drv, IPW_PARAM_TKIP_COUNTERMEASURES, - enabled); - -} - - -static int wpa_driver_ipw_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_ipw_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return ipw_set_wpa_param(drv, IPW_PARAM_DROP_UNENCRYPTED, - enabled); -} - - -static int wpa_driver_ipw_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_ipw_data *drv = priv; - return ipw_mlme(drv, addr, IPW_MLME_STA_DEAUTH, reason_code); -} - - -static int wpa_driver_ipw_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_ipw_data *drv = priv; - return ipw_mlme(drv, addr, IPW_MLME_STA_DISASSOC, reason_code); -} - - -static int -wpa_driver_ipw_associate(void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_ipw_data *drv = priv; - int ret = 0; - int unencrypted_eapol; - - if (ipw_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) - ret = -1; - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, - params->ssid_len) < 0) - ret = -1; - if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) - ret = -1; - - if (params->key_mgmt_suite == KEY_MGMT_802_1X || - params->key_mgmt_suite == KEY_MGMT_PSK) - unencrypted_eapol = 0; - else - unencrypted_eapol = 1; - - if (ipw_set_wpa_param(drv, IPW_PARAM_IEEE_802_1X, - unencrypted_eapol) < 0) { - wpa_printf(MSG_DEBUG, "ipw: Failed to configure " - "ieee_802_1x param"); - } - - return ret; -} - - -static int wpa_driver_ipw_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_ipw_data *drv = priv; - int algs = 0; - - if (auth_alg & AUTH_ALG_OPEN_SYSTEM) - algs |= 1; - if (auth_alg & AUTH_ALG_SHARED_KEY) - algs |= 2; - if (auth_alg & AUTH_ALG_LEAP) - algs |= 4; - if (algs == 0) - algs = 1; /* at least one algorithm should be set */ - - wpa_printf(MSG_DEBUG, "%s: auth_alg=0x%x", __FUNCTION__, algs); - return ipw_set_wpa_param(drv, IPW_PARAM_AUTH_ALGS, algs); -} - - -static int wpa_driver_ipw_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_ipw_data *drv = priv; - return wpa_driver_wext_get_bssid(drv->wext, bssid); -} - - -static int wpa_driver_ipw_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_ipw_data *drv = priv; - return wpa_driver_wext_get_ssid(drv->wext, ssid); -} - - -static int wpa_driver_ipw_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_ipw_data *drv = priv; - return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); -} - - -static struct wpa_scan_results * wpa_driver_ipw_get_scan_results(void *priv) -{ - struct wpa_driver_ipw_data *drv = priv; - return wpa_driver_wext_get_scan_results(drv->wext); -} - - -static int wpa_driver_ipw_set_operstate(void *priv, int state) -{ - struct wpa_driver_ipw_data *drv = priv; - return wpa_driver_wext_set_operstate(drv->wext, state); -} - - -static void * wpa_driver_ipw_init(void *ctx, const char *ifname) -{ - struct wpa_driver_ipw_data *drv; - int ver; - - wpa_printf(MSG_DEBUG, "%s is called", __FUNCTION__); - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->wext = wpa_driver_wext_init(ctx, ifname); - if (drv->wext == NULL) { - os_free(drv); - return NULL; - } - - ver = wpa_driver_wext_get_version(drv->wext); - if (ver >= 18) { - wpa_printf(MSG_WARNING, "Linux wireless extensions version %d " - "detected.", ver); - wpa_printf(MSG_WARNING, "ipw2x00 driver uses driver_wext " - "(-Dwext) instead of driver_ipw."); - } - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) { - wpa_driver_wext_deinit(drv->wext); - os_free(drv); - return NULL; - } - - return drv; -} - - -static void wpa_driver_ipw_deinit(void *priv) -{ - struct wpa_driver_ipw_data *drv = priv; - wpa_driver_wext_deinit(drv->wext); - close(drv->sock); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_ipw_ops = { - .name = "ipw", - .desc = "Intel ipw2100/2200 driver (old; use wext with Linux 2.6.13 " - "or newer)", - .get_bssid = wpa_driver_ipw_get_bssid, - .get_ssid = wpa_driver_ipw_get_ssid, - .set_wpa = wpa_driver_ipw_set_wpa, - .set_key = wpa_driver_ipw_set_key, - .set_countermeasures = wpa_driver_ipw_set_countermeasures, - .set_drop_unencrypted = wpa_driver_ipw_set_drop_unencrypted, - .scan = wpa_driver_ipw_scan, - .get_scan_results2 = wpa_driver_ipw_get_scan_results, - .deauthenticate = wpa_driver_ipw_deauthenticate, - .disassociate = wpa_driver_ipw_disassociate, - .associate = wpa_driver_ipw_associate, - .set_auth_alg = wpa_driver_ipw_set_auth_alg, - .init = wpa_driver_ipw_init, - .deinit = wpa_driver_ipw_deinit, - .set_operstate = wpa_driver_ipw_set_operstate, -}; diff --git a/contrib/wpa/src/drivers/driver_madwifi.c b/contrib/wpa/src/drivers/driver_madwifi.c deleted file mode 100644 index 7521037..0000000 --- a/contrib/wpa/src/drivers/driver_madwifi.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * WPA Supplicant - driver interaction with MADWIFI 802.11 driver - * Copyright (c) 2004, Sam Leffler <sam@errno.com> - * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * Please note that madwifi supports WPA configuration via Linux wireless - * extensions and if the kernel includes support for this, driver_wext.c should - * be used instead of this driver wrapper. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "common.h" -#include "driver.h" -#include "driver_wext.h" -#include "eloop.h" -#include "ieee802_11_defs.h" -#include "wireless_copy.h" - -/* - * Avoid conflicts with wpa_supplicant definitions by undefining a definition. - */ -#undef WME_OUI_TYPE - -#include <include/compat.h> -#include <net80211/ieee80211.h> -#ifdef WME_NUM_AC -/* Assume this is built against BSD branch of madwifi driver. */ -#define MADWIFI_BSD -#include <net80211/_ieee80211.h> -#endif /* WME_NUM_AC */ -#include <net80211/ieee80211_crypto.h> -#include <net80211/ieee80211_ioctl.h> - - -#ifdef IEEE80211_IOCTL_SETWMMPARAMS -/* Assume this is built against madwifi-ng */ -#define MADWIFI_NG -#endif /* IEEE80211_IOCTL_SETWMMPARAMS */ - -struct wpa_driver_madwifi_data { - void *wext; /* private data for driver_wext */ - void *ctx; - char ifname[IFNAMSIZ + 1]; - int sock; -}; - -static int -set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len, - int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - if (len < IFNAMSIZ && - op != IEEE80211_IOCTL_SET_APPIEBUF) { - /* - * Argument data fits inline; put it there. - */ - os_memcpy(iwr.u.name, data, len); - } else { - /* - * Argument data too big for inline transfer; setup a - * parameter block instead; the kernel will transfer - * the data for the driver. - */ - iwr.u.data.pointer = data; - iwr.u.data.length = len; - } - - if (ioctl(drv->sock, op, &iwr) < 0) { - if (show_err) { -#ifdef MADWIFI_NG - int first = IEEE80211_IOCTL_SETPARAM; - int last = IEEE80211_IOCTL_KICKMAC; - static const char *opnames[] = { - "ioctl[IEEE80211_IOCTL_SETPARAM]", - "ioctl[IEEE80211_IOCTL_GETPARAM]", - "ioctl[IEEE80211_IOCTL_SETMODE]", - "ioctl[IEEE80211_IOCTL_GETMODE]", - "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]", - "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]", - "ioctl[IEEE80211_IOCTL_SETCHANLIST]", - "ioctl[IEEE80211_IOCTL_GETCHANLIST]", - "ioctl[IEEE80211_IOCTL_CHANSWITCH]", - NULL, - "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]", - "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]", - NULL, - "ioctl[IEEE80211_IOCTL_GETCHANINFO]", - "ioctl[IEEE80211_IOCTL_SETOPTIE]", - "ioctl[IEEE80211_IOCTL_GETOPTIE]", - "ioctl[IEEE80211_IOCTL_SETMLME]", - NULL, - "ioctl[IEEE80211_IOCTL_SETKEY]", - NULL, - "ioctl[IEEE80211_IOCTL_DELKEY]", - NULL, - "ioctl[IEEE80211_IOCTL_ADDMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_DELMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_WDSMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_WDSDELMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_KICKMAC]", - }; -#else /* MADWIFI_NG */ - int first = IEEE80211_IOCTL_SETPARAM; - int last = IEEE80211_IOCTL_CHANLIST; - static const char *opnames[] = { - "ioctl[IEEE80211_IOCTL_SETPARAM]", - "ioctl[IEEE80211_IOCTL_GETPARAM]", - "ioctl[IEEE80211_IOCTL_SETKEY]", - "ioctl[IEEE80211_IOCTL_GETKEY]", - "ioctl[IEEE80211_IOCTL_DELKEY]", - NULL, - "ioctl[IEEE80211_IOCTL_SETMLME]", - NULL, - "ioctl[IEEE80211_IOCTL_SETOPTIE]", - "ioctl[IEEE80211_IOCTL_GETOPTIE]", - "ioctl[IEEE80211_IOCTL_ADDMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_DELMAC]", - NULL, - "ioctl[IEEE80211_IOCTL_CHANLIST]", - }; -#endif /* MADWIFI_NG */ - int idx = op - first; - if (first <= op && op <= last && - idx < (int) (sizeof(opnames) / sizeof(opnames[0])) - && opnames[idx]) - perror(opnames[idx]); - else - perror("ioctl[unknown???]"); - } - return -1; - } - return 0; -} - -static int -set80211param(struct wpa_driver_madwifi_data *drv, int op, int arg, - int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.mode = op; - os_memcpy(iwr.u.name+sizeof(u32), &arg, sizeof(arg)); - - if (ioctl(drv->sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { - if (show_err) - perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); - return -1; - } - return 0; -} - -static int -wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data *drv, - const u8 *wpa_ie, size_t wpa_ie_len) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - /* NB: SETOPTIE is not fixed-size so must not be inlined */ - iwr.u.data.pointer = (void *) wpa_ie; - iwr.u.data.length = wpa_ie_len; - - if (ioctl(drv->sock, IEEE80211_IOCTL_SETOPTIE, &iwr) < 0) { - perror("ioctl[IEEE80211_IOCTL_SETOPTIE]"); - return -1; - } - return 0; -} - -static int -wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data *drv, int key_idx, - const u8 *addr) -{ - struct ieee80211req_del_key wk; - - wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx); - os_memset(&wk, 0, sizeof(wk)); - wk.idk_keyix = key_idx; - if (addr != NULL) - os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); - - return set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk), 1); -} - -static int -wpa_driver_madwifi_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_madwifi_data *drv = priv; - struct ieee80211req_key wk; - char *alg_name; - u_int8_t cipher; - - if (alg == WPA_ALG_NONE) - return wpa_driver_madwifi_del_key(drv, key_idx, addr); - - switch (alg) { - case WPA_ALG_WEP: - if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", - ETH_ALEN) == 0) { - /* - * madwifi did not seem to like static WEP key - * configuration with IEEE80211_IOCTL_SETKEY, so use - * Linux wireless extensions ioctl for this. - */ - return wpa_driver_wext_set_key(drv->wext, alg, addr, - key_idx, set_tx, - seq, seq_len, - key, key_len); - } - alg_name = "WEP"; - cipher = IEEE80211_CIPHER_WEP; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - cipher = IEEE80211_CIPHER_TKIP; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - cipher = IEEE80211_CIPHER_AES_CCM; - break; - default: - wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", - __FUNCTION__, alg); - return -1; - } - - wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - if (seq_len > sizeof(u_int64_t)) { - wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big", - __FUNCTION__, (unsigned long) seq_len); - return -2; - } - if (key_len > sizeof(wk.ik_keydata)) { - wpa_printf(MSG_DEBUG, "%s: key length %lu too big", - __FUNCTION__, (unsigned long) key_len); - return -3; - } - - os_memset(&wk, 0, sizeof(wk)); - wk.ik_type = cipher; - wk.ik_flags = IEEE80211_KEY_RECV; - if (addr == NULL || - os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) - wk.ik_flags |= IEEE80211_KEY_GROUP; - if (set_tx) { - wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT; - os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); - } else - os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN); - wk.ik_keyix = key_idx; - wk.ik_keylen = key_len; -#ifdef WORDS_BIGENDIAN -#define WPA_KEY_RSC_LEN 8 - { - size_t i; - u8 tmp[WPA_KEY_RSC_LEN]; - os_memset(tmp, 0, sizeof(tmp)); - for (i = 0; i < seq_len; i++) - tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; - os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); - } -#else /* WORDS_BIGENDIAN */ - os_memcpy(&wk.ik_keyrsc, seq, seq_len); -#endif /* WORDS_BIGENDIAN */ - os_memcpy(wk.ik_keydata, key, key_len); - - return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1); -} - -static int -wpa_driver_madwifi_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_madwifi_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled, 1); -} - - -static int -wpa_driver_madwifi_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_madwifi_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED, enabled, 1); -} - -static int -wpa_driver_madwifi_deauthenticate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_madwifi_data *drv = priv; - struct ieee80211req_mlme mlme; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - mlme.im_op = IEEE80211_MLME_DEAUTH; - mlme.im_reason = reason_code; - os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1); -} - -static int -wpa_driver_madwifi_disassociate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_madwifi_data *drv = priv; - struct ieee80211req_mlme mlme; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - mlme.im_op = IEEE80211_MLME_DISASSOC; - mlme.im_reason = reason_code; - os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1); -} - -static int -wpa_driver_madwifi_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_madwifi_data *drv = priv; - struct ieee80211req_mlme mlme; - int ret = 0, privacy = 1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - /* - * NB: Don't need to set the freq or cipher-related state as - * this is implied by the bssid which is used to locate - * the scanned node state which holds it. The ssid is - * needed to disambiguate an AP that broadcasts multiple - * ssid's but uses the same bssid. - */ - /* XXX error handling is wrong but unclear what to do... */ - if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie, - params->wpa_ie_len) < 0) - ret = -1; - - if (params->pairwise_suite == CIPHER_NONE && - params->group_suite == CIPHER_NONE && - params->key_mgmt_suite == KEY_MGMT_NONE && - params->wpa_ie_len == 0) - privacy = 0; - - if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0) - ret = -1; - - if (params->wpa_ie_len && - set80211param(drv, IEEE80211_PARAM_WPA, - params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1, 1) < 0) - ret = -1; - - if (params->bssid == NULL) { - /* ap_scan=2 mode - driver takes care of AP selection and - * roaming */ - /* FIX: this does not seem to work; would probably need to - * change something in the driver */ - if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) - ret = -1; - - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, - params->ssid_len) < 0) - ret = -1; - } else { - if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) - ret = -1; - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, - params->ssid_len) < 0) - ret = -1; - os_memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_ASSOC; - os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); - if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, - sizeof(mlme), 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed", - __func__); - ret = -1; - } - } - - return ret; -} - -static int -wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_madwifi_data *drv = priv; - int authmode; - - if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) && - (auth_alg & AUTH_ALG_SHARED_KEY)) - authmode = IEEE80211_AUTH_AUTO; - else if (auth_alg & AUTH_ALG_SHARED_KEY) - authmode = IEEE80211_AUTH_SHARED; - else - authmode = IEEE80211_AUTH_OPEN; - - return set80211param(drv, IEEE80211_PARAM_AUTHMODE, authmode, 1); -} - -static int -wpa_driver_madwifi_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_madwifi_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - /* set desired ssid before scan */ - /* FIX: scan should not break the current association, so using - * set_ssid may not be the best way of doing this.. */ - if (wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len) < 0) - ret = -1; - - if (ioctl(drv->sock, SIOCSIWSCAN, &iwr) < 0) { - perror("ioctl[SIOCSIWSCAN]"); - ret = -1; - } - - /* - * madwifi delivers a scan complete event so no need to poll, but - * register a backup timeout anyway to make sure that we recover even - * if the driver does not send this event for any reason. This timeout - * will only be used if the event is not delivered (event handler will - * cancel the timeout). - */ - eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, - drv->ctx); - eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext, - drv->ctx); - - return ret; -} - -static int wpa_driver_madwifi_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_madwifi_data *drv = priv; - return wpa_driver_wext_get_bssid(drv->wext, bssid); -} - - -static int wpa_driver_madwifi_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_madwifi_data *drv = priv; - return wpa_driver_wext_get_ssid(drv->wext, ssid); -} - - -static struct wpa_scan_results * -wpa_driver_madwifi_get_scan_results(void *priv) -{ - struct wpa_driver_madwifi_data *drv = priv; - return wpa_driver_wext_get_scan_results(drv->wext); -} - - -static int wpa_driver_madwifi_set_operstate(void *priv, int state) -{ - struct wpa_driver_madwifi_data *drv = priv; - return wpa_driver_wext_set_operstate(drv->wext, state); -} - - -static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies, - size_t ies_len) -{ - struct ieee80211req_getset_appiebuf *probe_req_ie; - int ret; - - probe_req_ie = os_malloc(sizeof(*probe_req_ie) + ies_len); - if (probe_req_ie == NULL) - return -1; - - probe_req_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_REQ; - probe_req_ie->app_buflen = ies_len; - os_memcpy(probe_req_ie->app_buf, ies, ies_len); - - ret = set80211priv(priv, IEEE80211_IOCTL_SET_APPIEBUF, probe_req_ie, - sizeof(struct ieee80211req_getset_appiebuf) + - ies_len, 1); - - os_free(probe_req_ie); - - return ret; -} - - -static void * wpa_driver_madwifi_init(void *ctx, const char *ifname) -{ - struct wpa_driver_madwifi_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->wext = wpa_driver_wext_init(ctx, ifname); - if (drv->wext == NULL) - goto fail; - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) - goto fail2; - - if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " - "roaming", __FUNCTION__); - goto fail3; - } - - if (set80211param(drv, IEEE80211_PARAM_WPA, 3, 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support", - __FUNCTION__); - goto fail3; - } - - return drv; - -fail3: - close(drv->sock); -fail2: - wpa_driver_wext_deinit(drv->wext); -fail: - os_free(drv); - return NULL; -} - - -static void wpa_driver_madwifi_deinit(void *priv) -{ - struct wpa_driver_madwifi_data *drv = priv; - - if (wpa_driver_madwifi_set_wpa_ie(drv, NULL, 0) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to clear WPA IE", - __FUNCTION__); - } - if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based " - "roaming", __FUNCTION__); - } - if (set80211param(drv, IEEE80211_PARAM_PRIVACY, 0, 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to disable forced Privacy " - "flag", __FUNCTION__); - } - if (set80211param(drv, IEEE80211_PARAM_WPA, 0, 1) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to disable WPA", - __FUNCTION__); - } - - wpa_driver_wext_deinit(drv->wext); - - close(drv->sock); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_madwifi_ops = { - .name = "madwifi", - .desc = "MADWIFI 802.11 support (Atheros, etc.)", - .get_bssid = wpa_driver_madwifi_get_bssid, - .get_ssid = wpa_driver_madwifi_get_ssid, - .set_key = wpa_driver_madwifi_set_key, - .init = wpa_driver_madwifi_init, - .deinit = wpa_driver_madwifi_deinit, - .set_countermeasures = wpa_driver_madwifi_set_countermeasures, - .set_drop_unencrypted = wpa_driver_madwifi_set_drop_unencrypted, - .scan = wpa_driver_madwifi_scan, - .get_scan_results2 = wpa_driver_madwifi_get_scan_results, - .deauthenticate = wpa_driver_madwifi_deauthenticate, - .disassociate = wpa_driver_madwifi_disassociate, - .associate = wpa_driver_madwifi_associate, - .set_auth_alg = wpa_driver_madwifi_set_auth_alg, - .set_operstate = wpa_driver_madwifi_set_operstate, - .set_probe_req_ie = wpa_driver_madwifi_set_probe_req_ie, -}; diff --git a/contrib/wpa/src/drivers/driver_nl80211.c b/contrib/wpa/src/drivers/driver_nl80211.c deleted file mode 100644 index 9ab6d17..0000000 --- a/contrib/wpa/src/drivers/driver_nl80211.c +++ /dev/null @@ -1,2766 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Linux nl80211/cfg80211 - * Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> -#include <net/if_arp.h> -#include <netlink/genl/genl.h> -#include <netlink/genl/family.h> -#include <netlink/genl/ctrl.h> -#include "nl80211_copy.h" -#ifdef CONFIG_CLIENT_MLME -#include <netpacket/packet.h> -#include <linux/if_ether.h> -#include "radiotap.h" -#include "radiotap_iter.h" -#endif /* CONFIG_CLIENT_MLME */ - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "ieee802_11_defs.h" - -#ifndef IFF_LOWER_UP -#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ -#endif -#ifndef IFF_DORMANT -#define IFF_DORMANT 0x20000 /* driver signals dormant */ -#endif - -#ifndef IF_OPER_DORMANT -#define IF_OPER_DORMANT 5 -#endif -#ifndef IF_OPER_UP -#define IF_OPER_UP 6 -#endif - - -struct wpa_driver_nl80211_data { - void *ctx; - int wext_event_sock; - int ioctl_sock; - char ifname[IFNAMSIZ + 1]; - int ifindex; - int if_removed; - u8 *assoc_req_ies; - size_t assoc_req_ies_len; - u8 *assoc_resp_ies; - size_t assoc_resp_ies_len; - struct wpa_driver_capa capa; - int has_capability; - int we_version_compiled; - - /* for set_auth_alg fallback */ - int use_crypt; - int auth_alg_fallback; - - int operstate; - - char mlmedev[IFNAMSIZ + 1]; - - int scan_complete_events; - - struct nl_handle *nl_handle; - struct nl_cache *nl_cache; - struct nl_cb *nl_cb; - struct genl_family *nl80211; - -#ifdef CONFIG_CLIENT_MLME - int monitor_sock; /* socket for monitor */ - int monitor_ifidx; -#endif /* CONFIG_CLIENT_MLME */ -}; - - -static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, - void *timeout_ctx); -static int wpa_driver_nl80211_set_mode(void *priv, int mode); -static int wpa_driver_nl80211_flush_pmkid(void *priv); -static int wpa_driver_nl80211_get_range(void *priv); -static void -wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv); - - -/* nl80211 code */ -static int ack_handler(struct nl_msg *msg, void *arg) -{ - int *err = arg; - *err = 0; - return NL_STOP; -} - -static int finish_handler(struct nl_msg *msg, void *arg) -{ - int *ret = arg; - *ret = 0; - return NL_SKIP; -} - -static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, - void *arg) -{ - int *ret = arg; - *ret = err->error; - return NL_SKIP; -} - -static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv, - struct nl_msg *msg, - int (*valid_handler)(struct nl_msg *, void *), - void *valid_data) -{ - struct nl_cb *cb; - int err = -ENOMEM; - - cb = nl_cb_clone(drv->nl_cb); - if (!cb) - goto out; - - err = nl_send_auto_complete(drv->nl_handle, msg); - if (err < 0) - goto out; - - err = 1; - - nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); - nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); - - if (valid_handler) - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, - valid_handler, valid_data); - - while (err > 0) - nl_recvmsgs(drv->nl_handle, cb); - out: - nl_cb_put(cb); - nlmsg_free(msg); - return err; -} - - -struct family_data { - const char *group; - int id; -}; - - -static int family_handler(struct nl_msg *msg, void *arg) -{ - struct family_data *res = arg; - struct nlattr *tb[CTRL_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct nlattr *mcgrp; - int i; - - nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - if (!tb[CTRL_ATTR_MCAST_GROUPS]) - return NL_SKIP; - - nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], i) { - struct nlattr *tb2[CTRL_ATTR_MCAST_GRP_MAX + 1]; - nla_parse(tb2, CTRL_ATTR_MCAST_GRP_MAX, nla_data(mcgrp), - nla_len(mcgrp), NULL); - if (!tb2[CTRL_ATTR_MCAST_GRP_NAME] || - !tb2[CTRL_ATTR_MCAST_GRP_ID] || - os_strncmp(nla_data(tb2[CTRL_ATTR_MCAST_GRP_NAME]), - res->group, - nla_len(tb2[CTRL_ATTR_MCAST_GRP_NAME])) != 0) - continue; - res->id = nla_get_u32(tb2[CTRL_ATTR_MCAST_GRP_ID]); - break; - }; - - return NL_SKIP; -} - - -static int nl_get_multicast_id(struct wpa_driver_nl80211_data *drv, - const char *family, const char *group) -{ - struct nl_msg *msg; - int ret = -1; - struct family_data res = { group, -ENOENT }; - - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - genlmsg_put(msg, 0, 0, genl_ctrl_resolve(drv->nl_handle, "nlctrl"), - 0, 0, CTRL_CMD_GETFAMILY, 0); - NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family); - - ret = send_and_recv_msgs(drv, msg, family_handler, &res); - msg = NULL; - if (ret == 0) - ret = res.id; - -nla_put_failure: - nlmsg_free(msg); - return ret; -} - - -static int wpa_driver_nl80211_send_oper_ifla( - struct wpa_driver_nl80211_data *drv, - int linkmode, int operstate) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifinfo; - char opts[16]; - } req; - struct rtattr *rta; - static int nl_seq; - ssize_t ret; - - os_memset(&req, 0, sizeof(req)); - - req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - req.hdr.nlmsg_type = RTM_SETLINK; - req.hdr.nlmsg_flags = NLM_F_REQUEST; - req.hdr.nlmsg_seq = ++nl_seq; - req.hdr.nlmsg_pid = 0; - - req.ifinfo.ifi_family = AF_UNSPEC; - req.ifinfo.ifi_type = 0; - req.ifinfo.ifi_index = drv->ifindex; - req.ifinfo.ifi_flags = 0; - req.ifinfo.ifi_change = 0; - - if (linkmode != -1) { - rta = aliasing_hide_typecast( - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), - struct rtattr); - rta->rta_type = IFLA_LINKMODE; - rta->rta_len = RTA_LENGTH(sizeof(char)); - *((char *) RTA_DATA(rta)) = linkmode; - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_LENGTH(sizeof(char)); - } - if (operstate != -1) { - rta = (struct rtattr *) - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)); - rta->rta_type = IFLA_OPERSTATE; - rta->rta_len = RTA_LENGTH(sizeof(char)); - *((char *) RTA_DATA(rta)) = operstate; - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_LENGTH(sizeof(char)); - } - - wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d", - linkmode, operstate); - - ret = send(drv->wext_event_sock, &req, req.hdr.nlmsg_len, 0); - if (ret < 0) { - wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: " - "%s (assume operstate is not supported)", - strerror(errno)); - } - - return ret < 0 ? -1 : 0; -} - - -static int wpa_driver_nl80211_set_auth_param( - struct wpa_driver_nl80211_data *drv, int idx, u32 value) -{ - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.param.flags = idx & IW_AUTH_INDEX; - iwr.u.param.value = value; - - if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) { - if (errno != EOPNOTSUPP) { - wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d " - "value 0x%x) failed: %s)", - idx, value, strerror(errno)); - } - ret = errno == EOPNOTSUPP ? -2 : -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) { - perror("ioctl[SIOCGIWAP]"); - ret = -1; - } - os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN); - - return ret; -} - - -static int wpa_driver_nl80211_set_bssid(void *priv, const u8 *bssid) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.ap_addr.sa_family = ARPHRD_ETHER; - if (bssid) - os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN); - else - os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN); - - if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) { - perror("ioctl[SIOCSIWAP]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.essid.pointer = (caddr_t) ssid; - iwr.u.essid.length = 32; - - if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { - perror("ioctl[SIOCGIWESSID]"); - ret = -1; - } else { - ret = iwr.u.essid.length; - if (ret > 32) - ret = 32; - /* Some drivers include nul termination in the SSID, so let's - * remove it here before further processing. WE-21 changes this - * to explicitly require the length _not_ to include nul - * termination. */ - if (ret > 0 && ssid[ret - 1] == '\0' && - drv->we_version_compiled < 21) - ret--; - } - - return ret; -} - - -static int wpa_driver_nl80211_set_ssid(void *priv, const u8 *ssid, - size_t ssid_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - char buf[33]; - - if (ssid_len > 32) - return -1; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - /* flags: 1 = ESSID is active, 0 = not (promiscuous) */ - iwr.u.essid.flags = (ssid_len != 0); - os_memset(buf, 0, sizeof(buf)); - os_memcpy(buf, ssid, ssid_len); - iwr.u.essid.pointer = (caddr_t) buf; - if (drv->we_version_compiled < 21) { - /* For historic reasons, set SSID length to include one extra - * character, C string nul termination, even though SSID is - * really an octet string that should not be presented as a C - * string. Some Linux drivers decrement the length by one and - * can thus end up missing the last octet of the SSID if the - * length is not incremented here. WE-21 changes this to - * explicitly require the length _not_ to include nul - * termination. */ - if (ssid_len) - ssid_len++; - } - iwr.u.essid.length = ssid_len; - - if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { - perror("ioctl[SIOCSIWESSID]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_set_freq(void *priv, int freq) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.freq.m = freq * 100000; - iwr.u.freq.e = 1; - - if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) { - perror("ioctl[SIOCSIWFREQ]"); - ret = -1; - } - - return ret; -} - - -static void -wpa_driver_nl80211_event_wireless_custom(void *ctx, char *custom) -{ - union wpa_event_data data; - - wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'", - custom); - - os_memset(&data, 0, sizeof(data)); - /* Host AP driver */ - if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { - data.michael_mic_failure.unicast = - os_strstr(custom, " unicast ") != NULL; - /* TODO: parse parameters(?) */ - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) { - char *spos; - int bytes; - - spos = custom + 17; - - bytes = strspn(spos, "0123456789abcdefABCDEF"); - if (!bytes || (bytes & 1)) - return; - bytes /= 2; - - data.assoc_info.req_ies = os_malloc(bytes); - if (data.assoc_info.req_ies == NULL) - return; - - data.assoc_info.req_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.req_ies, bytes); - - spos += bytes * 2; - - data.assoc_info.resp_ies = NULL; - data.assoc_info.resp_ies_len = 0; - - if (os_strncmp(spos, " RespIEs=", 9) == 0) { - spos += 9; - - bytes = strspn(spos, "0123456789abcdefABCDEF"); - if (!bytes || (bytes & 1)) - goto done; - bytes /= 2; - - data.assoc_info.resp_ies = os_malloc(bytes); - if (data.assoc_info.resp_ies == NULL) - goto done; - - data.assoc_info.resp_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.resp_ies, bytes); - } - - wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - - done: - os_free(data.assoc_info.resp_ies); - os_free(data.assoc_info.req_ies); -#ifdef CONFIG_PEERKEY - } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) { - if (hwaddr_aton(custom + 17, data.stkstart.peer)) { - wpa_printf(MSG_DEBUG, "WEXT: unrecognized " - "STKSTART.request '%s'", custom + 17); - return; - } - wpa_supplicant_event(ctx, EVENT_STKSTART, &data); -#endif /* CONFIG_PEERKEY */ - } -} - - -static int wpa_driver_nl80211_event_wireless_michaelmicfailure( - void *ctx, const char *ev, size_t len) -{ - const struct iw_michaelmicfailure *mic; - union wpa_event_data data; - - if (len < sizeof(*mic)) - return -1; - - mic = (const struct iw_michaelmicfailure *) ev; - - wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: " - "flags=0x%x src_addr=" MACSTR, mic->flags, - MAC2STR(mic->src_addr.sa_data)); - - os_memset(&data, 0, sizeof(data)); - data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP); - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - - return 0; -} - - -static int wpa_driver_nl80211_event_wireless_pmkidcand( - struct wpa_driver_nl80211_data *drv, const char *ev, size_t len) -{ - const struct iw_pmkid_cand *cand; - union wpa_event_data data; - const u8 *addr; - - if (len < sizeof(*cand)) - return -1; - - cand = (const struct iw_pmkid_cand *) ev; - addr = (const u8 *) cand->bssid.sa_data; - - wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: " - "flags=0x%x index=%d bssid=" MACSTR, cand->flags, - cand->index, MAC2STR(addr)); - - os_memset(&data, 0, sizeof(data)); - os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN); - data.pmkid_candidate.index = cand->index; - data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH; - wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data); - - return 0; -} - - -static int wpa_driver_nl80211_event_wireless_assocreqie( - struct wpa_driver_nl80211_data *drv, const char *ev, int len) -{ - if (len < 0) - return -1; - - wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev, - len); - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = os_malloc(len); - if (drv->assoc_req_ies == NULL) { - drv->assoc_req_ies_len = 0; - return -1; - } - os_memcpy(drv->assoc_req_ies, ev, len); - drv->assoc_req_ies_len = len; - - return 0; -} - - -static int wpa_driver_nl80211_event_wireless_assocrespie( - struct wpa_driver_nl80211_data *drv, const char *ev, int len) -{ - if (len < 0) - return -1; - - wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev, - len); - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = os_malloc(len); - if (drv->assoc_resp_ies == NULL) { - drv->assoc_resp_ies_len = 0; - return -1; - } - os_memcpy(drv->assoc_resp_ies, ev, len); - drv->assoc_resp_ies_len = len; - - return 0; -} - - -static void wpa_driver_nl80211_event_assoc_ies(struct wpa_driver_nl80211_data *drv) -{ - union wpa_event_data data; - - if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL) - return; - - os_memset(&data, 0, sizeof(data)); - if (drv->assoc_req_ies) { - data.assoc_info.req_ies = drv->assoc_req_ies; - drv->assoc_req_ies = NULL; - data.assoc_info.req_ies_len = drv->assoc_req_ies_len; - } - if (drv->assoc_resp_ies) { - data.assoc_info.resp_ies = drv->assoc_resp_ies; - drv->assoc_resp_ies = NULL; - data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len; - } - - wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); - - os_free(data.assoc_info.req_ies); - os_free(data.assoc_info.resp_ies); -} - - -static void wpa_driver_nl80211_event_wireless(struct wpa_driver_nl80211_data *drv, - void *ctx, char *data, int len) -{ - struct iw_event iwe_buf, *iwe = &iwe_buf; - char *pos, *end, *custom, *buf; - - pos = data; - end = data + len; - - while (pos + IW_EV_LCP_LEN <= end) { - /* Event data may be unaligned, so make a local, aligned copy - * before processing. */ - os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); - wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", - iwe->cmd, iwe->len); - if (iwe->len <= IW_EV_LCP_LEN) - return; - - custom = pos + IW_EV_POINT_LEN; - if (drv->we_version_compiled > 18 && - (iwe->cmd == IWEVMICHAELMICFAILURE || - iwe->cmd == IWEVCUSTOM || - iwe->cmd == IWEVASSOCREQIE || - iwe->cmd == IWEVASSOCRESPIE || - iwe->cmd == IWEVPMKIDCAND)) { - /* WE-19 removed the pointer from struct iw_point */ - char *dpos = (char *) &iwe_buf.u.data.length; - int dlen = dpos - (char *) &iwe_buf; - os_memcpy(dpos, pos + IW_EV_LCP_LEN, - sizeof(struct iw_event) - dlen); - } else { - os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); - custom += IW_EV_POINT_OFF; - } - - switch (iwe->cmd) { - case SIOCGIWAP: - wpa_printf(MSG_DEBUG, "Wireless event: new AP: " - MACSTR, - MAC2STR((u8 *) iwe->u.ap_addr.sa_data)); - if (is_zero_ether_addr( - (const u8 *) iwe->u.ap_addr.sa_data) || - os_memcmp(iwe->u.ap_addr.sa_data, - "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == - 0) { - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = NULL; - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = NULL; - wpa_supplicant_event(ctx, EVENT_DISASSOC, - NULL); - - } else { - wpa_driver_nl80211_event_assoc_ies(drv); - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - } - break; - case IWEVMICHAELMICFAILURE: - wpa_driver_nl80211_event_wireless_michaelmicfailure( - ctx, custom, iwe->u.data.length); - break; - case IWEVCUSTOM: - if (custom + iwe->u.data.length > end) - return; - buf = os_malloc(iwe->u.data.length + 1); - if (buf == NULL) - return; - os_memcpy(buf, custom, iwe->u.data.length); - buf[iwe->u.data.length] = '\0'; - wpa_driver_nl80211_event_wireless_custom(ctx, buf); - os_free(buf); - break; - case IWEVASSOCREQIE: - wpa_driver_nl80211_event_wireless_assocreqie( - drv, custom, iwe->u.data.length); - break; - case IWEVASSOCRESPIE: - wpa_driver_nl80211_event_wireless_assocrespie( - drv, custom, iwe->u.data.length); - break; - case IWEVPMKIDCAND: - wpa_driver_nl80211_event_wireless_pmkidcand( - drv, custom, iwe->u.data.length); - break; - } - - pos += iwe->len; - } -} - - -static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv, - void *ctx, char *buf, size_t len, - int del) -{ - union wpa_event_data event; - - os_memset(&event, 0, sizeof(event)); - if (len > sizeof(event.interface_status.ifname)) - len = sizeof(event.interface_status.ifname) - 1; - os_memcpy(event.interface_status.ifname, buf, len); - event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED : - EVENT_INTERFACE_ADDED; - - wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s", - del ? "DEL" : "NEW", - event.interface_status.ifname, - del ? "removed" : "added"); - - if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) { - if (del) - drv->if_removed = 1; - else - drv->if_removed = 0; - } - - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); -} - - -static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv, - struct nlmsghdr *h) -{ - struct ifinfomsg *ifi; - int attrlen, _nlmsg_len, rta_len; - struct rtattr *attr; - - ifi = NLMSG_DATA(h); - - _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - _nlmsg_len; - if (attrlen < 0) - return 0; - - attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_IFNAME) { - if (os_strcmp(((char *) attr) + rta_len, drv->ifname) - == 0) - return 1; - else - break; - } - attr = RTA_NEXT(attr, attrlen); - } - - return 0; -} - - -static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv, - int ifindex, struct nlmsghdr *h) -{ - if (drv->ifindex == ifindex) - return 1; - - if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, h)) { - drv->ifindex = if_nametoindex(drv->ifname); - wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed " - "interface"); - wpa_driver_nl80211_finish_drv_init(drv); - return 1; - } - - return 0; -} - - -static void wpa_driver_nl80211_event_rtm_newlink(struct wpa_driver_nl80211_data *drv, - void *ctx, struct nlmsghdr *h, - size_t len) -{ - struct ifinfomsg *ifi; - int attrlen, _nlmsg_len, rta_len; - struct rtattr * attr; - - if (len < sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); - - if (!wpa_driver_nl80211_own_ifindex(drv, ifi->ifi_index, h)) { - wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d", - ifi->ifi_index); - return; - } - - wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x " - "(%s%s%s%s)", - drv->operstate, ifi->ifi_flags, - (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", - (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", - (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", - (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); - /* - * Some drivers send the association event before the operup event--in - * this case, lifting operstate in wpa_driver_nl80211_set_operstate() - * fails. This will hit us when wpa_supplicant does not need to do - * IEEE 802.1X authentication - */ - if (drv->operstate == 1 && - (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP && - !(ifi->ifi_flags & IFF_RUNNING)) - wpa_driver_nl80211_send_oper_ifla(drv, -1, IF_OPER_UP); - - _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - _nlmsg_len; - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_WIRELESS) { - wpa_driver_nl80211_event_wireless( - drv, ctx, ((char *) attr) + rta_len, - attr->rta_len - rta_len); - } else if (attr->rta_type == IFLA_IFNAME) { - wpa_driver_nl80211_event_link( - drv, ctx, - ((char *) attr) + rta_len, - attr->rta_len - rta_len, 0); - } - attr = RTA_NEXT(attr, attrlen); - } -} - - -static void wpa_driver_nl80211_event_rtm_dellink(struct wpa_driver_nl80211_data *drv, - void *ctx, struct nlmsghdr *h, - size_t len) -{ - struct ifinfomsg *ifi; - int attrlen, _nlmsg_len, rta_len; - struct rtattr * attr; - - if (len < sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); - - _nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - _nlmsg_len; - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + _nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_IFNAME) { - wpa_driver_nl80211_event_link( - drv, ctx, - ((char *) attr) + rta_len, - attr->rta_len - rta_len, 1); - } - attr = RTA_NEXT(attr, attrlen); - } -} - - -static void wpa_driver_nl80211_event_receive_wext(int sock, void *eloop_ctx, - void *sock_ctx) -{ - char buf[8192]; - int left; - struct sockaddr_nl from; - socklen_t fromlen; - struct nlmsghdr *h; - int max_events = 10; - -try_again: - fromlen = sizeof(from); - left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *) &from, &fromlen); - if (left < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("recvfrom(netlink)"); - return; - } - - h = (struct nlmsghdr *) buf; - while (left >= (int) sizeof(*h)) { - int len, plen; - - len = h->nlmsg_len; - plen = len - sizeof(*h); - if (len > left || plen < 0) { - wpa_printf(MSG_DEBUG, "Malformed netlink message: " - "len=%d left=%d plen=%d", - len, left, plen); - break; - } - - switch (h->nlmsg_type) { - case RTM_NEWLINK: - wpa_driver_nl80211_event_rtm_newlink(eloop_ctx, sock_ctx, - h, plen); - break; - case RTM_DELLINK: - wpa_driver_nl80211_event_rtm_dellink(eloop_ctx, sock_ctx, - h, plen); - break; - } - - len = NLMSG_ALIGN(len); - left -= len; - h = (struct nlmsghdr *) ((char *) h + len); - } - - if (left > 0) { - wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink " - "message", left); - } - - if (--max_events > 0) { - /* - * Try to receive all events in one eloop call in order to - * limit race condition on cases where AssocInfo event, Assoc - * event, and EAPOL frames are received more or less at the - * same time. We want to process the event messages first - * before starting EAPOL processing. - */ - goto try_again; - } -} - - -static int no_seq_check(struct nl_msg *msg, void *arg) -{ - return NL_OK; -} - - -static int process_event(struct nl_msg *msg, void *arg) -{ - struct wpa_driver_nl80211_data *drv = arg; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct nlattr *tb[NL80211_ATTR_MAX + 1]; - - nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (tb[NL80211_ATTR_IFINDEX]) { - int ifindex = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); - if (ifindex != drv->ifindex) { - wpa_printf(MSG_DEBUG, "nl80211: Ignored event (cmd=%d)" - " for foreign interface (ifindex %d)", - gnlh->cmd, ifindex); - return NL_SKIP; - } - } - - switch (gnlh->cmd) { - case NL80211_CMD_TRIGGER_SCAN: - wpa_printf(MSG_DEBUG, "nl80211: Scan trigger"); - break; - case NL80211_CMD_NEW_SCAN_RESULTS: - wpa_printf(MSG_DEBUG, "nl80211: New scan results available"); - drv->scan_complete_events = 1; - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, - drv->ctx); - wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL); - break; - case NL80211_CMD_SCAN_ABORTED: - wpa_printf(MSG_DEBUG, "nl80211: Scan aborted"); - /* - * Need to indicate that scan results are available in order - * not to make wpa_supplicant stop its scanning. - */ - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, - drv->ctx); - wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL); - break; - default: - wpa_printf(MSG_DEBUG, "nl0211: Ignored unknown event (cmd=%d)", - gnlh->cmd); - break; - } - - return NL_SKIP; -} - - -static void wpa_driver_nl80211_event_receive(int sock, void *eloop_ctx, - void *sock_ctx) -{ - struct nl_cb *cb; - struct wpa_driver_nl80211_data *drv = eloop_ctx; - - wpa_printf(MSG_DEBUG, "nl80211: Event message available"); - - cb = nl_cb_clone(drv->nl_cb); - if (!cb) - return; - nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, process_event, drv); - nl_recvmsgs(drv->nl_handle, cb); - nl_cb_put(cb); -} - - -static int wpa_driver_nl80211_get_ifflags_ifname(struct wpa_driver_nl80211_data *drv, - const char *ifname, int *flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - perror("ioctl[SIOCGIFFLAGS]"); - return -1; - } - *flags = ifr.ifr_flags & 0xffff; - return 0; -} - - -/** - * wpa_driver_nl80211_get_ifflags - Get interface flags (SIOCGIFFLAGS) - * @drv: driver_nl80211 private data - * @flags: Pointer to returned flags value - * Returns: 0 on success, -1 on failure - */ -static int wpa_driver_nl80211_get_ifflags(struct wpa_driver_nl80211_data *drv, - int *flags) -{ - return wpa_driver_nl80211_get_ifflags_ifname(drv, drv->ifname, flags); -} - - -static int wpa_driver_nl80211_set_ifflags_ifname( - struct wpa_driver_nl80211_data *drv, - const char *ifname, int flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_flags = flags & 0xffff; - if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - perror("SIOCSIFFLAGS"); - return -1; - } - return 0; -} - - -/** - * wpa_driver_nl80211_set_ifflags - Set interface flags (SIOCSIFFLAGS) - * @drv: driver_nl80211 private data - * @flags: New value for flags - * Returns: 0 on success, -1 on failure - */ -static int wpa_driver_nl80211_set_ifflags(struct wpa_driver_nl80211_data *drv, - int flags) -{ - return wpa_driver_nl80211_set_ifflags_ifname(drv, drv->ifname, flags); -} - - -/** - * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain - * @priv: driver_nl80211 private data - * @alpha2_arg: country to which to switch to - * Returns: 0 on success, -1 on failure - * - * This asks nl80211 to set the regulatory domain for given - * country ISO / IEC alpha2. - */ -static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg) -{ - struct wpa_driver_nl80211_data *drv = priv; - char alpha2[3]; - struct nl_msg *msg; - - msg = nlmsg_alloc(); - if (!msg) - goto nla_put_failure; - - alpha2[0] = alpha2_arg[0]; - alpha2[1] = alpha2_arg[1]; - alpha2[2] = '\0'; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_REQ_SET_REG, 0); - - NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2); - if (send_and_recv_msgs(drv, msg, NULL, NULL)) - return -EINVAL; - return 0; -nla_put_failure: - return -EINVAL; -} - - -static int wpa_driver_nl80211_set_probe_req_ie(void *priv, const u8 *ies, - size_t ies_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct nl_msg *msg; - int ret = -1; - - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, - NL80211_CMD_SET_MGMT_EXTRA_IE, 0); - - NLA_PUT_U8(msg, NL80211_ATTR_MGMT_SUBTYPE, 4 /* ProbeReq */); - if (ies) - NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies); - - ret = 0; - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - return ret; - -nla_put_failure: - return -ENOBUFS; -} - - -#ifdef CONFIG_CLIENT_MLME - -static int nl80211_set_vif(struct wpa_driver_nl80211_data *drv, - int drop_unencrypted, int userspace_mlme) -{ -#ifdef NL80211_CMD_SET_VIF - struct nl_msg *msg; - int ret = -1; - - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, - NL80211_CMD_SET_VIF, 0); - - if (drop_unencrypted >= 0) - NLA_PUT_U8(msg, NL80211_ATTR_VIF_DROP_UNENCRYPTED, - drop_unencrypted); - if (userspace_mlme >= 0) - NLA_PUT_U8(msg, NL80211_ATTR_VIF_USERSPACE_MLME, - userspace_mlme); - - ret = 0; - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - return ret; - -nla_put_failure: - return -ENOBUFS; -#else /* NL80211_CMD_SET_VIF */ - return -1; -#endif /* NL80211_CMD_SET_VIF */ -} - - -static int wpa_driver_nl80211_set_userspace_mlme( - struct wpa_driver_nl80211_data *drv, int enabled) -{ - return nl80211_set_vif(drv, -1, enabled); -} - - -static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, - int ifidx) -{ - struct nl_msg *msg; - - msg = nlmsg_alloc(); - if (!msg) - goto nla_put_failure; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_DEL_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx); - if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0) - return; -nla_put_failure: - wpa_printf(MSG_ERROR, "nl80211: Failed to remove interface."); -} - - -static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv, - const char *ifname, enum nl80211_iftype iftype) -{ - struct nl_msg *msg, *flags = NULL; - int ifidx, err; - int ret = -ENOBUFS; - - msg = nlmsg_alloc(); - if (!msg) - return -1; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_NEW_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname)); - NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname); - NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype); - - if (iftype == NL80211_IFTYPE_MONITOR) { - flags = nlmsg_alloc(); - if (!flags) - goto nla_put_failure; - - NLA_PUT_FLAG(flags, NL80211_MNTR_FLAG_COOK_FRAMES); - - err = nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags); - - nlmsg_free(flags); - - if (err) - goto nla_put_failure; - } - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - if (ret) { - nla_put_failure: - wpa_printf(MSG_ERROR, "nl80211: Failed to create interface %d", - ret); - return ret; - } - - ifidx = if_nametoindex(ifname); - if (ifidx <= 0) - return -1; - - return ifidx; -} - - -static void handle_monitor_read(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct wpa_driver_nl80211_data *drv = eloop_ctx; - int len; - unsigned char buf[3000]; - struct ieee80211_radiotap_iterator iter; - int ret; - int injected = 0, failed = 0, rxflags = 0; - struct ieee80211_rx_status rx_status; - - len = recv(sock, buf, sizeof(buf), 0); - if (len < 0) { - perror("recv"); - return; - } - - if (ieee80211_radiotap_iterator_init(&iter, (void *) buf, len)) { - wpa_printf(MSG_DEBUG, "nl80211: received invalid radiotap " - "frame"); - return; - } - - os_memset(&rx_status, 0, sizeof(rx_status)); - - while (1) { - ret = ieee80211_radiotap_iterator_next(&iter); - if (ret == -ENOENT) - break; - if (ret) { - wpa_printf(MSG_DEBUG, "nl80211: received invalid " - "radiotap frame (%d)", ret); - return; - } - switch (iter.this_arg_index) { - case IEEE80211_RADIOTAP_FLAGS: - if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS) - len -= 4; - break; - case IEEE80211_RADIOTAP_RX_FLAGS: - rxflags = 1; - break; - case IEEE80211_RADIOTAP_TX_FLAGS: - injected = 1; - failed = le_to_host16((*(u16 *) iter.this_arg)) & - IEEE80211_RADIOTAP_F_TX_FAIL; - break; - case IEEE80211_RADIOTAP_DATA_RETRIES: - break; - case IEEE80211_RADIOTAP_CHANNEL: - /* TODO convert from freq/flags to channel number - * rx_status.channel = XXX; - */ - break; - case IEEE80211_RADIOTAP_RATE: - break; - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - rx_status.ssi = *iter.this_arg; - break; - } - } - - if (rxflags && injected) - return; - - if (!injected) { - wpa_supplicant_sta_rx(drv->ctx, buf + iter.max_length, - len - iter.max_length, &rx_status); - } else if (failed) { - /* TX failure callback */ - } else { - /* TX success (ACK) callback */ - } -} - - -static int wpa_driver_nl80211_create_monitor_interface( - struct wpa_driver_nl80211_data *drv) -{ - char buf[IFNAMSIZ]; - struct sockaddr_ll ll; - int optval, flags; - socklen_t optlen; - - os_snprintf(buf, IFNAMSIZ, "mon.%s", drv->ifname); - buf[IFNAMSIZ - 1] = '\0'; - - drv->monitor_ifidx = - nl80211_create_iface(drv, buf, NL80211_IFTYPE_MONITOR); - - if (drv->monitor_ifidx < 0) - return -1; - - if (wpa_driver_nl80211_get_ifflags_ifname(drv, buf, &flags) != 0 || - wpa_driver_nl80211_set_ifflags_ifname(drv, buf, flags | IFF_UP) != - 0) { - wpa_printf(MSG_ERROR, "nl80211: Could not set interface '%s' " - "UP", buf); - goto error; - } - - os_memset(&ll, 0, sizeof(ll)); - ll.sll_family = AF_PACKET; - ll.sll_ifindex = drv->monitor_ifidx; - drv->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (drv->monitor_sock < 0) { - perror("socket[PF_PACKET,SOCK_RAW]"); - goto error; - } - - if (bind(drv->monitor_sock, (struct sockaddr *) &ll, - sizeof(ll)) < 0) { - perror("monitor socket bind"); - goto error; - } - - optlen = sizeof(optval); - optval = 20; - if (setsockopt - (drv->monitor_sock, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) { - perror("Failed to set socket priority"); - goto error; - } - - if (eloop_register_read_sock(drv->monitor_sock, handle_monitor_read, - drv, NULL)) { - wpa_printf(MSG_ERROR, "nl80211: Could not register monitor " - "read socket"); - goto error; - } - - return 0; - - error: - nl80211_remove_iface(drv, drv->monitor_ifidx); - return -1; -} - -#endif /* CONFIG_CLIENT_MLME */ - - -/** - * wpa_driver_nl80211_init - Initialize nl80211 driver interface - * @ctx: context to be used when calling wpa_supplicant functions, - * e.g., wpa_supplicant_event() - * @ifname: interface name, e.g., wlan0 - * Returns: Pointer to private data, %NULL on failure - */ -static void * wpa_driver_nl80211_init(void *ctx, const char *ifname) -{ - int s, ret; - struct sockaddr_nl local; - struct wpa_driver_nl80211_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - - drv->nl_cb = nl_cb_alloc(NL_CB_DEFAULT); - if (drv->nl_cb == NULL) { - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink " - "callbacks"); - goto err1; - } - - drv->nl_handle = nl_handle_alloc_cb(drv->nl_cb); - if (drv->nl_handle == NULL) { - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate netlink " - "callbacks"); - goto err2; - } - - if (genl_connect(drv->nl_handle)) { - wpa_printf(MSG_ERROR, "nl80211: Failed to connect to generic " - "netlink"); - goto err3; - } - - drv->nl_cache = genl_ctrl_alloc_cache(drv->nl_handle); - if (drv->nl_cache == NULL) { - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate generic " - "netlink cache"); - goto err3; - } - - drv->nl80211 = genl_ctrl_search_by_name(drv->nl_cache, "nl80211"); - if (drv->nl80211 == NULL) { - wpa_printf(MSG_ERROR, "nl80211: 'nl80211' generic netlink not " - "found"); - goto err4; - } - - ret = nl_get_multicast_id(drv, "nl80211", "scan"); - if (ret >= 0) - ret = nl_socket_add_membership(drv->nl_handle, ret); - if (ret < 0) { - wpa_printf(MSG_ERROR, "nl80211: Could not add multicast " - "membership for scan events: %d (%s)", - ret, strerror(-ret)); - goto err4; - } - eloop_register_read_sock(nl_socket_get_fd(drv->nl_handle), - wpa_driver_nl80211_event_receive, drv, ctx); - - drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->ioctl_sock < 0) { - perror("socket(PF_INET,SOCK_DGRAM)"); - goto err5; - } - - s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (s < 0) { - perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); - goto err6; - } - - os_memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = RTMGRP_LINK; - if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { - perror("bind(netlink)"); - close(s); - goto err6; - } - - eloop_register_read_sock(s, wpa_driver_nl80211_event_receive_wext, drv, - ctx); - drv->wext_event_sock = s; - - wpa_driver_nl80211_finish_drv_init(drv); - - return drv; - -err6: - close(drv->ioctl_sock); -err5: - genl_family_put(drv->nl80211); -err4: - nl_cache_free(drv->nl_cache); -err3: - nl_handle_destroy(drv->nl_handle); -err2: - nl_cb_put(drv->nl_cb); -err1: - os_free(drv); - return NULL; -} - - -static void -wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv) -{ - int flags; - - drv->ifindex = if_nametoindex(drv->ifname); - - if (wpa_driver_nl80211_set_mode(drv, 0) < 0) { - printf("Could not configure driver to use managed mode\n"); - } - - if (wpa_driver_nl80211_get_ifflags(drv, &flags) != 0) - printf("Could not get interface '%s' flags\n", drv->ifname); - else if (!(flags & IFF_UP)) { - if (wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP) != 0) { - printf("Could not set interface '%s' UP\n", - drv->ifname); - } - } - - /* - * Make sure that the driver does not have any obsolete PMKID entries. - */ - wpa_driver_nl80211_flush_pmkid(drv); - - wpa_driver_nl80211_get_range(drv); - - wpa_driver_nl80211_send_oper_ifla(drv, 1, IF_OPER_DORMANT); -} - - -/** - * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface - * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init() - * - * Shut down driver interface and processing of driver events. Free - * private data buffer if one was allocated in wpa_driver_nl80211_init(). - */ -static void wpa_driver_nl80211_deinit(void *priv) -{ - struct wpa_driver_nl80211_data *drv = priv; - int flags; - -#ifdef CONFIG_CLIENT_MLME - if (drv->monitor_sock >= 0) { - eloop_unregister_read_sock(drv->monitor_sock); - close(drv->monitor_sock); - } - if (drv->monitor_ifidx > 0) - nl80211_remove_iface(drv, drv->monitor_ifidx); - if (drv->capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) - wpa_driver_nl80211_set_userspace_mlme(drv, 0); -#endif /* CONFIG_CLIENT_MLME */ - - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); - - /* - * Clear possibly configured driver parameters in order to make it - * easier to use the driver after wpa_supplicant has been terminated. - */ - (void) wpa_driver_nl80211_set_bssid(drv, - (u8 *) "\x00\x00\x00\x00\x00\x00"); - - wpa_driver_nl80211_send_oper_ifla(priv, 0, IF_OPER_UP); - - eloop_unregister_read_sock(drv->wext_event_sock); - - if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0) - (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP); - - close(drv->wext_event_sock); - close(drv->ioctl_sock); - os_free(drv->assoc_req_ies); - os_free(drv->assoc_resp_ies); - - eloop_unregister_read_sock(nl_socket_get_fd(drv->nl_handle)); - genl_family_put(drv->nl80211); - nl_cache_free(drv->nl_cache); - nl_handle_destroy(drv->nl_handle); - nl_cb_put(drv->nl_cb); - - os_free(drv); -} - - -/** - * wpa_driver_nl80211_scan_timeout - Scan timeout to report scan completion - * @eloop_ctx: Unused - * @timeout_ctx: ctx argument given to wpa_driver_nl80211_init() - * - * This function can be used as registered timeout when starting a scan to - * generate a scan completed event if the driver does not report this. - */ -static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - - -/** - * wpa_driver_nl80211_scan - Request the driver to initiate scan - * @priv: Pointer to private wext data from wpa_driver_nl80211_init() - * @ssid: Specific SSID to scan for (ProbeReq) or %NULL to scan for - * all SSIDs (either active scan with broadcast SSID or passive - * scan - * @ssid_len: Length of the SSID - * Returns: 0 on success, -1 on failure - */ -static int wpa_driver_nl80211_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - int ret = 0, timeout; - struct nl_msg *msg, *ssids; - - msg = nlmsg_alloc(); - ssids = nlmsg_alloc(); - if (!msg || !ssids) { - nlmsg_free(msg); - nlmsg_free(ssids); - return -1; - } - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, - NL80211_CMD_TRIGGER_SCAN, 0); - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - if (ssid && ssid_len) { - /* Request an active scan for a specific SSID */ - NLA_PUT(ssids, 1, ssid_len, ssid); - } else { - /* Request an active scan for wildcard SSID */ - NLA_PUT(ssids, 1, 0, ""); - } - nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - msg = NULL; - if (ret) { - wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d " - "(%s)", ret, strerror(-ret)); - goto nla_put_failure; - } - - /* Not all drivers generate "scan completed" wireless event, so try to - * read results after a timeout. */ - timeout = 10; - if (drv->scan_complete_events) { - /* - * The driver seems to deliver SIOCGIWSCAN events to notify - * when scan is complete, so use longer timeout to avoid race - * conditions with scanning and following association request. - */ - timeout = 30; - } - wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d " - "seconds", ret, timeout); - eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); - eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout, - drv, drv->ctx); - -nla_put_failure: - nlmsg_free(ssids); - nlmsg_free(msg); - return ret; -} - - -static int bss_info_handler(struct nl_msg *msg, void *arg) -{ - struct nlattr *tb[NL80211_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct nlattr *bss[NL80211_BSS_MAX + 1]; - static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { - [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC }, - [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, - [NL80211_BSS_TSF] = { .type = NLA_U64 }, - [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, - [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, - [NL80211_BSS_INFORMATION_ELEMENTS] = { .type = NLA_UNSPEC }, - [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, - [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, - }; - struct wpa_scan_results *res = arg; - struct wpa_scan_res **tmp; - struct wpa_scan_res *r; - const u8 *ie; - size_t ie_len; - - nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - if (!tb[NL80211_ATTR_BSS]) - return NL_SKIP; - if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], - bss_policy)) - return NL_SKIP; - if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) { - ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]); - ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); - } else { - ie = NULL; - ie_len = 0; - } - - r = os_zalloc(sizeof(*r) + ie_len); - if (r == NULL) - return NL_SKIP; - if (bss[NL80211_BSS_BSSID]) - os_memcpy(r->bssid, nla_data(bss[NL80211_BSS_BSSID]), - ETH_ALEN); - if (bss[NL80211_BSS_FREQUENCY]) - r->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); - if (bss[NL80211_BSS_BEACON_INTERVAL]) - r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]); - if (bss[NL80211_BSS_CAPABILITY]) - r->caps = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); - if (bss[NL80211_BSS_SIGNAL_UNSPEC]) - r->qual = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); - if (bss[NL80211_BSS_SIGNAL_MBM]) - r->level = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); - if (bss[NL80211_BSS_TSF]) - r->tsf = nla_get_u64(bss[NL80211_BSS_TSF]); - r->ie_len = ie_len; - if (ie) - os_memcpy(r + 1, ie, ie_len); - - tmp = os_realloc(res->res, - (res->num + 1) * sizeof(struct wpa_scan_res *)); - if (tmp == NULL) { - os_free(r); - return NL_SKIP; - } - tmp[res->num++] = r; - res->res = tmp; - - return NL_SKIP; -} - - -/** - * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results - * @priv: Pointer to private wext data from wpa_driver_nl80211_init() - * Returns: Scan results on success, -1 on failure - */ -static struct wpa_scan_results * -wpa_driver_nl80211_get_scan_results(void *priv) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct nl_msg *msg; - struct wpa_scan_results *res; - int ret; - - res = os_zalloc(sizeof(*res)); - if (res == NULL) - return 0; - msg = nlmsg_alloc(); - if (!msg) - goto nla_put_failure; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, NLM_F_DUMP, - NL80211_CMD_GET_SCAN, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - ret = send_and_recv_msgs(drv, msg, bss_info_handler, res); - msg = NULL; - if (ret == 0) { - wpa_printf(MSG_DEBUG, "Received scan results (%lu BSSes)", - (unsigned long) res->num); - return res; - } - wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d " - "(%s)", ret, strerror(-ret)); -nla_put_failure: - nlmsg_free(msg); - wpa_scan_results_free(res); - return NULL; -} - - -static int wpa_driver_nl80211_get_range(void *priv) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iw_range *range; - struct iwreq iwr; - int minlen; - size_t buflen; - - /* - * Use larger buffer than struct iw_range in order to allow the - * structure to grow in the future. - */ - buflen = sizeof(struct iw_range) + 500; - range = os_zalloc(buflen); - if (range == NULL) - return -1; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) range; - iwr.u.data.length = buflen; - - minlen = ((char *) &range->enc_capa) - (char *) range + - sizeof(range->enc_capa); - - if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { - perror("ioctl[SIOCGIWRANGE]"); - os_free(range); - return -1; - } else if (iwr.u.data.length >= minlen && - range->we_version_compiled >= 18) { - wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " - "WE(source)=%d enc_capa=0x%x", - range->we_version_compiled, - range->we_version_source, - range->enc_capa); - drv->has_capability = 1; - drv->we_version_compiled = range->we_version_compiled; - if (range->enc_capa & IW_ENC_CAPA_WPA) { - drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; - } - if (range->enc_capa & IW_ENC_CAPA_WPA2) { - drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; - } - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | - WPA_DRIVER_CAPA_ENC_WEP104; - if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; - if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; - drv->capa.auth = WPA_DRIVER_AUTH_OPEN | - WPA_DRIVER_AUTH_SHARED | - WPA_DRIVER_AUTH_LEAP; - wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x", - drv->capa.key_mgmt, drv->capa.enc); - } else { - wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - " - "assuming WPA is not supported"); - } - - os_free(range); - return 0; -} - - -static int wpa_driver_nl80211_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_nl80211_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - return wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_WPA_ENABLED, - enabled); -} - - -static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, - size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - int err; - struct nl_msg *msg; - - wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " - "seq_len=%lu key_len=%lu", - __func__, alg, addr, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - msg = nlmsg_alloc(); - if (msg == NULL) - return -1; - - if (alg == WPA_ALG_NONE) { - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, - NL80211_CMD_DEL_KEY, 0); - } else { - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0, - NL80211_CMD_NEW_KEY, 0); - NLA_PUT(msg, NL80211_ATTR_KEY_DATA, key_len, key); - switch (alg) { - case WPA_ALG_WEP: - if (key_len == 5) - NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, - 0x000FAC01); - else - NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, - 0x000FAC05); - break; - case WPA_ALG_TKIP: - NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC02); - break; - case WPA_ALG_CCMP: - NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC04); - break; -#ifdef CONFIG_IEEE80211W - case WPA_ALG_IGTK: - NLA_PUT_U32(msg, NL80211_ATTR_KEY_CIPHER, 0x000FAC06); - break; -#endif /* CONFIG_IEEE80211W */ - default: - nlmsg_free(msg); - return -1; - } - } - - if (addr && os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) - { - wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr)); - NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); - } - NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - err = send_and_recv_msgs(drv, msg, NULL, NULL); - if (err) { - wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err); - return -1; - } - - if (set_tx && alg != WPA_ALG_NONE) { - msg = nlmsg_alloc(); - if (msg == NULL) - return -1; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_SET_KEY, 0); - NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT); - - err = send_and_recv_msgs(drv, msg, NULL, NULL); - if (err) { - wpa_printf(MSG_DEBUG, "nl80211: set default key " - "failed; err=%d", err); - return -1; - } - } - - return 0; - -nla_put_failure: - return -ENOBUFS; -} - - -static int wpa_driver_nl80211_set_countermeasures(void *priv, - int enabled) -{ - struct wpa_driver_nl80211_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_TKIP_COUNTERMEASURES, - enabled); -} - - -static int wpa_driver_nl80211_set_drop_unencrypted(void *priv, - int enabled) -{ - struct wpa_driver_nl80211_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - drv->use_crypt = enabled; - return wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, - enabled); -} - - -static int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, - const u8 *addr, int cmd, int reason_code) -{ - struct iwreq iwr; - struct iw_mlme mlme; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - os_memset(&mlme, 0, sizeof(mlme)); - mlme.cmd = cmd; - mlme.reason_code = reason_code; - mlme.addr.sa_family = ARPHRD_ETHER; - os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN); - iwr.u.data.pointer = (caddr_t) &mlme; - iwr.u.data.length = sizeof(mlme); - - if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) { - perror("ioctl[SIOCSIWMLME]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_nl80211_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_nl80211_mlme(drv, addr, IW_MLME_DEAUTH, reason_code); -} - - -static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_nl80211_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_nl80211_mlme(drv, addr, IW_MLME_DISASSOC, - reason_code); -} - - -static int wpa_driver_nl80211_set_gen_ie(void *priv, const u8 *ie, - size_t ie_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) ie; - iwr.u.data.length = ie_len; - - if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) { - perror("ioctl[SIOCSIWGENIE]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_cipher2wext(int cipher) -{ - switch (cipher) { - case CIPHER_NONE: - return IW_AUTH_CIPHER_NONE; - case CIPHER_WEP40: - return IW_AUTH_CIPHER_WEP40; - case CIPHER_TKIP: - return IW_AUTH_CIPHER_TKIP; - case CIPHER_CCMP: - return IW_AUTH_CIPHER_CCMP; - case CIPHER_WEP104: - return IW_AUTH_CIPHER_WEP104; - default: - return 0; - } -} - - -static int wpa_driver_nl80211_keymgmt2wext(int keymgmt) -{ - switch (keymgmt) { - case KEY_MGMT_802_1X: - case KEY_MGMT_802_1X_NO_WPA: - return IW_AUTH_KEY_MGMT_802_1X; - case KEY_MGMT_PSK: - return IW_AUTH_KEY_MGMT_PSK; - default: - return 0; - } -} - - -static int -wpa_driver_nl80211_auth_alg_fallback(struct wpa_driver_nl80211_data *drv, - struct wpa_driver_associate_params *params) -{ - struct iwreq iwr; - int ret = 0; - - wpa_printf(MSG_DEBUG, "WEXT: Driver did not support " - "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE"); - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - /* Just changing mode, not actual keys */ - iwr.u.encoding.flags = 0; - iwr.u.encoding.pointer = (caddr_t) NULL; - iwr.u.encoding.length = 0; - - /* - * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two - * different things. Here they are used to indicate Open System vs. - * Shared Key authentication algorithm. However, some drivers may use - * them to select between open/restricted WEP encrypted (open = allow - * both unencrypted and encrypted frames; restricted = only allow - * encrypted frames). - */ - - if (!drv->use_crypt) { - iwr.u.encoding.flags |= IW_ENCODE_DISABLED; - } else { - if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM) - iwr.u.encoding.flags |= IW_ENCODE_OPEN; - if (params->auth_alg & AUTH_ALG_SHARED_KEY) - iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; - } - - if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { - perror("ioctl[SIOCSIWENCODE]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_associate( - void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_nl80211_data *drv = priv; - int ret = 0; - int allow_unencrypted_eapol; - int value; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - /* - * If the driver did not support SIOCSIWAUTH, fallback to - * SIOCSIWENCODE here. - */ - if (drv->auth_alg_fallback && - wpa_driver_nl80211_auth_alg_fallback(drv, params) < 0) - ret = -1; - - if (!params->bssid && - wpa_driver_nl80211_set_bssid(drv, NULL) < 0) - ret = -1; - - /* TODO: should consider getting wpa version and cipher/key_mgmt suites - * from configuration, not from here, where only the selected suite is - * available */ - if (wpa_driver_nl80211_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len) - < 0) - ret = -1; - if (params->wpa_ie == NULL || params->wpa_ie_len == 0) - value = IW_AUTH_WPA_VERSION_DISABLED; - else if (params->wpa_ie[0] == WLAN_EID_RSN) - value = IW_AUTH_WPA_VERSION_WPA2; - else - value = IW_AUTH_WPA_VERSION_WPA; - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_WPA_VERSION, value) < 0) - ret = -1; - value = wpa_driver_nl80211_cipher2wext(params->pairwise_suite); - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_CIPHER_PAIRWISE, value) < 0) - ret = -1; - value = wpa_driver_nl80211_cipher2wext(params->group_suite); - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_CIPHER_GROUP, value) < 0) - ret = -1; - value = wpa_driver_nl80211_keymgmt2wext(params->key_mgmt_suite); - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_KEY_MGMT, value) < 0) - ret = -1; - value = params->key_mgmt_suite != KEY_MGMT_NONE || - params->pairwise_suite != CIPHER_NONE || - params->group_suite != CIPHER_NONE || - params->wpa_ie_len; - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_PRIVACY_INVOKED, value) < 0) - ret = -1; - - /* Allow unencrypted EAPOL messages even if pairwise keys are set when - * not using WPA. IEEE 802.1X specifies that these frames are not - * encrypted, but WPA encrypts them when pairwise keys are in use. */ - if (params->key_mgmt_suite == KEY_MGMT_802_1X || - params->key_mgmt_suite == KEY_MGMT_PSK) - allow_unencrypted_eapol = 0; - else - allow_unencrypted_eapol = 1; - - if (wpa_driver_nl80211_set_auth_param(drv, - IW_AUTH_RX_UNENCRYPTED_EAPOL, - allow_unencrypted_eapol) < 0) - ret = -1; - if (params->freq && wpa_driver_nl80211_set_freq(drv, params->freq) < 0) - ret = -1; - if (wpa_driver_nl80211_set_ssid(drv, params->ssid, params->ssid_len) < 0) - ret = -1; - if (params->bssid && - wpa_driver_nl80211_set_bssid(drv, params->bssid) < 0) - ret = -1; - - return ret; -} - - -static int wpa_driver_nl80211_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_nl80211_data *drv = priv; - int algs = 0, res; - - if (auth_alg & AUTH_ALG_OPEN_SYSTEM) - algs |= IW_AUTH_ALG_OPEN_SYSTEM; - if (auth_alg & AUTH_ALG_SHARED_KEY) - algs |= IW_AUTH_ALG_SHARED_KEY; - if (auth_alg & AUTH_ALG_LEAP) - algs |= IW_AUTH_ALG_LEAP; - if (algs == 0) { - /* at least one algorithm should be set */ - algs = IW_AUTH_ALG_OPEN_SYSTEM; - } - - res = wpa_driver_nl80211_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, - algs); - drv->auth_alg_fallback = res == -2; - return res; -} - - -/** - * wpa_driver_nl80211_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE - * @priv: Pointer to private wext data from wpa_driver_nl80211_init() - * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS - * Returns: 0 on success, -1 on failure - */ -static int wpa_driver_nl80211_set_mode(void *priv, int mode) -{ - struct wpa_driver_nl80211_data *drv = priv; - int ret = -1, flags; - struct nl_msg *msg; - - msg = nlmsg_alloc(); - if (!msg) - return -1; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_SET_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, - mode ? NL80211_IFTYPE_ADHOC : NL80211_IFTYPE_STATION); - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - if (!ret) - return 0; - else - goto try_again; - -nla_put_failure: - wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode: %d (%s)", - ret, strerror(-ret)); - return -1; - -try_again: - /* mac80211 doesn't allow mode changes while the device is up, so - * take the device down, try to set the mode again, and bring the - * device back up. - */ - if (wpa_driver_nl80211_get_ifflags(drv, &flags) == 0) { - (void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP); - - /* Try to set the mode again while the interface is down */ - msg = nlmsg_alloc(); - if (!msg) - return -1; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_SET_INTERFACE, 0); - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, - mode ? NL80211_IFTYPE_ADHOC : - NL80211_IFTYPE_STATION); - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - if (ret) { - wpa_printf(MSG_ERROR, "Failed to set interface %s " - "mode(try_again): %d (%s)", - drv->ifname, ret, strerror(-ret)); - } - - /* Ignore return value of get_ifflags to ensure that the device - * is always up like it was before this function was called. - */ - (void) wpa_driver_nl80211_get_ifflags(drv, &flags); - (void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP); - } - - return ret; -} - - -static int wpa_driver_nl80211_pmksa(struct wpa_driver_nl80211_data *drv, - u32 cmd, const u8 *bssid, const u8 *pmkid) -{ - struct iwreq iwr; - struct iw_pmksa pmksa; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - os_memset(&pmksa, 0, sizeof(pmksa)); - pmksa.cmd = cmd; - pmksa.bssid.sa_family = ARPHRD_ETHER; - if (bssid) - os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); - if (pmkid) - os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); - iwr.u.data.pointer = (caddr_t) &pmksa; - iwr.u.data.length = sizeof(pmksa); - - if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { - if (errno != EOPNOTSUPP) - perror("ioctl[SIOCSIWPMKSA]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_nl80211_add_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_nl80211_data *drv = priv; - return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid); -} - - -static int wpa_driver_nl80211_remove_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_nl80211_data *drv = priv; - return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid); -} - - -static int wpa_driver_nl80211_flush_pmkid(void *priv) -{ - struct wpa_driver_nl80211_data *drv = priv; - return wpa_driver_nl80211_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL); -} - - -static int wpa_driver_nl80211_get_capa(void *priv, - struct wpa_driver_capa *capa) -{ - struct wpa_driver_nl80211_data *drv = priv; - if (!drv->has_capability) - return -1; - os_memcpy(capa, &drv->capa, sizeof(*capa)); - return 0; -} - - -static int wpa_driver_nl80211_set_operstate(void *priv, int state) -{ - struct wpa_driver_nl80211_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)", - __func__, drv->operstate, state, state ? "UP" : "DORMANT"); - drv->operstate = state; - return wpa_driver_nl80211_send_oper_ifla( - drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT); -} - - -#ifdef CONFIG_CLIENT_MLME -static int wpa_driver_nl80211_open_mlme(struct wpa_driver_nl80211_data *drv) -{ - if (wpa_driver_nl80211_set_userspace_mlme(drv, 1) < 0) { - wpa_printf(MSG_ERROR, "nl80211: Failed to enable userspace " - "MLME"); - return -1; - } - if (wpa_driver_nl80211_create_monitor_interface(drv)) { - wpa_printf(MSG_ERROR, "nl80211: Failed to create monitor " - "interface"); - return -1; - } - return 0; -} -#endif /* CONFIG_CLIENT_MLME */ - - -static int wpa_driver_nl80211_set_param(void *priv, const char *param) -{ -#ifdef CONFIG_CLIENT_MLME - struct wpa_driver_nl80211_data *drv = priv; - - if (param == NULL) - return 0; - - wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); - - if (os_strstr(param, "use_mlme=1")) { - wpa_printf(MSG_DEBUG, "nl80211: Using user space MLME"); - drv->capa.flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; - - if (wpa_driver_nl80211_open_mlme(drv)) - return -1; - } -#endif /* CONFIG_CLIENT_MLME */ - - return 0; -} - - -#ifdef CONFIG_CLIENT_MLME - -struct phy_info_arg { - u16 *num_modes; - struct wpa_hw_modes *modes; -}; - - -static int phy_info_handler(struct nl_msg *msg, void *arg) -{ - struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; - struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); - struct phy_info_arg *phy_info = arg; - - struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; - - struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; - static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] - = { - [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, - [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, - [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, - [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, - [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, - }; - - struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1]; - static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = { - [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 }, - [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = - { .type = NLA_FLAG }, - }; - - struct nlattr *nl_band; - struct nlattr *nl_freq; - struct nlattr *nl_rate; - int rem_band, rem_freq, rem_rate; - struct wpa_hw_modes *mode; - int idx, mode_is_set; - - nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (!tb_msg[NL80211_ATTR_WIPHY_BANDS]) - return NL_SKIP; - - nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], - rem_band) { - mode = os_realloc(phy_info->modes, - (*phy_info->num_modes + 1) * sizeof(*mode)); - if (!mode) - return NL_SKIP; - phy_info->modes = mode; - - mode_is_set = 0; - - mode = &phy_info->modes[*(phy_info->num_modes)]; - os_memset(mode, 0, sizeof(*mode)); - *(phy_info->num_modes) += 1; - - nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), - nla_len(nl_band), NULL); - - nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], - rem_freq) { - nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, - nla_data(nl_freq), nla_len(nl_freq), - freq_policy); - if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) - continue; - mode->num_channels++; - } - - mode->channels = os_zalloc(mode->num_channels * - sizeof(struct wpa_channel_data)); - if (!mode->channels) - return NL_SKIP; - - idx = 0; - - nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], - rem_freq) { - nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, - nla_data(nl_freq), nla_len(nl_freq), - freq_policy); - if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) - continue; - - mode->channels[idx].freq = nla_get_u32( - tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); - mode->channels[idx].flag |= WPA_CHAN_W_SCAN | - WPA_CHAN_W_ACTIVE_SCAN | - WPA_CHAN_W_IBSS; - - if (!mode_is_set) { - /* crude heuristic */ - if (mode->channels[idx].freq < 4000) - mode->mode = WPA_MODE_IEEE80211B; - else - mode->mode = WPA_MODE_IEEE80211A; - mode_is_set = 1; - } - - /* crude heuristic */ - if (mode->channels[idx].freq < 4000) { - if (mode->channels[idx].freq == 2484) - mode->channels[idx].chan = 14; - else - mode->channels[idx].chan = - (mode->channels[idx].freq - - 2407) / 5; - } else - mode->channels[idx].chan = - mode->channels[idx].freq / 5 - 1000; - - if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) - mode->channels[idx].flag &= ~WPA_CHAN_W_SCAN; - if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) - mode->channels[idx].flag &= - ~WPA_CHAN_W_ACTIVE_SCAN; - if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS]) - mode->channels[idx].flag &= ~WPA_CHAN_W_IBSS; - idx++; - } - - nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], - rem_rate) { - nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, - nla_data(nl_rate), nla_len(nl_rate), - rate_policy); - if (!tb_rate[NL80211_BITRATE_ATTR_RATE]) - continue; - mode->num_rates++; - } - - mode->rates = os_zalloc(mode->num_rates * - sizeof(struct wpa_rate_data)); - if (!mode->rates) - return NL_SKIP; - - idx = 0; - - nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], - rem_rate) { - nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, - nla_data(nl_rate), nla_len(nl_rate), - rate_policy); - if (!tb_rate[NL80211_BITRATE_ATTR_RATE]) - continue; - mode->rates[idx].rate = nla_get_u32( - tb_rate[NL80211_BITRATE_ATTR_RATE]); - - /* crude heuristic */ - if (mode->mode == WPA_MODE_IEEE80211B && - mode->rates[idx].rate > 200) - mode->mode = WPA_MODE_IEEE80211G; - - if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE]) - mode->rates[idx].flags |= WPA_RATE_PREAMBLE2; - - idx++; - } - } - - return NL_SKIP; -} - - -static struct wpa_hw_modes * -wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct nl_msg *msg; - struct phy_info_arg result = { - .num_modes = num_modes, - .modes = NULL, - }; - - *num_modes = 0; - *flags = 0; - - msg = nlmsg_alloc(); - if (!msg) - return NULL; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_GET_WIPHY, 0); - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - - if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) - return result.modes; -nla_put_failure: - return NULL; -} - - -static int wpa_driver_nl80211_set_channel(void *priv, wpa_hw_mode phymode, - int chan, int freq) -{ - return wpa_driver_nl80211_set_freq(priv, freq); -} - - -static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data, - size_t data_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - __u8 rtap_hdr[] = { - 0x00, 0x00, /* radiotap version */ - 0x0e, 0x00, /* radiotap length */ - 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */ - 0x0c, /* F_WEP | F_FRAG (encrypt/fragment if required) */ - 0x00, /* padding */ - 0x00, 0x00, /* RX and TX flags to indicate that */ - 0x00, 0x00, /* this is the injected frame directly */ - }; - struct iovec iov[2] = { - { - .iov_base = &rtap_hdr, - .iov_len = sizeof(rtap_hdr), - }, - { - .iov_base = (void *) data, - .iov_len = data_len, - } - }; - struct msghdr msg = { - .msg_name = NULL, - .msg_namelen = 0, - .msg_iov = iov, - .msg_iovlen = 2, - .msg_control = NULL, - .msg_controllen = 0, - .msg_flags = 0, - }; - - if (sendmsg(drv->monitor_sock, &msg, 0) < 0) { - perror("send[MLME]"); - return -1; - } - - return 0; -} - - -static int wpa_driver_nl80211_mlme_add_sta(void *priv, const u8 *addr, - const u8 *supp_rates, - size_t supp_rates_len) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct nl_msg *msg; - int ret = -1; - - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_NEW_STATION, 0); - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); - /* TODO: Get proper Association ID and listen interval */ - NLA_PUT_U16(msg, NL80211_ATTR_STA_AID, 1); - NLA_PUT(msg, NL80211_ATTR_STA_SUPPORTED_RATES, supp_rates_len, - supp_rates); - NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 1); - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - /* ignore EEXIST, this happens if a STA associates while associated */ - if (ret == -EEXIST || ret >= 0) - ret = 0; - -nla_put_failure: - return ret; -} - - -static int wpa_driver_nl80211_mlme_remove_sta(void *priv, const u8 *addr) -{ - struct wpa_driver_nl80211_data *drv = priv; - struct nl_msg *msg; - int ret = -1; - - msg = nlmsg_alloc(); - if (!msg) - return -ENOMEM; - - genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, - 0, NL80211_CMD_DEL_STATION, 0); - - NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); - - ret = 0; - - ret = send_and_recv_msgs(drv, msg, NULL, NULL); - return ret; - -nla_put_failure: - return -ENOBUFS; -} - -#endif /* CONFIG_CLIENT_MLME */ - - -const struct wpa_driver_ops wpa_driver_nl80211_ops = { - .name = "nl80211", - .desc = "Linux nl80211/cfg80211", - .get_bssid = wpa_driver_nl80211_get_bssid, - .get_ssid = wpa_driver_nl80211_get_ssid, - .set_wpa = wpa_driver_nl80211_set_wpa, - .set_key = wpa_driver_nl80211_set_key, - .set_countermeasures = wpa_driver_nl80211_set_countermeasures, - .set_drop_unencrypted = wpa_driver_nl80211_set_drop_unencrypted, - .scan = wpa_driver_nl80211_scan, - .get_scan_results2 = wpa_driver_nl80211_get_scan_results, - .deauthenticate = wpa_driver_nl80211_deauthenticate, - .disassociate = wpa_driver_nl80211_disassociate, - .set_mode = wpa_driver_nl80211_set_mode, - .associate = wpa_driver_nl80211_associate, - .set_auth_alg = wpa_driver_nl80211_set_auth_alg, - .init = wpa_driver_nl80211_init, - .deinit = wpa_driver_nl80211_deinit, - .set_param = wpa_driver_nl80211_set_param, - .add_pmkid = wpa_driver_nl80211_add_pmkid, - .remove_pmkid = wpa_driver_nl80211_remove_pmkid, - .flush_pmkid = wpa_driver_nl80211_flush_pmkid, - .get_capa = wpa_driver_nl80211_get_capa, - .set_operstate = wpa_driver_nl80211_set_operstate, - .set_country = wpa_driver_nl80211_set_country, - .set_probe_req_ie = wpa_driver_nl80211_set_probe_req_ie, -#ifdef CONFIG_CLIENT_MLME - .get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data, - .set_channel = wpa_driver_nl80211_set_channel, - .set_ssid = wpa_driver_nl80211_set_ssid, - .set_bssid = wpa_driver_nl80211_set_bssid, - .send_mlme = wpa_driver_nl80211_send_mlme, - .mlme_add_sta = wpa_driver_nl80211_mlme_add_sta, - .mlme_remove_sta = wpa_driver_nl80211_mlme_remove_sta, -#endif /* CONFIG_CLIENT_MLME */ -}; diff --git a/contrib/wpa/src/drivers/driver_osx.m b/contrib/wpa/src/drivers/driver_osx.m deleted file mode 100644 index 93d7df0..0000000 --- a/contrib/wpa/src/drivers/driver_osx.m +++ /dev/null @@ -1,432 +0,0 @@ -/* - * WPA Supplicant - Mac OS X Apple80211 driver interface - * Copyright (c) 2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#define Boolean __DummyBoolean -#include <CoreFoundation/CoreFoundation.h> -#undef Boolean - -#include "common.h" -#include "driver.h" -#include "eloop.h" - -#include "Apple80211.h" - -struct wpa_driver_osx_data { - void *ctx; - WirelessRef wireless_ctx; - CFArrayRef scan_results; -}; - - -#ifndef CONFIG_NO_STDOUT_DEBUG -extern int wpa_debug_level; - -static void dump_dict_cb(const void *key, const void *value, void *context) -{ - if (MSG_DEBUG < wpa_debug_level) - return; - - wpa_printf(MSG_DEBUG, "Key:"); - CFShow(key); - wpa_printf(MSG_DEBUG, "Value:"); - CFShow(value); -} -#endif /* CONFIG_NO_STDOUT_DEBUG */ - - -static void wpa_driver_osx_dump_dict(CFDictionaryRef dict, const char *title) -{ -#ifndef CONFIG_NO_STDOUT_DEBUG - wpa_printf(MSG_DEBUG, "OSX: Dump dictionary %s - %u entries", - title, (unsigned int) CFDictionaryGetCount(dict)); - CFDictionaryApplyFunction(dict, dump_dict_cb, NULL); -#endif /* CONFIG_NO_STDOUT_DEBUG */ -} - - -static int wpa_driver_osx_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - WirelessInfo info; - int len; - - err = WirelessGetInfo(drv->wireless_ctx, &info); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessGetInfo failed: %d", - (int) err); - return -1; - } - if (!info.power) { - wpa_printf(MSG_DEBUG, "OSX: Wireless device power off"); - return -1; - } - - for (len = 0; len < 32; len++) - if (info.ssid[len] == 0) - break; - - os_memcpy(ssid, info.ssid, len); - return len; -} - - -static int wpa_driver_osx_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - WirelessInfo info; - - err = WirelessGetInfo(drv->wireless_ctx, &info); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessGetInfo failed: %d", - (int) err); - return -1; - } - if (!info.power) { - wpa_printf(MSG_DEBUG, "OSX: Wireless device power off"); - return -1; - } - - os_memcpy(bssid, info.bssID, ETH_ALEN); - return 0; -} - - -static void wpa_driver_osx_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - - -static int wpa_driver_osx_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - - if (drv->scan_results) { - CFRelease(drv->scan_results); - drv->scan_results = NULL; - } - - if (ssid) { - CFStringRef data; - data = CFStringCreateWithBytes(kCFAllocatorDefault, - ssid, ssid_len, - kCFStringEncodingISOLatin1, - FALSE); - if (data == NULL) { - wpa_printf(MSG_DEBUG, "CFStringCreateWithBytes " - "failed"); - return -1; - } - - err = WirelessDirectedScan(drv->wireless_ctx, - &drv->scan_results, 0, data); - CFRelease(data); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessDirectedScan " - "failed: 0x%08x", (unsigned int) err); - return -1; - } - } else { - err = WirelessScan(drv->wireless_ctx, &drv->scan_results, 0); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessScan failed: " - "0x%08x", (unsigned int) err); - return -1; - } - } - - eloop_register_timeout(0, 0, wpa_driver_osx_scan_timeout, drv, - drv->ctx); - return 0; -} - - -static int wpa_driver_osx_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ - struct wpa_driver_osx_data *drv = priv; - size_t i, num; - - if (drv->scan_results == NULL) - return 0; - - num = CFArrayGetCount(drv->scan_results); - if (num > max_size) - num = max_size; - os_memset(results, 0, num * sizeof(struct wpa_scan_result)); - - for (i = 0; i < num; i++) { - struct wpa_scan_result *res = &results[i]; - WirelessNetworkInfo *info; - info = (WirelessNetworkInfo *) - CFDataGetBytePtr(CFArrayGetValueAtIndex( - drv->scan_results, i)); - - os_memcpy(res->bssid, info->bssid, ETH_ALEN); - if (info->ssid_len > 32) { - wpa_printf(MSG_DEBUG, "OSX: Invalid SSID length %d in " - "scan results", (int) info->ssid_len); - continue; - } - os_memcpy(res->ssid, info->ssid, info->ssid_len); - res->ssid_len = info->ssid_len; - res->caps = info->capability; - res->freq = 2407 + info->channel * 5; - res->level = info->signal; - res->noise = info->noise; - } - - return num; -} - - -static void wpa_driver_osx_assoc_timeout(void *eloop_ctx, void *timeout_ctx) -{ - struct wpa_driver_osx_data *drv = eloop_ctx; - u8 bssid[ETH_ALEN]; - CFDictionaryRef ai; - - if (wpa_driver_osx_get_bssid(drv, bssid) != 0) { - eloop_register_timeout(1, 0, wpa_driver_osx_assoc_timeout, - drv, drv->ctx); - return; - } - - ai = WirelessGetAssociationInfo(drv->wireless_ctx); - if (ai) { - wpa_driver_osx_dump_dict(ai, "WirelessGetAssociationInfo"); - CFRelease(ai); - } else { - wpa_printf(MSG_DEBUG, "OSX: Failed to get association info"); - } - - wpa_supplicant_event(timeout_ctx, EVENT_ASSOC, NULL); -} - - -static int wpa_driver_osx_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - CFDataRef ssid; - CFStringRef key; - int assoc_type; - - ssid = CFDataCreate(kCFAllocatorDefault, params->ssid, - params->ssid_len); - if (ssid == NULL) - return -1; - - /* TODO: support for WEP */ - if (params->key_mgmt_suite == KEY_MGMT_PSK) { - if (params->passphrase == NULL) - return -1; - key = CFStringCreateWithCString(kCFAllocatorDefault, - params->passphrase, - kCFStringEncodingISOLatin1); - if (key == NULL) { - CFRelease(ssid); - return -1; - } - } else - key = NULL; - - if (params->key_mgmt_suite == KEY_MGMT_NONE) - assoc_type = 0; - else - assoc_type = 4; - - wpa_printf(MSG_DEBUG, "OSX: WirelessAssociate(type=%d key=%p)", - assoc_type, key); - err = WirelessAssociate(drv->wireless_ctx, assoc_type, ssid, key); - CFRelease(ssid); - if (key) - CFRelease(key); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessAssociate failed: 0x%08x", - (unsigned int) err); - return -1; - } - - /* - * Driver is actually already associated; report association from an - * eloop callback. - */ - eloop_cancel_timeout(wpa_driver_osx_assoc_timeout, drv, drv->ctx); - eloop_register_timeout(0, 0, wpa_driver_osx_assoc_timeout, drv, - drv->ctx); - - return 0; -} - - -static int wpa_driver_osx_set_key(void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, const u8 *seq, - size_t seq_len, const u8 *key, - size_t key_len) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - - if (alg == WPA_ALG_WEP) { - err = WirelessSetKey(drv->wireless_ctx, 1, key_idx, key_len, - key); - if (err != 0) { - wpa_printf(MSG_DEBUG, "OSX: WirelessSetKey failed: " - "0x%08x", (unsigned int) err); - return -1; - } - - return 0; - } - - if (alg == WPA_ALG_PMK) { - err = WirelessSetWPAKey(drv->wireless_ctx, 1, key_len, key); - if (err != 0) { - wpa_printf(MSG_DEBUG, "OSX: WirelessSetWPAKey failed: " - "0x%08x", (unsigned int) err); - return -1; - } - return 0; - } - - wpa_printf(MSG_DEBUG, "OSX: Unsupported set_key alg %d", alg); - return -1; -} - - -static int wpa_driver_osx_get_capa(void *priv, struct wpa_driver_capa *capa) -{ - os_memset(capa, 0, sizeof(*capa)); - - capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; - capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104 | - WPA_DRIVER_CAPA_ENC_TKIP | WPA_DRIVER_CAPA_ENC_CCMP; - capa->auth = WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED | - WPA_DRIVER_AUTH_LEAP; - capa->flags = WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; - - return 0; -} - - -static void * wpa_driver_osx_init(void *ctx, const char *ifname) -{ - struct wpa_driver_osx_data *drv; - WirelessError err; - u8 enabled, power; - - if (!WirelessIsAvailable()) { - wpa_printf(MSG_ERROR, "OSX: No wireless interface available"); - return NULL; - } - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - err = WirelessAttach(&drv->wireless_ctx, 0); - if (err) { - wpa_printf(MSG_ERROR, "OSX: WirelessAttach failed: %d", - (int) err); - os_free(drv); - return NULL; - } - - err = WirelessGetEnabled(drv->wireless_ctx, &enabled); - if (err) - wpa_printf(MSG_DEBUG, "OSX: WirelessGetEnabled failed: 0x%08x", - (unsigned int) err); - err = WirelessGetPower(drv->wireless_ctx, &power); - if (err) - wpa_printf(MSG_DEBUG, "OSX: WirelessGetPower failed: 0x%08x", - (unsigned int) err); - - wpa_printf(MSG_DEBUG, "OSX: Enabled=%d Power=%d", enabled, power); - - if (!enabled) { - err = WirelessSetEnabled(drv->wireless_ctx, 1); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessSetEnabled failed:" - " 0x%08x", (unsigned int) err); - WirelessDetach(drv->wireless_ctx); - os_free(drv); - return NULL; - } - } - - if (!power) { - err = WirelessSetPower(drv->wireless_ctx, 1); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessSetPower failed: " - "0x%08x", (unsigned int) err); - WirelessDetach(drv->wireless_ctx); - os_free(drv); - return NULL; - } - } - - return drv; -} - - -static void wpa_driver_osx_deinit(void *priv) -{ - struct wpa_driver_osx_data *drv = priv; - WirelessError err; - - eloop_cancel_timeout(wpa_driver_osx_scan_timeout, drv, drv->ctx); - eloop_cancel_timeout(wpa_driver_osx_assoc_timeout, drv, drv->ctx); - - err = WirelessSetPower(drv->wireless_ctx, 0); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessSetPower(0) failed: " - "0x%08x", (unsigned int) err); - } - - err = WirelessDetach(drv->wireless_ctx); - if (err) { - wpa_printf(MSG_DEBUG, "OSX: WirelessDetach failed: 0x%08x", - (unsigned int) err); - } - - if (drv->scan_results) - CFRelease(drv->scan_results); - - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_osx_ops = { - .name = "osx", - .desc = "Mac OS X Apple80211 driver", - .get_ssid = wpa_driver_osx_get_ssid, - .get_bssid = wpa_driver_osx_get_bssid, - .init = wpa_driver_osx_init, - .deinit = wpa_driver_osx_deinit, - .scan = wpa_driver_osx_scan, - .get_scan_results = wpa_driver_osx_get_scan_results, - .associate = wpa_driver_osx_associate, - .set_key = wpa_driver_osx_set_key, - .get_capa = wpa_driver_osx_get_capa, -}; diff --git a/contrib/wpa/src/drivers/driver_prism54.c b/contrib/wpa/src/drivers/driver_prism54.c deleted file mode 100644 index e64e762..0000000 --- a/contrib/wpa/src/drivers/driver_prism54.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Linux Prism54.org driver - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * Copyright (c) 2004, Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "driver_wext.h" -#include "driver_hostap.h" - -struct wpa_driver_prism54_data { - void *wext; /* private data for driver_wext */ - void *ctx; - char ifname[IFNAMSIZ + 1]; - int sock; -}; - -#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12 -#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25 -#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26 - -static void show_set_key_error(struct prism2_hostapd_param *); - -static int hostapd_ioctl_prism54(struct wpa_driver_prism54_data *drv, - struct prism2_hostapd_param *param, - int len, int show_err) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) param; - iwr.u.data.length = len; - - if (ioctl(drv->sock, PRISM54_HOSTAPD, &iwr) < 0) { - int ret = errno; - if (show_err) - perror("ioctl[PRISM54_HOSTAPD]"); - return ret; - } - - return 0; -} - - -static int wpa_driver_prism54_set_wpa_ie(struct wpa_driver_prism54_data *drv, - const u8 *wpa_ie, - size_t wpa_ie_len) -{ - struct prism2_hostapd_param *param; - int res; - size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; - if (blen < sizeof(*param)) - blen = sizeof(*param); - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT; - param->u.generic_elem.len = wpa_ie_len; - os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); - res = hostapd_ioctl_prism54(drv, param, blen, 1); - - os_free(param); - - return res; -} - - -/* This is called at wpa_supplicant daemon init time */ -static int wpa_driver_prism54_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_prism54_data *drv = priv; - struct prism2_hostapd_param *param; - int res; - size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN; - if (blen < sizeof(*param)) - blen = sizeof(*param); - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = PRISM54_SET_WPA; - param->u.generic_elem.len = 0; - res = hostapd_ioctl_prism54(drv, param, blen, 1); - - os_free(param); - - return res; -} - - -static int wpa_driver_prism54_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_prism54_data *drv = priv; - struct prism2_hostapd_param *param; - u8 *buf; - size_t blen; - int ret = 0; - char *alg_name; - - switch (alg) { - case WPA_ALG_NONE: - alg_name = "none"; - return -1; - break; - case WPA_ALG_WEP: - alg_name = "WEP"; - return -1; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - return -1; - break; - default: - return -1; - } - - wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - if (seq_len > 8) - return -2; - - blen = sizeof(*param) + key_len; - buf = os_zalloc(blen); - if (buf == NULL) - return -1; - - param = (struct prism2_hostapd_param *) buf; - param->cmd = PRISM2_SET_ENCRYPTION; - /* TODO: In theory, STA in client mode can use five keys; four default - * keys for receiving (with keyidx 0..3) and one individual key for - * both transmitting and receiving (keyidx 0) _unicast_ packets. Now, - * keyidx 0 is reserved for this unicast use and default keys can only - * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported). - * This should be fine for more or less all cases, but for completeness - * sake, the driver could be enhanced to support the missing key. */ -#if 0 - if (addr == NULL) - os_memset(param->sta_addr, 0xff, ETH_ALEN); - else - os_memcpy(param->sta_addr, addr, ETH_ALEN); -#else - os_memset(param->sta_addr, 0xff, ETH_ALEN); -#endif - os_strlcpy((char *) param->u.crypt.alg, alg_name, - HOSTAP_CRYPT_ALG_NAME_LEN); - param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; - param->u.crypt.idx = key_idx; - os_memcpy(param->u.crypt.seq, seq, seq_len); - param->u.crypt.key_len = key_len; - os_memcpy((u8 *) (param + 1), key, key_len); - - if (hostapd_ioctl_prism54(drv, param, blen, 1)) { - wpa_printf(MSG_WARNING, "Failed to set encryption."); - show_set_key_error(param); - ret = -1; - } - os_free(buf); - - return ret; -} - - -static int wpa_driver_prism54_set_countermeasures(void *priv, - int enabled) -{ - /* FIX */ - printf("wpa_driver_prism54_set_countermeasures - not yet " - "implemented\n"); - return 0; -} - - -static int wpa_driver_prism54_set_drop_unencrypted(void *priv, - int enabled) -{ - struct wpa_driver_prism54_data *drv = priv; - struct prism2_hostapd_param *param; - int res; - size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN; - if (blen < sizeof(*param)) - blen = sizeof(*param); - - param = os_zalloc(blen); - if (param == NULL) - return -1; - - param->cmd = PRISM54_DROP_UNENCRYPTED; - param->u.generic_elem.len = 0; - res = hostapd_ioctl_prism54(drv, param, blen, 1); - - os_free(param); - - return res; -} - - -static int wpa_driver_prism54_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - /* FIX */ - printf("wpa_driver_prism54_deauthenticate - not yet implemented\n"); - return 0; -} - - -static int wpa_driver_prism54_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - /* FIX */ - printf("wpa_driver_prism54_disassociate - not yet implemented\n"); - return 0; -} - - -static int -wpa_driver_prism54_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_prism54_data *drv = priv; - int ret = 0; - - if (wpa_driver_prism54_set_wpa_ie(drv, params->wpa_ie, - params->wpa_ie_len) < 0) - ret = -1; - if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) - ret = -1; - if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, - params->ssid_len) < 0) - ret = -1; - if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) - ret = -1; - - return ret; -} - -static void show_set_key_error(struct prism2_hostapd_param *param) -{ - switch (param->u.crypt.err) { - case HOSTAP_CRYPT_ERR_UNKNOWN_ALG: - wpa_printf(MSG_INFO, "Unknown algorithm '%s'.", - param->u.crypt.alg); - wpa_printf(MSG_INFO, "You may need to load kernel module to " - "register that algorithm."); - wpa_printf(MSG_INFO, "E.g., 'modprobe hostap_crypt_wep' for " - "WEP."); - break; - case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR: - wpa_printf(MSG_INFO, "Unknown address " MACSTR ".", - MAC2STR(param->sta_addr)); - break; - case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED: - wpa_printf(MSG_INFO, "Crypt algorithm initialization failed."); - break; - case HOSTAP_CRYPT_ERR_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "Key setting failed."); - break; - case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED: - wpa_printf(MSG_INFO, "TX key index setting failed."); - break; - case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED: - wpa_printf(MSG_INFO, "Card configuration failed."); - break; - } -} - - -static int wpa_driver_prism54_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_prism54_data *drv = priv; - return wpa_driver_wext_get_bssid(drv->wext, bssid); -} - - -static int wpa_driver_prism54_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_prism54_data *drv = priv; - return wpa_driver_wext_get_ssid(drv->wext, ssid); -} - - -static int wpa_driver_prism54_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_prism54_data *drv = priv; - return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); -} - - -static struct wpa_scan_results * -wpa_driver_prism54_get_scan_results(void *priv) -{ - struct wpa_driver_prism54_data *drv = priv; - return wpa_driver_wext_get_scan_results(drv->wext); -} - - -static int wpa_driver_prism54_set_operstate(void *priv, int state) -{ - struct wpa_driver_prism54_data *drv = priv; - return wpa_driver_wext_set_operstate(drv->wext, state); -} - - -static void * wpa_driver_prism54_init(void *ctx, const char *ifname) -{ - struct wpa_driver_prism54_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->wext = wpa_driver_wext_init(ctx, ifname); - if (drv->wext == NULL) { - os_free(drv); - return NULL; - } - - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) { - wpa_driver_wext_deinit(drv->wext); - os_free(drv); - return NULL; - } - - return drv; -} - - -static void wpa_driver_prism54_deinit(void *priv) -{ - struct wpa_driver_prism54_data *drv = priv; - wpa_driver_wext_deinit(drv->wext); - close(drv->sock); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_prism54_ops = { - .name = "prism54", - .desc = "Prism54.org driver (Intersil Prism GT/Duette/Indigo)", - .get_bssid = wpa_driver_prism54_get_bssid, - .get_ssid = wpa_driver_prism54_get_ssid, - .set_wpa = wpa_driver_prism54_set_wpa, - .set_key = wpa_driver_prism54_set_key, - .set_countermeasures = wpa_driver_prism54_set_countermeasures, - .set_drop_unencrypted = wpa_driver_prism54_set_drop_unencrypted, - .scan = wpa_driver_prism54_scan, - .get_scan_results2 = wpa_driver_prism54_get_scan_results, - .deauthenticate = wpa_driver_prism54_deauthenticate, - .disassociate = wpa_driver_prism54_disassociate, - .associate = wpa_driver_prism54_associate, - .init = wpa_driver_prism54_init, - .deinit = wpa_driver_prism54_deinit, - .set_operstate = wpa_driver_prism54_set_operstate, -}; diff --git a/contrib/wpa/src/drivers/driver_privsep.c b/contrib/wpa/src/drivers/driver_privsep.c deleted file mode 100644 index fdf299d..0000000 --- a/contrib/wpa/src/drivers/driver_privsep.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * WPA Supplicant - privilege separated driver interface - * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/un.h> - -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "privsep_commands.h" - - -struct wpa_driver_privsep_data { - void *ctx; - u8 own_addr[ETH_ALEN]; - int priv_socket; - char *own_socket_path; - int cmd_socket; - char *own_cmd_path; - struct sockaddr_un priv_addr; - char ifname[16]; -}; - - -static int wpa_priv_reg_cmd(struct wpa_driver_privsep_data *drv, int cmd) -{ - int res; - - res = sendto(drv->priv_socket, &cmd, sizeof(cmd), 0, - (struct sockaddr *) &drv->priv_addr, - sizeof(drv->priv_addr)); - if (res < 0) - perror("sendto"); - return res < 0 ? -1 : 0; -} - - -static int wpa_priv_cmd(struct wpa_driver_privsep_data *drv, int cmd, - const void *data, size_t data_len, - void *reply, size_t *reply_len) -{ - struct msghdr msg; - struct iovec io[2]; - - io[0].iov_base = &cmd; - io[0].iov_len = sizeof(cmd); - io[1].iov_base = (u8 *) data; - io[1].iov_len = data_len; - - os_memset(&msg, 0, sizeof(msg)); - msg.msg_iov = io; - msg.msg_iovlen = data ? 2 : 1; - msg.msg_name = &drv->priv_addr; - msg.msg_namelen = sizeof(drv->priv_addr); - - if (sendmsg(drv->cmd_socket, &msg, 0) < 0) { - perror("sendmsg(cmd_socket)"); - return -1; - } - - if (reply) { - fd_set rfds; - struct timeval tv; - int res; - - FD_ZERO(&rfds); - FD_SET(drv->cmd_socket, &rfds); - tv.tv_sec = 5; - tv.tv_usec = 0; - res = select(drv->cmd_socket + 1, &rfds, NULL, NULL, &tv); - if (res < 0 && errno != EINTR) { - perror("select"); - return -1; - } - - if (FD_ISSET(drv->cmd_socket, &rfds)) { - res = recv(drv->cmd_socket, reply, *reply_len, 0); - if (res < 0) { - perror("recv"); - return -1; - } - *reply_len = res; - } else { - wpa_printf(MSG_DEBUG, "PRIVSEP: Timeout while waiting " - "for reply (cmd=%d)", cmd); - return -1; - } - } - - return 0; -} - - -static int wpa_driver_privsep_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_WPA, &enabled, - sizeof(enabled), NULL, NULL); -} - - -static int wpa_driver_privsep_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv); - return wpa_priv_cmd(drv, PRIVSEP_CMD_SCAN, ssid, ssid_len, - NULL, NULL); -} - - -static struct wpa_scan_results * -wpa_driver_privsep_get_scan_results2(void *priv) -{ - struct wpa_driver_privsep_data *drv = priv; - int res, num; - u8 *buf, *pos, *end; - size_t reply_len = 60000; - struct wpa_scan_results *results; - struct wpa_scan_res *r; - - buf = os_malloc(reply_len); - if (buf == NULL) - return NULL; - res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SCAN_RESULTS, - NULL, 0, buf, &reply_len); - if (res < 0) { - os_free(buf); - return NULL; - } - - wpa_printf(MSG_DEBUG, "privsep: Received %lu bytes of scan results", - (unsigned long) reply_len); - if (reply_len < sizeof(int)) { - wpa_printf(MSG_DEBUG, "privsep: Invalid scan result len %lu", - (unsigned long) reply_len); - os_free(buf); - return NULL; - } - - pos = buf; - end = buf + reply_len; - os_memcpy(&num, pos, sizeof(int)); - if (num < 0 || num > 1000) { - os_free(buf); - return NULL; - } - pos += sizeof(int); - - results = os_zalloc(sizeof(*results)); - if (results == NULL) { - os_free(buf); - return NULL; - } - - results->res = os_zalloc(num * sizeof(struct wpa_scan_res *)); - if (results->res == NULL) { - os_free(results); - os_free(buf); - return NULL; - } - - while (results->num < (size_t) num && pos + sizeof(int) < end) { - int len; - os_memcpy(&len, pos, sizeof(int)); - pos += sizeof(int); - if (len < 0 || len > 10000 || pos + len > end) - break; - - r = os_malloc(len); - if (r == NULL) - break; - os_memcpy(r, pos, len); - pos += len; - if (sizeof(*r) + r->ie_len > (size_t) len) { - os_free(r); - break; - } - - results->res[results->num++] = r; - } - - os_free(buf); - return results; -} - - -static int wpa_driver_privsep_set_key(void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_privsep_data *drv = priv; - struct privsep_cmd_set_key cmd; - - wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d", - __func__, priv, alg, key_idx, set_tx); - - os_memset(&cmd, 0, sizeof(cmd)); - cmd.alg = alg; - if (addr) - os_memcpy(cmd.addr, addr, ETH_ALEN); - else - os_memset(cmd.addr, 0xff, ETH_ALEN); - cmd.key_idx = key_idx; - cmd.set_tx = set_tx; - if (seq && seq_len > 0 && seq_len < sizeof(cmd.seq)) { - os_memcpy(cmd.seq, seq, seq_len); - cmd.seq_len = seq_len; - } - if (key && key_len > 0 && key_len < sizeof(cmd.key)) { - os_memcpy(cmd.key, key, key_len); - cmd.key_len = key_len; - } - - return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_KEY, &cmd, sizeof(cmd), - NULL, NULL); -} - - -static int wpa_driver_privsep_associate( - void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_privsep_data *drv = priv; - struct privsep_cmd_associate *data; - int res; - size_t buflen; - - wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d " - "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d", - __func__, priv, params->freq, params->pairwise_suite, - params->group_suite, params->key_mgmt_suite, - params->auth_alg, params->mode); - - buflen = sizeof(*data) + params->wpa_ie_len; - data = os_zalloc(buflen); - if (data == NULL) - return -1; - - if (params->bssid) - os_memcpy(data->bssid, params->bssid, ETH_ALEN); - os_memcpy(data->ssid, params->ssid, params->ssid_len); - data->ssid_len = params->ssid_len; - data->freq = params->freq; - data->pairwise_suite = params->pairwise_suite; - data->group_suite = params->group_suite; - data->key_mgmt_suite = params->key_mgmt_suite; - data->auth_alg = params->auth_alg; - data->mode = params->mode; - data->wpa_ie_len = params->wpa_ie_len; - if (params->wpa_ie) - os_memcpy(data + 1, params->wpa_ie, params->wpa_ie_len); - /* TODO: add support for other assoc parameters */ - - res = wpa_priv_cmd(drv, PRIVSEP_CMD_ASSOCIATE, data, buflen, - NULL, NULL); - os_free(data); - - return res; -} - - -static int wpa_driver_privsep_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_privsep_data *drv = priv; - int res; - size_t len = ETH_ALEN; - - res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_BSSID, NULL, 0, bssid, &len); - if (res < 0 || len != ETH_ALEN) - return -1; - return 0; -} - - -static int wpa_driver_privsep_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_privsep_data *drv = priv; - int res, ssid_len; - u8 reply[sizeof(int) + 32]; - size_t len = sizeof(reply); - - res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SSID, NULL, 0, reply, &len); - if (res < 0 || len < sizeof(int)) - return -1; - os_memcpy(&ssid_len, reply, sizeof(int)); - if (ssid_len < 0 || ssid_len > 32 || sizeof(int) + ssid_len > len) { - wpa_printf(MSG_DEBUG, "privsep: Invalid get SSID reply"); - return -1; - } - os_memcpy(ssid, &reply[sizeof(int)], ssid_len); - return ssid_len; -} - - -static int wpa_driver_privsep_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - //struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", - __func__, MAC2STR(addr), reason_code); - wpa_printf(MSG_DEBUG, "%s - TODO", __func__); - return 0; -} - - -static int wpa_driver_privsep_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - //struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", - __func__, MAC2STR(addr), reason_code); - wpa_printf(MSG_DEBUG, "%s - TODO", __func__); - return 0; -} - - -static void wpa_driver_privsep_event_assoc(void *ctx, wpa_event_type event, - u8 *buf, size_t len) -{ - union wpa_event_data data; - int inc_data = 0; - u8 *pos, *end; - int ie_len; - - os_memset(&data, 0, sizeof(data)); - - pos = buf; - end = buf + len; - - if (end - pos < (int) sizeof(int)) - return; - os_memcpy(&ie_len, pos, sizeof(int)); - pos += sizeof(int); - if (ie_len < 0 || ie_len > end - pos) - return; - if (ie_len) { - data.assoc_info.req_ies = pos; - data.assoc_info.req_ies_len = ie_len; - pos += ie_len; - inc_data = 1; - } - - wpa_supplicant_event(ctx, event, inc_data ? &data : NULL); -} - - -static void wpa_driver_privsep_event_interface_status(void *ctx, u8 *buf, - size_t len) -{ - union wpa_event_data data; - int ievent; - - if (len < sizeof(int) || - len - sizeof(int) > sizeof(data.interface_status.ifname)) - return; - - os_memcpy(&ievent, buf, sizeof(int)); - - os_memset(&data, 0, sizeof(data)); - data.interface_status.ievent = ievent; - os_memcpy(data.interface_status.ifname, buf + sizeof(int), - len - sizeof(int)); - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &data); -} - - -static void wpa_driver_privsep_event_michael_mic_failure( - void *ctx, u8 *buf, size_t len) -{ - union wpa_event_data data; - - if (len != sizeof(int)) - return; - - os_memset(&data, 0, sizeof(data)); - os_memcpy(&data.michael_mic_failure.unicast, buf, sizeof(int)); - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); -} - - -static void wpa_driver_privsep_event_pmkid_candidate(void *ctx, u8 *buf, - size_t len) -{ - union wpa_event_data data; - - if (len != sizeof(struct pmkid_candidate)) - return; - - os_memset(&data, 0, sizeof(data)); - os_memcpy(&data.pmkid_candidate, buf, len); - wpa_supplicant_event(ctx, EVENT_PMKID_CANDIDATE, &data); -} - - -static void wpa_driver_privsep_event_stkstart(void *ctx, u8 *buf, size_t len) -{ - union wpa_event_data data; - - if (len != ETH_ALEN) - return; - - os_memset(&data, 0, sizeof(data)); - os_memcpy(data.stkstart.peer, buf, ETH_ALEN); - wpa_supplicant_event(ctx, EVENT_STKSTART, &data); -} - - -static void wpa_driver_privsep_event_ft_response(void *ctx, u8 *buf, - size_t len) -{ - union wpa_event_data data; - - if (len < sizeof(int) + ETH_ALEN) - return; - - os_memset(&data, 0, sizeof(data)); - os_memcpy(&data.ft_ies.ft_action, buf, sizeof(int)); - os_memcpy(data.ft_ies.target_ap, buf + sizeof(int), ETH_ALEN); - data.ft_ies.ies = buf + sizeof(int) + ETH_ALEN; - data.ft_ies.ies_len = len - sizeof(int) - ETH_ALEN; - wpa_supplicant_event(ctx, EVENT_FT_RESPONSE, &data); -} - - -static void wpa_driver_privsep_event_rx_eapol(void *ctx, u8 *buf, size_t len) -{ - if (len < ETH_ALEN) - return; - - wpa_supplicant_rx_eapol(ctx, buf, buf + ETH_ALEN, len - ETH_ALEN); -} - - -static void wpa_driver_privsep_event_sta_rx(void *ctx, u8 *buf, size_t len) -{ -#ifdef CONFIG_CLIENT_MLME - struct ieee80211_rx_status *rx_status; - - if (len < sizeof(*rx_status)) - return; - rx_status = (struct ieee80211_rx_status *) buf; - buf += sizeof(*rx_status); - len -= sizeof(*rx_status); - - wpa_supplicant_sta_rx(ctx, buf, len, rx_status); -#endif /* CONFIG_CLIENT_MLME */ -} - - -static void wpa_driver_privsep_receive(int sock, void *eloop_ctx, - void *sock_ctx) -{ - struct wpa_driver_privsep_data *drv = eloop_ctx; - u8 *buf, *event_buf; - size_t event_len; - int res, event; - enum privsep_event e; - struct sockaddr_un from; - socklen_t fromlen = sizeof(from); - const size_t buflen = 2000; - - buf = os_malloc(buflen); - if (buf == NULL) - return; - res = recvfrom(sock, buf, buflen, 0, - (struct sockaddr *) &from, &fromlen); - if (res < 0) { - perror("recvfrom(priv_socket)"); - os_free(buf); - return; - } - - wpa_printf(MSG_DEBUG, "privsep_driver: received %u bytes", res); - - if (res < (int) sizeof(int)) { - wpa_printf(MSG_DEBUG, "Too short event message (len=%d)", res); - return; - } - - os_memcpy(&event, buf, sizeof(int)); - event_buf = &buf[sizeof(int)]; - event_len = res - sizeof(int); - wpa_printf(MSG_DEBUG, "privsep: Event %d received (len=%lu)", - event, (unsigned long) event_len); - - e = event; - switch (e) { - case PRIVSEP_EVENT_SCAN_RESULTS: - wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL); - break; - case PRIVSEP_EVENT_ASSOC: - wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOC, - event_buf, event_len); - break; - case PRIVSEP_EVENT_DISASSOC: - wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); - break; - case PRIVSEP_EVENT_ASSOCINFO: - wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOCINFO, - event_buf, event_len); - break; - case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE: - wpa_driver_privsep_event_michael_mic_failure( - drv->ctx, event_buf, event_len); - break; - case PRIVSEP_EVENT_INTERFACE_STATUS: - wpa_driver_privsep_event_interface_status(drv->ctx, event_buf, - event_len); - break; - case PRIVSEP_EVENT_PMKID_CANDIDATE: - wpa_driver_privsep_event_pmkid_candidate(drv->ctx, event_buf, - event_len); - break; - case PRIVSEP_EVENT_STKSTART: - wpa_driver_privsep_event_stkstart(drv->ctx, event_buf, - event_len); - break; - case PRIVSEP_EVENT_FT_RESPONSE: - wpa_driver_privsep_event_ft_response(drv->ctx, event_buf, - event_len); - break; - case PRIVSEP_EVENT_RX_EAPOL: - wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf, - event_len); - break; - case PRIVSEP_EVENT_STA_RX: - wpa_driver_privsep_event_sta_rx(drv->ctx, event_buf, - event_len); - break; - } - - os_free(buf); -} - - -static void * wpa_driver_privsep_init(void *ctx, const char *ifname) -{ - struct wpa_driver_privsep_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - drv->priv_socket = -1; - drv->cmd_socket = -1; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - - return drv; -} - - -static void wpa_driver_privsep_deinit(void *priv) -{ - struct wpa_driver_privsep_data *drv = priv; - - if (drv->priv_socket >= 0) { - wpa_priv_reg_cmd(drv, PRIVSEP_CMD_UNREGISTER); - eloop_unregister_read_sock(drv->priv_socket); - close(drv->priv_socket); - } - - if (drv->own_socket_path) { - unlink(drv->own_socket_path); - os_free(drv->own_socket_path); - } - - if (drv->cmd_socket >= 0) { - eloop_unregister_read_sock(drv->cmd_socket); - close(drv->cmd_socket); - } - - if (drv->own_cmd_path) { - unlink(drv->own_cmd_path); - os_free(drv->own_cmd_path); - } - - os_free(drv); -} - - -static int wpa_driver_privsep_set_param(void *priv, const char *param) -{ - struct wpa_driver_privsep_data *drv = priv; - const char *pos; - char *own_dir, *priv_dir; - static unsigned int counter = 0; - size_t len; - struct sockaddr_un addr; - - wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); - if (param == NULL) - pos = NULL; - else - pos = os_strstr(param, "own_dir="); - if (pos) { - char *end; - own_dir = os_strdup(pos + 8); - if (own_dir == NULL) - return -1; - end = os_strchr(own_dir, ' '); - if (end) - *end = '\0'; - } else { - own_dir = os_strdup("/tmp"); - if (own_dir == NULL) - return -1; - } - - if (param == NULL) - pos = NULL; - else - pos = os_strstr(param, "priv_dir="); - if (pos) { - char *end; - priv_dir = os_strdup(pos + 9); - if (priv_dir == NULL) { - os_free(own_dir); - return -1; - } - end = os_strchr(priv_dir, ' '); - if (end) - *end = '\0'; - } else { - priv_dir = os_strdup("/var/run/wpa_priv"); - if (priv_dir == NULL) { - os_free(own_dir); - return -1; - } - } - - len = os_strlen(own_dir) + 50; - drv->own_socket_path = os_malloc(len); - if (drv->own_socket_path == NULL) { - os_free(priv_dir); - os_free(own_dir); - return -1; - } - os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d", - own_dir, getpid(), counter++); - - len = os_strlen(own_dir) + 50; - drv->own_cmd_path = os_malloc(len); - if (drv->own_cmd_path == NULL) { - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - os_free(priv_dir); - os_free(own_dir); - return -1; - } - os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d", - own_dir, getpid(), counter++); - - os_free(own_dir); - - drv->priv_addr.sun_family = AF_UNIX; - os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path), - "%s/%s", priv_dir, drv->ifname); - os_free(priv_dir); - - drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0); - if (drv->priv_socket < 0) { - perror("socket(PF_UNIX)"); - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - return -1; - } - - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); - if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) < - 0) { - perror("bind(PF_UNIX)"); - close(drv->priv_socket); - drv->priv_socket = -1; - unlink(drv->own_socket_path); - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - return -1; - } - - eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive, - drv, NULL); - - drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0); - if (drv->cmd_socket < 0) { - perror("socket(PF_UNIX)"); - os_free(drv->own_cmd_path); - drv->own_cmd_path = NULL; - return -1; - } - - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path)); - if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) - { - perror("bind(PF_UNIX)"); - close(drv->cmd_socket); - drv->cmd_socket = -1; - unlink(drv->own_cmd_path); - os_free(drv->own_cmd_path); - drv->own_cmd_path = NULL; - return -1; - } - - if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) { - wpa_printf(MSG_ERROR, "Failed to register with wpa_priv"); - return -1; - } - - return 0; -} - - -static int wpa_driver_privsep_get_capa(void *priv, - struct wpa_driver_capa *capa) -{ - struct wpa_driver_privsep_data *drv = priv; - int res; - size_t len = sizeof(*capa); - - res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_CAPA, NULL, 0, capa, &len); - if (res < 0 || len != sizeof(*capa)) - return -1; - return 0; -} - - -static const u8 * wpa_driver_privsep_get_mac_addr(void *priv) -{ - struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __func__); - return drv->own_addr; -} - - -static int wpa_driver_privsep_set_mode(void *priv, int mode) -{ - struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s mode=%d", __func__, mode); - return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_MODE, &mode, sizeof(mode), - NULL, NULL); -} - - -static int wpa_driver_privsep_set_country(void *priv, const char *alpha2) -{ - struct wpa_driver_privsep_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s country='%s'", __func__, alpha2); - return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_COUNTRY, alpha2, - os_strlen(alpha2), NULL, NULL); -} - - -struct wpa_driver_ops wpa_driver_privsep_ops = { - "privsep", - "wpa_supplicant privilege separated driver", - wpa_driver_privsep_get_bssid, - wpa_driver_privsep_get_ssid, - wpa_driver_privsep_set_wpa, - wpa_driver_privsep_set_key, - wpa_driver_privsep_init, - wpa_driver_privsep_deinit, - wpa_driver_privsep_set_param, - NULL /* set_countermeasures */, - NULL /* set_drop_unencrypted */, - wpa_driver_privsep_scan, - NULL /* get_scan_results */, - wpa_driver_privsep_deauthenticate, - wpa_driver_privsep_disassociate, - wpa_driver_privsep_associate, - NULL /* set_auth_alg */, - NULL /* add_pmkid */, - NULL /* remove_pmkid */, - NULL /* flush_pmkid */, - wpa_driver_privsep_get_capa, - NULL /* poll */, - NULL /* get_ifname */, - wpa_driver_privsep_get_mac_addr, - NULL /* send_eapol */, - NULL /* set_operstate */, - NULL /* mlme_setprotection */, - NULL /* get_hw_feature_data */, - NULL /* set_channel */, - NULL /* set_ssid */, - NULL /* set_bssid */, - NULL /* send_mlme */, - NULL /* mlme_add_sta */, - NULL /* mlme_remove_sta */, - NULL /* update_ft_ies */, - NULL /* send_ft_action */, - wpa_driver_privsep_get_scan_results2, - NULL /* set_probe_req_ie */, - wpa_driver_privsep_set_mode, - wpa_driver_privsep_set_country, - NULL /* global_init */, - NULL /* global_deinit */, - NULL /* init2 */, - NULL /* get_interfaces */ -}; - - -struct wpa_driver_ops *wpa_supplicant_drivers[] = -{ - &wpa_driver_privsep_ops, - NULL -}; diff --git a/contrib/wpa/src/drivers/driver_ps3.c b/contrib/wpa/src/drivers/driver_ps3.c deleted file mode 100644 index fde3425..0000000 --- a/contrib/wpa/src/drivers/driver_ps3.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * WPA Supplicant - PS3 Linux wireless extension driver interface - * Copyright 2007, 2008 Sony Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> -#include "wireless_copy.h" -#include "common.h" -#include "wpa_common.h" -#include "driver.h" -#include "eloop.h" -#include "driver_wext.h" -#include "ieee802_11_defs.h" - -static int wpa_driver_ps3_set_wpa_key(struct wpa_driver_wext_data *drv, - struct wpa_driver_associate_params *params) -{ - int ret, i; - struct iwreq iwr; - char *buf, *str; - - if (!params->psk && !params->passphrase) { - wpa_printf(MSG_INFO, "%s:no PSK error", __func__); - return -EINVAL; - } - - os_memset(&iwr, 0, sizeof(iwr)); - if (params->psk) { - /* includes null */ - iwr.u.data.length = PMK_LEN * 2 + 1; - buf = os_malloc(iwr.u.data.length); - if (!buf) - return -ENOMEM; - str = buf; - for (i = 0; i < PMK_LEN; i++) { - str += snprintf(str, iwr.u.data.length - (str - buf), - "%02x", params->psk[i]); - } - } else if (params->passphrase) { - /* including quotations and null */ - iwr.u.data.length = strlen(params->passphrase) + 3; - buf = os_malloc(iwr.u.data.length); - if (!buf) - return -ENOMEM; - buf[0] = '"'; - os_memcpy(buf + 1, params->passphrase, iwr.u.data.length - 3); - buf[iwr.u.data.length - 2] = '"'; - buf[iwr.u.data.length - 1] = '\0'; - } else - return -EINVAL; - iwr.u.data.pointer = (caddr_t) buf; - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - ret = ioctl(drv->ioctl_sock, SIOCIWFIRSTPRIV, &iwr); - os_free(buf); - - return ret; -} - -static int wpa_driver_ps3_set_wep_keys(struct wpa_driver_wext_data *drv, - struct wpa_driver_associate_params *params) -{ - int ret, i; - struct iwreq iwr; - - for (i = 0; i < 4; i++) { - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = i + 1; - if (params->wep_key_len[i]) { - iwr.u.encoding.pointer = (caddr_t) params->wep_key[i]; - iwr.u.encoding.length = params->wep_key_len[i]; - } else - iwr.u.encoding.flags = IW_ENCODE_NOKEY | - IW_ENCODE_DISABLED; - - if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { - perror("ioctl[SIOCSIWENCODE]"); - ret = -1; - } - } - return ret; -} - -static int wpa_driver_ps3_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_wext_data *drv = priv; - int ret, value; - - wpa_printf(MSG_DEBUG, "%s: <-", __func__); - - /* clear BSSID */ - if (!params->bssid && - wpa_driver_wext_set_bssid(drv, NULL) < 0) - ret = -1; - - if (wpa_driver_wext_set_mode(drv, params->mode) < 0) - ret = -1; - - if (params->wpa_ie == NULL || params->wpa_ie_len == 0) - value = IW_AUTH_WPA_VERSION_DISABLED; - else if (params->wpa_ie[0] == WLAN_EID_RSN) - value = IW_AUTH_WPA_VERSION_WPA2; - else - value = IW_AUTH_WPA_VERSION_WPA; - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_WPA_VERSION, value) < 0) - ret = -1; - value = wpa_driver_wext_cipher2wext(params->pairwise_suite); - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_CIPHER_PAIRWISE, value) < 0) - ret = -1; - value = wpa_driver_wext_cipher2wext(params->group_suite); - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_CIPHER_GROUP, value) < 0) - ret = -1; - value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite); - if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_KEY_MGMT, value) < 0) - ret = -1; - - /* set selected BSSID */ - if (params->bssid && - wpa_driver_wext_set_bssid(drv, params->bssid) < 0) - ret = -1; - - switch (params->group_suite) { - case CIPHER_NONE: - ret = 0; - break; - case CIPHER_WEP40: - case CIPHER_WEP104: - ret = wpa_driver_ps3_set_wep_keys(drv, params); - break; - case CIPHER_TKIP: - case CIPHER_CCMP: - ret = wpa_driver_ps3_set_wpa_key(drv, params); - break; - } - - /* start to associate */ - ret = wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len); - - wpa_printf(MSG_DEBUG, "%s: ->", __func__); - - return ret; -} - -static int wpa_driver_ps3_get_capa(void *priv, struct wpa_driver_capa *capa) -{ - int ret; - wpa_printf(MSG_DEBUG, "%s:<-", __func__); - - ret = wpa_driver_wext_get_capa(priv, capa); - if (ret) { - wpa_printf(MSG_INFO, "%s: base wext returns error %d", - __func__, ret); - return ret; - } - /* PS3 hypervisor does association and 4way handshake by itself */ - capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; - wpa_printf(MSG_DEBUG, "%s:->", __func__); - return 0; -} - -const struct wpa_driver_ops wpa_driver_ps3_ops = { - .name = "ps3", - .desc = "PLAYSTATION3 Linux wireless extension driver", - .get_bssid = wpa_driver_wext_get_bssid, - .get_ssid = wpa_driver_wext_get_ssid, - .scan = wpa_driver_wext_scan, - .get_scan_results2 = wpa_driver_wext_get_scan_results, - .associate = wpa_driver_ps3_associate, /* PS3 */ - .init = wpa_driver_wext_init, - .deinit = wpa_driver_wext_deinit, - .get_capa = wpa_driver_ps3_get_capa, /* PS3 */ -}; diff --git a/contrib/wpa/src/drivers/driver_ralink.c b/contrib/wpa/src/drivers/driver_ralink.c deleted file mode 100644 index e9313cb..0000000 --- a/contrib/wpa/src/drivers/driver_ralink.c +++ /dev/null @@ -1,1505 +0,0 @@ -/* - * WPA Supplicant - driver interaction with Ralink Wireless Client - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * Copyright (c) 2007, Snowpin Lee <snowpin_lee@ralinktech.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "l2_packet/l2_packet.h" -#include "eloop.h" -#include "ieee802_11_defs.h" -#include "priv_netlink.h" -#include "driver_ralink.h" - -static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx); - -#define MAX_SSID_LEN 32 - -struct wpa_driver_ralink_data { - void *ctx; - int ioctl_sock; - int event_sock; - char ifname[IFNAMSIZ + 1]; - u8 *assoc_req_ies; - size_t assoc_req_ies_len; - u8 *assoc_resp_ies; - size_t assoc_resp_ies_len; - int no_of_pmkid; - struct ndis_pmkid_entry *pmkid; - int we_version_compiled; - int ap_scan; - int scanning_done; - u8 g_driver_down; -}; - -static int ralink_set_oid(struct wpa_driver_ralink_data *drv, - unsigned short oid, char *data, int len) -{ - char *buf; - struct iwreq iwr; - - buf = os_zalloc(len); - if (buf == NULL) - return -1; - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.flags = oid; - iwr.u.data.flags |= OID_GET_SET_TOGGLE; - - if (data) - os_memcpy(buf, data, len); - - iwr.u.data.pointer = (caddr_t) buf; - iwr.u.data.length = len; - - if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) { - wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed", - __func__, oid, len); - os_free(buf); - return -1; - } - os_free(buf); - return 0; -} - -static int -ralink_get_new_driver_flag(struct wpa_driver_ralink_data *drv) -{ - struct iwreq iwr; - UCHAR enabled = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (UCHAR*) &enabled; - iwr.u.data.flags = RT_OID_NEW_DRIVER; - - if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed", __func__); - return 0; - } - - return (enabled == 1) ? 1 : 0; -} - -static int wpa_driver_ralink_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_ralink_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) { - perror("ioctl[SIOCGIWAP]"); - ret = -1; - } - os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN); - - return ret; -} - -static int wpa_driver_ralink_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_ralink_data *drv = priv; -#if 0 - struct wpa_supplicant *wpa_s = drv->ctx; - struct wpa_ssid *entry; -#endif - int ssid_len; - u8 bssid[ETH_ALEN]; - u8 ssid_str[MAX_SSID_LEN]; - struct iwreq iwr; -#if 0 - int result = 0; -#endif - int ret = 0; -#if 0 - BOOLEAN ieee8021x_mode = FALSE; - BOOLEAN ieee8021x_required_key = FALSE; -#endif - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.essid.pointer = (caddr_t) ssid; - iwr.u.essid.length = 32; - - if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { - perror("ioctl[SIOCGIWESSID]"); - ret = -1; - } else - ret = iwr.u.essid.length; - - if (ret <= 0) - return ret; - - ssid_len = ret; - os_memset(ssid_str, 0, MAX_SSID_LEN); - os_memcpy(ssid_str, ssid, ssid_len); - - if (drv->ap_scan == 0) { - /* Read BSSID form driver */ - if (wpa_driver_ralink_get_bssid(priv, bssid) < 0) { - wpa_printf(MSG_WARNING, "Could not read BSSID from " - "driver."); - return ret; - } - -#if 0 - entry = wpa_s->conf->ssid; - while (entry) { - if (!entry->disabled && ssid_len == entry->ssid_len && - os_memcmp(ssid_str, entry->ssid, ssid_len) == 0 && - (!entry->bssid_set || - os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)) { - /* match the config of driver */ - result = 1; - break; - } - entry = entry->next; - } - - if (result) { - wpa_printf(MSG_DEBUG, "Ready to set 802.1x mode and " - "ieee_required_keys parameters to driver"); - - /* set 802.1x mode and ieee_required_keys parameter */ - if (entry->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { - if ((entry->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) - ieee8021x_required_key = TRUE; - ieee8021x_mode = TRUE; - } - - if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X, (char *) &ieee8021x_mode, sizeof(BOOLEAN)) < 0) - { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set OID_802_11_SET_IEEE8021X(%d)", (int) ieee8021x_mode); - } - else - { - wpa_printf(MSG_DEBUG, "ieee8021x_mode is %s", ieee8021x_mode ? "TRUE" : "FALSE"); - } - - if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0) - { - wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)", (int) ieee8021x_required_key); - } - else - { - wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d)", ieee8021x_required_key ? "TRUE" : "FALSE", - entry->eapol_flags); - } - } -#endif - } - - return ret; -} - -static int wpa_driver_ralink_set_ssid(struct wpa_driver_ralink_data *drv, - const u8 *ssid, size_t ssid_len) -{ - NDIS_802_11_SSID *buf; - int ret = 0; - struct iwreq iwr; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - buf = os_zalloc(sizeof(NDIS_802_11_SSID)); - if (buf == NULL) - return -1; - os_memset(buf, 0, sizeof(buf)); - buf->SsidLength = ssid_len; - os_memcpy(buf->Ssid, ssid, ssid_len); - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - iwr.u.data.flags = OID_802_11_SSID; - iwr.u.data.flags |= OID_GET_SET_TOGGLE; - iwr.u.data.pointer = (caddr_t) buf; - iwr.u.data.length = sizeof(NDIS_802_11_SSID); - - if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) { - perror("ioctl[RT_PRIV_IOCTL] -- OID_802_11_SSID"); - ret = -1; - } - os_free(buf); - return ret; -} - -static void wpa_driver_ralink_event_pmkid(struct wpa_driver_ralink_data *drv, - const u8 *data, size_t data_len) -{ - NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid; - size_t i; - union wpa_event_data event; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (data_len < 8) { - wpa_printf(MSG_DEBUG, "RALINK: Too short PMKID Candidate List " - "Event (len=%lu)", (unsigned long) data_len); - return; - } - pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data; - wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List Event - Version %d" - " NumCandidates %d", - (int) pmkid->Version, (int) pmkid->NumCandidates); - - if (pmkid->Version != 1) { - wpa_printf(MSG_DEBUG, "RALINK: Unsupported PMKID Candidate " - "List Version %d", (int) pmkid->Version); - return; - } - - if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) { - wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List " - "underflow"); - - return; - } - - - - os_memset(&event, 0, sizeof(event)); - for (i = 0; i < pmkid->NumCandidates; i++) { - PMKID_CANDIDATE *p = &pmkid->CandidateList[i]; - wpa_printf(MSG_DEBUG, "RALINK: %lu: " MACSTR " Flags 0x%x", - (unsigned long) i, MAC2STR(p->BSSID), - (int) p->Flags); - os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN); - event.pmkid_candidate.index = i; - event.pmkid_candidate.preauth = - p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; - wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, - &event); - } -} - -static int wpa_driver_ralink_set_pmkid(struct wpa_driver_ralink_data *drv) -{ - int len, count, i, ret; - struct ndis_pmkid_entry *entry; - NDIS_802_11_PMKID *p; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - count = 0; - entry = drv->pmkid; - while (entry) { - count++; - if (count >= drv->no_of_pmkid) - break; - entry = entry->next; - } - len = 8 + count * sizeof(BSSID_INFO); - p = os_zalloc(len); - if (p == NULL) - return -1; - p->Length = len; - p->BSSIDInfoCount = count; - entry = drv->pmkid; - for (i = 0; i < count; i++) { - os_memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN); - os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16); - entry = entry->next; - } - wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", - (const u8 *) p, len); - ret = ralink_set_oid(drv, OID_802_11_PMKID, (char *) p, len); - os_free(p); - return ret; -} - -static int wpa_driver_ralink_add_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_ralink_data *drv = priv; - struct ndis_pmkid_entry *entry, *prev; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (drv->no_of_pmkid == 0) - return 0; - - prev = NULL; - entry = drv->pmkid; - while (entry) { - if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0) - break; - prev = entry; - entry = entry->next; - } - - if (entry) { - /* Replace existing entry for this BSSID and move it into the - * beginning of the list. */ - os_memcpy(entry->pmkid, pmkid, 16); - if (prev) { - prev->next = entry->next; - entry->next = drv->pmkid; - drv->pmkid = entry; - } - } else { - entry = os_malloc(sizeof(*entry)); - if (entry) { - os_memcpy(entry->bssid, bssid, ETH_ALEN); - os_memcpy(entry->pmkid, pmkid, 16); - entry->next = drv->pmkid; - drv->pmkid = entry; - } - } - - return wpa_driver_ralink_set_pmkid(drv); -} - - -static int wpa_driver_ralink_remove_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_ralink_data *drv = priv; - struct ndis_pmkid_entry *entry, *prev; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (drv->no_of_pmkid == 0) - return 0; - - entry = drv->pmkid; - prev = NULL; - drv->pmkid = NULL; - while (entry) { - if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 && - os_memcmp(entry->pmkid, pmkid, 16) == 0) { - if (prev) - prev->next = entry->next; - else - drv->pmkid = entry->next; - os_free(entry); - break; - } - prev = entry; - entry = entry->next; - } - return wpa_driver_ralink_set_pmkid(drv); -} - - -static int wpa_driver_ralink_flush_pmkid(void *priv) -{ - struct wpa_driver_ralink_data *drv = priv; - NDIS_802_11_PMKID p; - struct ndis_pmkid_entry *pmkid, *prev; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (drv->no_of_pmkid == 0) - return 0; - - pmkid = drv->pmkid; - drv->pmkid = NULL; - while (pmkid) { - prev = pmkid; - pmkid = pmkid->next; - os_free(prev); - } - - os_memset(&p, 0, sizeof(p)); - p.Length = 8; - p.BSSIDInfoCount = 0; - wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)", - (const u8 *) &p, 8); - return ralink_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8); -} - -static void -wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv, - void *ctx, char *custom) -{ - union wpa_event_data data; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); - - os_memset(&data, 0, sizeof(data)); - /* Host AP driver */ - if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { - /* receive a MICFAILURE report */ - data.michael_mic_failure.unicast = - os_strstr(custom, " unicast") != NULL; - /* TODO: parse parameters(?) */ - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - } else if (os_strncmp(custom, "ASSOCINFO_ReqIEs=", 17) == 0) { - /* receive assoc. req. IEs */ - char *spos; - int bytes; - - spos = custom + 17; - /*get IE's length */ - /* - * bytes = strlen(spos); ==> bug, bytes may less than original - * size by using this way to get size. snowpin 20070312 - * if (!bytes) - * return; - */ - bytes = drv->assoc_req_ies_len; - - data.assoc_info.req_ies = os_malloc(bytes); - if (data.assoc_info.req_ies == NULL) - return; - - data.assoc_info.req_ies_len = bytes; - os_memcpy(data.assoc_info.req_ies, spos, bytes); - - /* skip the '\0' byte */ - spos += bytes + 1; - - data.assoc_info.resp_ies = NULL; - data.assoc_info.resp_ies_len = 0; - - if (os_strncmp(spos, " RespIEs=", 9) == 0) { - /* receive assoc. resp. IEs */ - spos += 9; - /* get IE's length */ - bytes = os_strlen(spos); - if (!bytes) - goto done; - - - data.assoc_info.resp_ies = os_malloc(bytes); - if (data.assoc_info.resp_ies == NULL) - goto done; - - data.assoc_info.resp_ies_len = bytes; - os_memcpy(data.assoc_info.resp_ies, spos, bytes); - } - - wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - - /* free allocated memory */ - done: - os_free(data.assoc_info.resp_ies); - os_free(data.assoc_info.req_ies); - } -} - -static void -wpa_driver_ralink_event_wireless(struct wpa_driver_ralink_data *drv, - void *ctx, char *data, int len) -{ - struct iw_event iwe_buf, *iwe = &iwe_buf; - char *pos, *end, *custom, *buf, *assoc_info_buf, *info_pos; -#if 0 - BOOLEAN ieee8021x_required_key = FALSE; -#endif - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - assoc_info_buf = info_pos = NULL; - pos = data; - end = data + len; - - while (pos + IW_EV_LCP_LEN <= end) { - /* Event data may be unaligned, so make a local, aligned copy - * before processing. */ - os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); - wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", - iwe->cmd, iwe->len); - if (iwe->len <= IW_EV_LCP_LEN) - return; - - custom = pos + IW_EV_POINT_LEN; - - if (drv->we_version_compiled > 18 && iwe->cmd == IWEVCUSTOM) { - /* WE-19 removed the pointer from struct iw_point */ - char *dpos = (char *) &iwe_buf.u.data.length; - int dlen = dpos - (char *) &iwe_buf; - os_memcpy(dpos, pos + IW_EV_LCP_LEN, - sizeof(struct iw_event) - dlen); - } else { - os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); - custom += IW_EV_POINT_OFF; - } - - switch (iwe->cmd) { - case IWEVCUSTOM: - if (custom + iwe->u.data.length > end) - return; - buf = os_malloc(iwe->u.data.length + 1); - if (buf == NULL) - return; - os_memcpy(buf, custom, iwe->u.data.length); - buf[iwe->u.data.length] = '\0'; - - if (drv->ap_scan == 1) { - if ((iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) - || (iwe->u.data.flags == - RT_REQIE_EVENT_FLAG) || - (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) - || (iwe->u.data.flags == - RT_ASSOCINFO_EVENT_FLAG)) { - if (drv->scanning_done == 0) { - os_free(buf); - return; - } - } - } - - if (iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive ASSOCIATED_EVENT !!!"); - /* determine whether the dynamic-WEP is used or - * not */ -#if 0 - if (wpa_s && wpa_s->current_ssid && - wpa_s->current_ssid->key_mgmt == - WPA_KEY_MGMT_IEEE8021X_NO_WPA) { - if ((wpa_s->current_ssid->eapol_flags & - (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) { - //wpa_printf(MSG_DEBUG, "The current ssid - (%s), eapol_flag = %d.\n", - // wpa_ssid_txt(wpa_s->current_ssid->ssid, wpa_s->current_ssid->ssid_len),wpa_s->current_ssid->eapol_flags); - ieee8021x_required_key = TRUE; - } - - if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0) - { - wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)", - (int) ieee8021x_required_key); - } - - wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d).\n", ieee8021x_required_key ? "TRUE" : "FALSE", - wpa_s->current_ssid->eapol_flags); - } -#endif - - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - } else if (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive ReqIEs !!!"); - drv->assoc_req_ies = - os_malloc(iwe->u.data.length); - if (drv->assoc_req_ies == NULL) { - os_free(buf); - return; - } - - drv->assoc_req_ies_len = iwe->u.data.length; - os_memcpy(drv->assoc_req_ies, custom, - iwe->u.data.length); - } else if (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive RespIEs !!!"); - drv->assoc_resp_ies = - os_malloc(iwe->u.data.length); - if (drv->assoc_resp_ies == NULL) { - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = NULL; - os_free(buf); - return; - } - - drv->assoc_resp_ies_len = iwe->u.data.length; - os_memcpy(drv->assoc_resp_ies, custom, - iwe->u.data.length); - } else if (iwe->u.data.flags == - RT_ASSOCINFO_EVENT_FLAG) { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive ASSOCINFO_EVENT !!!"); - - assoc_info_buf = - os_zalloc(drv->assoc_req_ies_len + - drv->assoc_resp_ies_len + 1); - - if (assoc_info_buf == NULL) { - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = NULL; - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = NULL; - os_free(buf); - return; - } - - if (drv->assoc_req_ies) { - os_memcpy(assoc_info_buf, - drv->assoc_req_ies, - drv->assoc_req_ies_len); - } - info_pos = assoc_info_buf + - drv->assoc_req_ies_len; - if (drv->assoc_resp_ies) { - os_memcpy(info_pos, - drv->assoc_resp_ies, - drv->assoc_resp_ies_len); - } - assoc_info_buf[drv->assoc_req_ies_len + - drv->assoc_resp_ies_len] = '\0'; - wpa_driver_ralink_event_wireless_custom( - drv, ctx, assoc_info_buf); - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = NULL; - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = NULL; - os_free(assoc_info_buf); - } else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG) - { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive DISASSOCIATED_EVENT !!!"); - wpa_supplicant_event(ctx, EVENT_DISASSOC, - NULL); - } else if (iwe->u.data.flags == RT_PMKIDCAND_FLAG) { - wpa_printf(MSG_DEBUG, "Custom wireless event: " - "receive PMKIDCAND_EVENT !!!"); - wpa_driver_ralink_event_pmkid( - drv, (const u8 *) custom, - iwe->u.data.length); - } else if (iwe->u.data.flags == RT_INTERFACE_DOWN) { - drv->g_driver_down = 1; - eloop_terminate(); - } else if (iwe->u.data.flags == RT_REPORT_AP_INFO) { - if (drv->ap_scan != 1) { - typedef struct PACKED { - UCHAR bssid[MAC_ADDR_LEN]; - UCHAR ssid[MAX_LEN_OF_SSID]; - INT ssid_len; - UCHAR wpa_ie[40]; - INT wpa_ie_len; - UCHAR rsn_ie[40]; - INT rsn_ie_len; - INT freq; - USHORT caps; - } *PAPINFO; - - wpa_printf(MSG_DEBUG, "Custom wireless" - " event: receive " - "RT_REPORT_AP_INFO !!!"); - //printf("iwe->u.data.length = %d\n", iwe->u.data.length); - //wpa_hexdump(MSG_DEBUG, "AP_Info: ", buf, iwe->u.data.length); -#if 0 - wpa_s->num_scan_results = 1; - if (wpa_s->scan_results) - os_free(wpa_s->scan_results); - wpa_s->scan_results = os_malloc(sizeof(struct wpa_scan_result) + 1); - if (wpa_s->scan_results) { - PAPINFO pApInfo = (PAPINFO)buf; - os_memcpy(wpa_s->scan_results[0].bssid, pApInfo->bssid, ETH_ALEN); - os_memcpy(wpa_s->scan_results[0].ssid, pApInfo->ssid, pApInfo->ssid_len); - wpa_s->scan_results[0].ssid_len = pApInfo->ssid_len; - if (pApInfo->wpa_ie_len > 0) { - os_memcpy(wpa_s->scan_results[0].wpa_ie, pApInfo->wpa_ie, pApInfo->wpa_ie_len); - wpa_s->scan_results[0].wpa_ie_len = pApInfo->wpa_ie_len; - } else if (pApInfo->rsn_ie_len > 0) { - os_memcpy(wpa_s->scan_results[0].rsn_ie, pApInfo->rsn_ie, pApInfo->rsn_ie_len); - wpa_s->scan_results[0].rsn_ie_len = pApInfo->rsn_ie_len; - } - wpa_s->scan_results[0].caps = pApInfo->caps; - wpa_s->scan_results[0].freq = pApInfo->freq; - } else { - wpa_printf("wpa_s->scan_" - "results fail to " - "os_malloc!!\n"); - } -#endif - } - } else { - wpa_driver_ralink_event_wireless_custom( - drv, ctx, buf); - } - os_free(buf); - break; - } - - pos += iwe->len; - } -} - -static void -wpa_driver_ralink_event_rtm_newlink(struct wpa_driver_ralink_data *drv, - void *ctx, struct nlmsghdr *h, int len) -{ - struct ifinfomsg *ifi; - int attrlen, nlmsg_len, rta_len; - struct rtattr * attr; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (len < (int) sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); - wpa_hexdump(MSG_DEBUG, "ifi: ", (u8 *) ifi, sizeof(struct ifinfomsg)); - - nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - nlmsg_len; - wpa_printf(MSG_DEBUG, "attrlen=%d", attrlen); - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); - wpa_hexdump(MSG_DEBUG, "attr1: ", (u8 *) attr, sizeof(struct rtattr)); - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - wpa_hexdump(MSG_DEBUG, "attr2: ", (u8 *)attr,rta_len); - while (RTA_OK(attr, attrlen)) { - wpa_printf(MSG_DEBUG, "rta_type=%02x\n", attr->rta_type); - if (attr->rta_type == IFLA_WIRELESS) { - wpa_driver_ralink_event_wireless( - drv, ctx, - ((char *) attr) + rta_len, - attr->rta_len - rta_len); - } - attr = RTA_NEXT(attr, attrlen); - wpa_hexdump(MSG_DEBUG, "attr3: ", - (u8 *) attr, sizeof(struct rtattr)); - } -} - -static void wpa_driver_ralink_event_receive(int sock, void *ctx, - void *sock_ctx) -{ - char buf[8192]; - int left; - struct sockaddr_nl from; - socklen_t fromlen; - struct nlmsghdr *h; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - fromlen = sizeof(from); - left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *) &from, &fromlen); - - if (left < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("recvfrom(netlink)"); - return; - } - - h = (struct nlmsghdr *) buf; - wpa_hexdump(MSG_DEBUG, "h: ", (u8 *)h, h->nlmsg_len); - - while (left >= (int) sizeof(*h)) { - int len, plen; - - len = h->nlmsg_len; - plen = len - sizeof(*h); - if (len > left || plen < 0) { - wpa_printf(MSG_DEBUG, "Malformed netlink message: " - "len=%d left=%d plen=%d", len, left, plen); - break; - } - - switch (h->nlmsg_type) { - case RTM_NEWLINK: - wpa_driver_ralink_event_rtm_newlink(ctx, sock_ctx, h, - plen); - break; - } - - len = NLMSG_ALIGN(len); - left -= len; - h = (struct nlmsghdr *) ((char *) h + len); - } - - if (left > 0) { - wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink " - "message", left); - } - -} - -static int -ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv) -{ - struct iwreq iwr; - UINT we_version_compiled = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) &we_version_compiled; - iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED; - - if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed", __func__); - return -1; - } - - drv->we_version_compiled = we_version_compiled; - - return 0; -} - -static int -ralink_set_iface_flags(void *priv, int dev_up) -{ - struct wpa_driver_ralink_data *drv = priv; - struct ifreq ifr; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (drv->ioctl_sock < 0) - return -1; - - os_memset(&ifr, 0, sizeof(ifr)); - os_snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->ifname); - - if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) { - perror("ioctl[SIOCGIFFLAGS]"); - return -1; - } - - if (dev_up) - ifr.ifr_flags |= IFF_UP; - else - ifr.ifr_flags &= ~IFF_UP; - - if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) { - perror("ioctl[SIOCSIFFLAGS]"); - return -1; - } - - return 0; -} - -static void * wpa_driver_ralink_init(void *ctx, const char *ifname) -{ - int s; - struct wpa_driver_ralink_data *drv; - struct ifreq ifr; - struct sockaddr_nl local; - UCHAR enable_wpa_supplicant = 0; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return NULL; - } - /* do it */ - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { - perror(ifr.ifr_name); - return NULL; - } - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - - drv->scanning_done = 1; - drv->ap_scan = 1; /* for now - let's assume ap_scan=1 is used */ - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - drv->ioctl_sock = s; - drv->g_driver_down = 0; - - s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (s < 0) { - perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - os_memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = RTMGRP_LINK; - - if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { - perror("bind(netlink)"); - close(s); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - eloop_register_read_sock(s, wpa_driver_ralink_event_receive, drv, ctx); - drv->event_sock = s; - drv->no_of_pmkid = 4; /* Number of PMKID saved supported */ - - ralink_set_iface_flags(drv, 1); /* mark up during setup */ - ralink_get_we_version_compiled(drv); - wpa_driver_ralink_flush_pmkid(drv); - - if (drv->ap_scan == 1) - enable_wpa_supplicant = 1; - else - enable_wpa_supplicant = 2; - /* trigger driver support wpa_supplicant */ - if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT, - (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0) - { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)", - (int) enable_wpa_supplicant); - wpa_printf(MSG_ERROR, "RALINK: Driver does not support " - "wpa_supplicant"); - close(s); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - if (drv->ap_scan == 1) - drv->scanning_done = 0; - - return drv; -} - -static void wpa_driver_ralink_deinit(void *priv) -{ - struct wpa_driver_ralink_data *drv = priv; - UCHAR enable_wpa_supplicant; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - enable_wpa_supplicant = 0; - - if (drv->g_driver_down == 0) { - /* trigger driver disable wpa_supplicant support */ - if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT, - (char *) &enable_wpa_supplicant, - sizeof(BOOLEAN)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)", - (int) enable_wpa_supplicant); - } - - wpa_driver_ralink_flush_pmkid(drv); - - sleep(1); - ralink_set_iface_flags(drv, 0); - } - - eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx); - eloop_unregister_read_sock(drv->event_sock); - close(drv->event_sock); - close(drv->ioctl_sock); - os_free(drv); -} - -static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - struct wpa_driver_ralink_data *drv = eloop_ctx; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); - - drv->scanning_done = 1; - -} - -static int wpa_driver_ralink_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_ralink_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (ssid_len > IW_ESSID_MAX_SIZE) { - wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)", - __FUNCTION__, (unsigned long) ssid_len); - return -1; - } - - /* wpa_driver_ralink_set_ssid(drv, ssid, ssid_len); */ - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) { - perror("ioctl[SIOCSIWSCAN]"); - ret = -1; - } - - /* Not all drivers generate "scan completed" wireless event, so try to - * read results after a timeout. */ - eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx); - eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv, - drv->ctx); - - drv->scanning_done = 0; - - return ret; -} - -static int -wpa_driver_ralink_get_scan_results(void *priv, - struct wpa_scan_result *results, - size_t max_size) -{ - struct wpa_driver_ralink_data *drv = priv; - UCHAR *buf = NULL; - NDIS_802_11_BSSID_LIST_EX *wsr; - NDIS_WLAN_BSSID_EX *wbi; - struct iwreq iwr; - int rv = 0; - size_t ap_num; - u8 *pos, *end; - - if (drv->g_driver_down == 1) - return -1; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (drv->we_version_compiled >= 17) { - buf = os_zalloc(8192); - iwr.u.data.length = 8192; - } else { - buf = os_zalloc(4096); - iwr.u.data.length = 4096; - } - if (buf == NULL) - return -1; - - wsr = (NDIS_802_11_BSSID_LIST_EX *) buf; - - wsr->NumberOfItems = 0; - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (void *) buf; - iwr.u.data.flags = OID_802_11_BSSID_LIST; - - if ((rv = ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr)) < 0) { - wpa_printf(MSG_DEBUG, "ioctl fail: rv = %d", rv); - os_free(buf); - return -1; - } - - os_memset(results, 0, max_size * sizeof(struct wpa_scan_result)); - - for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems; - ++ap_num) { - os_memcpy(results[ap_num].bssid, &wbi->MacAddress, ETH_ALEN); - os_memcpy(results[ap_num].ssid, wbi->Ssid.Ssid, - wbi->Ssid.SsidLength); - results[ap_num].ssid_len = wbi->Ssid.SsidLength; - results[ap_num].freq = (wbi->Configuration.DSConfig / 1000); - - /* get ie's */ - wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs", - (u8 *) wbi + sizeof(*wbi) - 1, wbi->IELength); - - pos = (u8 *) wbi + sizeof(*wbi) - 1; - end = (u8 *) wbi + sizeof(*wbi) + wbi->IELength; - - if (wbi->IELength < sizeof(NDIS_802_11_FIXED_IEs)) - break; - - pos += sizeof(NDIS_802_11_FIXED_IEs) - 2; - os_memcpy(&results[ap_num].caps, pos, 2); - pos += 2; - - while (pos + 1 < end && pos + 2 + pos[1] <= end) { - u8 ielen = 2 + pos[1]; - - if (ielen > SSID_MAX_WPA_IE_LEN) { - pos += ielen; - continue; - } - - if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && - pos[1] >= 4 && - os_memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) { - os_memcpy(results[ap_num].wpa_ie, pos, ielen); - results[ap_num].wpa_ie_len = ielen; - } else if (pos[0] == WLAN_EID_RSN) { - os_memcpy(results[ap_num].rsn_ie, pos, ielen); - results[ap_num].rsn_ie_len = ielen; - } - pos += ielen; - } - - wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length); - } - - os_free(buf); - return ap_num; -} - -static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv, - NDIS_802_11_AUTHENTICATION_MODE mode) -{ - NDIS_802_11_AUTHENTICATION_MODE auth_mode = mode; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (ralink_set_oid(drv, OID_802_11_AUTHENTICATION_MODE, - (char *) &auth_mode, sizeof(auth_mode)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_AUTHENTICATION_MODE (%d)", - (int) auth_mode); - return -1; - } - return 0; -} - -static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv, - int key_idx, const u8 *addr, - const u8 *bssid, int pairwise) -{ - NDIS_802_11_REMOVE_KEY rkey; - NDIS_802_11_KEY_INDEX _index; - int res, res2; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - os_memset(&rkey, 0, sizeof(rkey)); - - rkey.Length = sizeof(rkey); - rkey.KeyIndex = key_idx; - - if (pairwise) - rkey.KeyIndex |= 1 << 30; - - os_memcpy(rkey.BSSID, bssid, ETH_ALEN); - - res = ralink_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey, - sizeof(rkey)); - - /* AlbertY@20060210 removed it */ - if (0 /* !pairwise */) { - res2 = ralink_set_oid(drv, OID_802_11_REMOVE_WEP, - (char *) &_index, sizeof(_index)); - } else - res2 = 0; - - if (res < 0 && res2 < 0) - return res; - return 0; -} - -static int wpa_driver_ralink_add_wep(struct wpa_driver_ralink_data *drv, - int pairwise, int key_idx, int set_tx, - const u8 *key, size_t key_len) -{ - NDIS_802_11_WEP *wep; - size_t len; - int res; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - len = 12 + key_len; - wep = os_zalloc(len); - if (wep == NULL) - return -1; - - wep->Length = len; - wep->KeyIndex = key_idx; - - if (set_tx) - wep->KeyIndex |= 0x80000000; - - wep->KeyLength = key_len; - os_memcpy(wep->KeyMaterial, key, key_len); - - wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_WEP", - (const u8 *) wep, len); - res = ralink_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len); - - os_free(wep); - - return res; -} - -static int wpa_driver_ralink_set_key(void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_ralink_data *drv = priv; - size_t len, i; - NDIS_802_11_KEY *nkey; - int res, pairwise; - u8 bssid[ETH_ALEN]; - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", - ETH_ALEN) == 0) { - /* Group Key */ - pairwise = 0; - wpa_driver_ralink_get_bssid(drv, bssid); - } else { - /* Pairwise Key */ - pairwise = 1; - os_memcpy(bssid, addr, ETH_ALEN); - } - - if (alg == WPA_ALG_NONE || key_len == 0) { - return wpa_driver_ralink_remove_key(drv, key_idx, addr, bssid, - pairwise); - } - - if (alg == WPA_ALG_WEP) { - return wpa_driver_ralink_add_wep(drv, pairwise, key_idx, - set_tx, key, key_len); - } - - len = 12 + 6 + 6 + 8 + key_len; - - nkey = os_zalloc(len); - if (nkey == NULL) - return -1; - - nkey->Length = len; - nkey->KeyIndex = key_idx; - - if (set_tx) - nkey->KeyIndex |= 1 << 31; - - if (pairwise) - nkey->KeyIndex |= 1 << 30; - - if (seq && seq_len) - nkey->KeyIndex |= 1 << 29; - - nkey->KeyLength = key_len; - os_memcpy(nkey->BSSID, bssid, ETH_ALEN); - - if (seq && seq_len) { - for (i = 0; i < seq_len; i++) - nkey->KeyRSC |= seq[i] << (i * 8); - } - if (alg == WPA_ALG_TKIP && key_len == 32) { - os_memcpy(nkey->KeyMaterial, key, 16); - os_memcpy(nkey->KeyMaterial + 16, key + 24, 8); - os_memcpy(nkey->KeyMaterial + 24, key + 16, 8); - } else { - os_memcpy(nkey->KeyMaterial, key, key_len); - } - - wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", __FUNCTION__, alg, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_KEY", - (const u8 *) nkey, len); - res = ralink_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len); - os_free(nkey); - - return res; -} - -static int wpa_driver_ralink_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_ralink_data *drv = priv; - - if (drv->g_driver_down == 1) - return -1; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - if (ralink_set_oid(drv, OID_802_11_DISASSOCIATE, " ", 4) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_DISASSOCIATE"); - } - - return 0; -} - -static int wpa_driver_ralink_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_ralink_data *drv = priv; - - wpa_printf(MSG_DEBUG, "g_driver_down = %d", drv->g_driver_down); - - if (drv->g_driver_down == 1) - return -1; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - if (ralink_get_new_driver_flag(drv) == 0) { - return wpa_driver_ralink_disassociate(priv, addr, reason_code); - } else { - MLME_DEAUTH_REQ_STRUCT mlme; - os_memset(&mlme, 0, sizeof(MLME_DEAUTH_REQ_STRUCT)); - mlme.Reason = reason_code; - os_memcpy(mlme.Addr, addr, MAC_ADDR_LEN); - return ralink_set_oid(drv, OID_802_11_DEAUTHENTICATION, - (char *) &mlme, - sizeof(MLME_DEAUTH_REQ_STRUCT)); - } -} - -static int -wpa_driver_ralink_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_ralink_data *drv = priv; - - NDIS_802_11_NETWORK_INFRASTRUCTURE mode; - NDIS_802_11_AUTHENTICATION_MODE auth_mode; - NDIS_802_11_WEP_STATUS encr; - BOOLEAN ieee8021xMode; - - if (drv->g_driver_down == 1) - return -1; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (params->mode == IEEE80211_MODE_IBSS) - mode = Ndis802_11IBSS; - else - mode = Ndis802_11Infrastructure; - - if (ralink_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE, - (char *) &mode, sizeof(mode)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_INFRASTRUCTURE_MODE (%d)", - (int) mode); - /* Try to continue anyway */ - } - - if (params->wpa_ie == NULL || params->wpa_ie_len == 0) { - if (params->auth_alg & AUTH_ALG_SHARED_KEY) { - if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM) - auth_mode = Ndis802_11AuthModeAutoSwitch; - else - auth_mode = Ndis802_11AuthModeShared; - } else - auth_mode = Ndis802_11AuthModeOpen; - } else if (params->wpa_ie[0] == WLAN_EID_RSN) { - if (params->key_mgmt_suite == KEY_MGMT_PSK) - auth_mode = Ndis802_11AuthModeWPA2PSK; - else - auth_mode = Ndis802_11AuthModeWPA2; - } else { - if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE) - auth_mode = Ndis802_11AuthModeWPANone; - else if (params->key_mgmt_suite == KEY_MGMT_PSK) - auth_mode = Ndis802_11AuthModeWPAPSK; - else - auth_mode = Ndis802_11AuthModeWPA; - } - - switch (params->pairwise_suite) { - case CIPHER_CCMP: - encr = Ndis802_11Encryption3Enabled; - break; - case CIPHER_TKIP: - encr = Ndis802_11Encryption2Enabled; - break; - case CIPHER_WEP40: - case CIPHER_WEP104: - encr = Ndis802_11Encryption1Enabled; - break; - case CIPHER_NONE: - if (params->group_suite == CIPHER_CCMP) - encr = Ndis802_11Encryption3Enabled; - else if (params->group_suite == CIPHER_TKIP) - encr = Ndis802_11Encryption2Enabled; - else - encr = Ndis802_11EncryptionDisabled; - break; - default: - encr = Ndis802_11EncryptionDisabled; - break; - } - - ralink_set_auth_mode(drv, auth_mode); - - /* notify driver that IEEE8021x mode is enabled */ - if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) - ieee8021xMode = TRUE; - else - ieee8021xMode = FALSE; - - if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X, - (char *) &ieee8021xMode, sizeof(BOOLEAN)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_SET_IEEE8021X(%d)", - (int) ieee8021xMode); - } - - if (ralink_set_oid(drv, OID_802_11_WEP_STATUS, - (char *) &encr, sizeof(encr)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_WEP_STATUS(%d)", - (int) encr); - } - - if ((ieee8021xMode == FALSE) && - (encr == Ndis802_11Encryption1Enabled)) { - /* static WEP */ - int enabled = 0; - if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED, - (char *) &enabled, sizeof(enabled)) < 0) { - wpa_printf(MSG_DEBUG, "RALINK: Failed to set " - "OID_802_11_DROP_UNENCRYPTED(%d)", - (int) encr); - } - } - - return wpa_driver_ralink_set_ssid(drv, params->ssid, params->ssid_len); -} - -static int -wpa_driver_ralink_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_ralink_data *drv = priv; - if (drv->g_driver_down == 1) - return -1; - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return ralink_set_oid(drv, OID_SET_COUNTERMEASURES, (char *) &enabled, - sizeof(int)); -} - -const struct wpa_driver_ops wpa_driver_ralink_ops = { - .name = "ralink", - .desc = "Ralink Wireless Client driver", - .get_bssid = wpa_driver_ralink_get_bssid, - .get_ssid = wpa_driver_ralink_get_ssid, - .set_key = wpa_driver_ralink_set_key, - .init = wpa_driver_ralink_init, - .deinit = wpa_driver_ralink_deinit, - .set_countermeasures = wpa_driver_ralink_set_countermeasures, - .scan = wpa_driver_ralink_scan, - .get_scan_results = wpa_driver_ralink_get_scan_results, - .deauthenticate = wpa_driver_ralink_deauthenticate, - .disassociate = wpa_driver_ralink_disassociate, - .associate = wpa_driver_ralink_associate, - .add_pmkid = wpa_driver_ralink_add_pmkid, - .remove_pmkid = wpa_driver_ralink_remove_pmkid, - .flush_pmkid = wpa_driver_ralink_flush_pmkid, -}; diff --git a/contrib/wpa/src/drivers/driver_ralink.h b/contrib/wpa/src/drivers/driver_ralink.h deleted file mode 100644 index ddf44de..0000000 --- a/contrib/wpa/src/drivers/driver_ralink.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * WPA Supplicant - driver_ralink exported functions - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * Copyright (c) 2007, Snowpin Lee <snowpin_lee@ralinktech.com.tw> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -// Ralink defined OIDs -#if WIRELESS_EXT <= 11 -#ifndef SIOCDEVPRIVATE -#define SIOCDEVPRIVATE 0x8BE0 -#endif -#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE -#endif - -#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) -#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) - -// IEEE 802.11 OIDs & Ralink defined OIDs ****** - -// (RaConfig Set/QueryInform) ==> -#define OID_GET_SET_TOGGLE 0x8000 - -#define OID_802_11_ADD_WEP 0x0112 -#define OID_802_11_REMOVE_WEP 0x0113 -#define OID_802_11_DISASSOCIATE 0x0114 -#define OID_802_11_PRIVACY_FILTER 0x0118 -#define OID_802_11_ASSOCIATION_INFORMATION 0x011E -#define OID_802_11_BSSID_LIST_SCAN 0x0508 -#define OID_802_11_SSID 0x0509 -#define OID_802_11_BSSID 0x050A -#define OID_802_11_WEP_STATUS 0x0510 -#define OID_802_11_AUTHENTICATION_MODE 0x0511 -#define OID_802_11_INFRASTRUCTURE_MODE 0x0512 -#define OID_802_11_TX_POWER_LEVEL 0x0517 -#define OID_802_11_REMOVE_KEY 0x0519 -#define OID_802_11_ADD_KEY 0x0520 -#define OID_802_11_DEAUTHENTICATION 0x0526 -#define OID_802_11_DROP_UNENCRYPTED 0x0527 -#define OID_802_11_BSSID_LIST 0x0609 -#define OID_802_3_CURRENT_ADDRESS 0x060A -#define OID_SET_COUNTERMEASURES 0x0616 -#define OID_802_11_SET_IEEE8021X 0x0617 // For IEEE8021x mode -#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618 // For DynamicWEP in IEEE802.1x mode -#define OID_802_11_PMKID 0x0620 -#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621 // for trigger driver enable/disable wpa_supplicant support -#define RT_OID_WE_VERSION_COMPILED 0x0622 -#define RT_OID_NEW_DRIVER 0x0623 - -#define PACKED __attribute__ ((packed)) - -//wpa_supplicant event flags -#define RT_ASSOC_EVENT_FLAG 0x0101 -#define RT_DISASSOC_EVENT_FLAG 0x0102 -#define RT_REQIE_EVENT_FLAG 0x0103 -#define RT_RESPIE_EVENT_FLAG 0x0104 -#define RT_ASSOCINFO_EVENT_FLAG 0x0105 -#define RT_PMKIDCAND_FLAG 0x0106 -#define RT_INTERFACE_DOWN 0x0107 -#define RT_REPORT_AP_INFO 0x0108 - -// -// IEEE 802.11 Structures and definitions -// -// new types for Media Specific Indications - -#ifndef ULONG -#define CHAR char -#define INT int -#define SHORT int -#define UINT u32 -#undef ULONG -//#define ULONG u32 -#define ULONG unsigned long /* 32-bit in 32-bit CPU or 64-bit in 64-bit CPU */ -#define USHORT unsigned short -#define UCHAR unsigned char - -#define uint32 u32 -#define uint8 u8 - - -#define BOOLEAN u8 -//#define LARGE_INTEGER s64 -#define VOID void -#define LONG long -#define LONGLONG s64 -#define ULONGLONG u64 -typedef VOID *PVOID; -typedef CHAR *PCHAR; -typedef UCHAR *PUCHAR; -typedef USHORT *PUSHORT; -typedef LONG *PLONG; -typedef ULONG *PULONG; - -typedef union _LARGE_INTEGER { - struct { - ULONG LowPart; - LONG HighPart; - }vv; - struct { - ULONG LowPart; - LONG HighPart; - } u; - s64 QuadPart; -} LARGE_INTEGER; - -#endif - -#define NDIS_802_11_LENGTH_SSID 32 -#define NDIS_802_11_LENGTH_RATES 8 -#define NDIS_802_11_LENGTH_RATES_EX 16 -#define MAX_LEN_OF_SSID 32 -#define MAC_ADDR_LEN 6 - -typedef UCHAR NDIS_802_11_MAC_ADDRESS[6]; - -// mask for authentication/integrity fields -#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f - -#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 -#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 -#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 -#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E - -// Added new types for OFDM 5G and 2.4G -typedef enum _NDIS_802_11_NETWORK_TYPE -{ - Ndis802_11FH, - Ndis802_11DS, - Ndis802_11OFDM5, - Ndis802_11OFDM24, - Ndis802_11Automode, - Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound -} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; - -// -// Received Signal Strength Indication -// -typedef LONG NDIS_802_11_RSSI; // in dBm - -typedef struct _NDIS_802_11_CONFIGURATION_FH -{ - ULONG Length; // Length of structure - ULONG HopPattern; // As defined by 802.11, MSB set - ULONG HopSet; // to one if non-802.11 - ULONG DwellTime; // units are Kusec -} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; - -typedef struct _NDIS_802_11_CONFIGURATION -{ - ULONG Length; // Length of structure - ULONG BeaconPeriod; // units are Kusec - ULONG ATIMWindow; // units are Kusec - ULONG DSConfig; // Frequency, units are kHz - NDIS_802_11_CONFIGURATION_FH FHConfig; -} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; - -typedef ULONG NDIS_802_11_KEY_INDEX; -typedef ULONGLONG NDIS_802_11_KEY_RSC; - -// Key mapping keys require a BSSID -typedef struct _NDIS_802_11_KEY -{ - UINT Length; // Length of this structure - UINT KeyIndex; - UINT KeyLength; // length of key in bytes - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_KEY_RSC KeyRSC; - UCHAR KeyMaterial[1]; // variable length depending on above field -} NDIS_802_11_KEY, *PNDIS_802_11_KEY; - -typedef struct _NDIS_802_11_REMOVE_KEY -{ - UINT Length; // Length of this structure - UINT KeyIndex; - NDIS_802_11_MAC_ADDRESS BSSID; -} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; - -typedef struct PACKED _NDIS_802_11_WEP -{ - UINT Length; // Length of this structure - UINT KeyIndex; // 0 is the per-client key, 1-N are the - // global keys - UINT KeyLength; // length of key in bytes - UCHAR KeyMaterial[1];// variable length depending on above field -} NDIS_802_11_WEP, *PNDIS_802_11_WEP; - - -typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE -{ - Ndis802_11IBSS, - Ndis802_11Infrastructure, - Ndis802_11AutoUnknown, - Ndis802_11InfrastructureMax // Not a real value, defined as upper bound -} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; - -// PMKID Structures -typedef UCHAR NDIS_802_11_PMKID_VALUE[16]; - -typedef struct _BSSID_INFO -{ - NDIS_802_11_MAC_ADDRESS BSSID; - NDIS_802_11_PMKID_VALUE PMKID; -} BSSID_INFO, *PBSSID_INFO; - -typedef struct _NDIS_802_11_PMKID -{ - ULONG Length; - ULONG BSSIDInfoCount; - BSSID_INFO BSSIDInfo[1]; -} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID; - -//Added new types for PMKID Candidate lists. -typedef struct _PMKID_CANDIDATE { - NDIS_802_11_MAC_ADDRESS BSSID; - ULONG Flags; -} PMKID_CANDIDATE, *PPMKID_CANDIDATE; - -typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST -{ - ULONG Version; // Version of the structure - ULONG NumCandidates; // No. of pmkid candidates - PMKID_CANDIDATE CandidateList[1]; -} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST; - -//Flags for PMKID Candidate list structure -#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 - -// Add new authentication modes -typedef enum _NDIS_802_11_AUTHENTICATION_MODE -{ - Ndis802_11AuthModeOpen, - Ndis802_11AuthModeShared, - Ndis802_11AuthModeAutoSwitch, - Ndis802_11AuthModeWPA, - Ndis802_11AuthModeWPAPSK, - Ndis802_11AuthModeWPANone, - Ndis802_11AuthModeWPA2, - Ndis802_11AuthModeWPA2PSK, - Ndis802_11AuthModeMax // Not a real mode, defined as upper bound -} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; - -typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates -typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates - -typedef struct PACKED _NDIS_802_11_SSID -{ - INT SsidLength; // length of SSID field below, in bytes; - // this can be zero. - UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field -} NDIS_802_11_SSID, *PNDIS_802_11_SSID; - - -typedef struct PACKED _NDIS_WLAN_BSSID -{ - ULONG Length; // Length of this structure - NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID - UCHAR Reserved[2]; - NDIS_802_11_SSID Ssid; // SSID - ULONG Privacy; // WEP encryption requirement - NDIS_802_11_RSSI Rssi; // receive signal - // strength in dBm - NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - NDIS_802_11_CONFIGURATION Configuration; - NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - NDIS_802_11_RATES SupportedRates; -} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID; - -typedef struct PACKED _NDIS_802_11_BSSID_LIST -{ - UINT NumberOfItems; // in list below, at least 1 - NDIS_WLAN_BSSID Bssid[1]; -} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST; - -// Added Capabilities, IELength and IEs for each BSSID -typedef struct PACKED _NDIS_WLAN_BSSID_EX -{ - ULONG Length; // Length of this structure - NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID - UCHAR Reserved[2]; - NDIS_802_11_SSID Ssid; // SSID - UINT Privacy; // WEP encryption requirement - NDIS_802_11_RSSI Rssi; // receive signal - // strength in dBm - NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; - NDIS_802_11_CONFIGURATION Configuration; - NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; - NDIS_802_11_RATES_EX SupportedRates; - ULONG IELength; - UCHAR IEs[1]; -} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; - -typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX -{ - UINT NumberOfItems; // in list below, at least 1 - NDIS_WLAN_BSSID_EX Bssid[1]; -} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; - -typedef struct PACKED _NDIS_802_11_FIXED_IEs -{ - UCHAR Timestamp[8]; - USHORT BeaconInterval; - USHORT Capabilities; -} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; - -// Added new encryption types -// Also aliased typedef to new name -typedef enum _NDIS_802_11_WEP_STATUS -{ - Ndis802_11WEPEnabled, - Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, - Ndis802_11WEPDisabled, - Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, - Ndis802_11WEPKeyAbsent, - Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, - Ndis802_11WEPNotSupported, - Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, - Ndis802_11Encryption2Enabled, - Ndis802_11Encryption2KeyAbsent, - Ndis802_11Encryption3Enabled, - Ndis802_11Encryption3KeyAbsent -} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, - NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; - -typedef enum _NDIS_802_11_RELOAD_DEFAULTS -{ - Ndis802_11ReloadWEPKeys -} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; - -#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 -#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 -#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 - -#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 -#define NDIS_802_11_AI_RESFI_STATUSCODE 2 -#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 - -typedef struct _NDIS_802_11_AI_REQFI -{ - USHORT Capabilities; - USHORT ListenInterval; - NDIS_802_11_MAC_ADDRESS CurrentAPAddress; -} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; - -typedef struct _NDIS_802_11_AI_RESFI -{ - USHORT Capabilities; - USHORT StatusCode; - USHORT AssociationId; -} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; - -typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION -{ - ULONG Length; - USHORT AvailableRequestFixedIEs; - NDIS_802_11_AI_REQFI RequestFixedIEs; - ULONG RequestIELength; - ULONG OffsetRequestIEs; - USHORT AvailableResponseFixedIEs; - NDIS_802_11_AI_RESFI ResponseFixedIEs; - ULONG ResponseIELength; - ULONG OffsetResponseIEs; -} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; - -struct ndis_pmkid_entry { - struct ndis_pmkid_entry *next; - u8 bssid[ETH_ALEN]; - u8 pmkid[16]; -}; - -typedef struct _MLME_DEAUTH_REQ_STRUCT { - UCHAR Addr[MAC_ADDR_LEN]; - USHORT Reason; -} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT; diff --git a/contrib/wpa/src/drivers/driver_roboswitch.c b/contrib/wpa/src/drivers/driver_roboswitch.c deleted file mode 100644 index bc11a48..0000000 --- a/contrib/wpa/src/drivers/driver_roboswitch.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * WPA Supplicant - roboswitch driver interface - * Copyright (c) 2008-2009 Jouke Witteveen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> -#include <linux/if.h> -#include <linux/sockios.h> -#include <linux/if_ether.h> -#include <linux/mii.h> - -#include "common.h" -#include "driver.h" -#include "l2_packet/l2_packet.h" - -#ifndef ETH_P_EAPOL -#define ETH_P_EAPOL 0x888e -#endif - -#define ROBO_PHY_ADDR 0x1e /* RoboSwitch PHY address */ - -/* MII access registers */ -#define ROBO_MII_PAGE 0x10 /* MII page register */ -#define ROBO_MII_ADDR 0x11 /* MII address register */ -#define ROBO_MII_DATA_OFFSET 0x18 /* Start of MII data registers */ - -#define ROBO_MII_PAGE_ENABLE 0x01 /* MII page op code */ -#define ROBO_MII_ADDR_WRITE 0x01 /* MII address write op code */ -#define ROBO_MII_ADDR_READ 0x02 /* MII address read op code */ -#define ROBO_MII_DATA_MAX 4 /* Consecutive MII data registers */ -#define ROBO_MII_RETRY_MAX 10 /* Read attempts before giving up */ - -/* Page numbers */ -#define ROBO_ARLCTRL_PAGE 0x04 /* ARL control page */ -#define ROBO_VLAN_PAGE 0x34 /* VLAN page */ - -/* ARL control page registers */ -#define ROBO_ARLCTRL_CONF 0x00 /* ARL configuration register */ -#define ROBO_ARLCTRL_ADDR_1 0x10 /* Multiport address 1 */ -#define ROBO_ARLCTRL_VEC_1 0x16 /* Multiport vector 1 */ -#define ROBO_ARLCTRL_ADDR_2 0x20 /* Multiport address 2 */ -#define ROBO_ARLCTRL_VEC_2 0x26 /* Multiport vector 2 */ - -/* VLAN page registers */ -#define ROBO_VLAN_ACCESS 0x08 /* VLAN table access register */ -#define ROBO_VLAN_ACCESS_5350 0x06 /* VLAN table access register (5350) */ -#define ROBO_VLAN_READ 0x0c /* VLAN read register */ -#define ROBO_VLAN_MAX 0xff /* Maximum number of VLANs */ - - -static const u8 pae_group_addr[ETH_ALEN] = -{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; - - -struct wpa_driver_roboswitch_data { - void *ctx; - struct l2_packet_data *l2; - char ifname[IFNAMSIZ + 1]; - u8 own_addr[ETH_ALEN]; - struct ifreq ifr; - int fd, is_5350; - u16 ports; -}; - - -/* Copied from the kernel-only part of mii.h. */ -static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) -{ - return (struct mii_ioctl_data *) &rq->ifr_ifru; -} - - -/* - * RoboSwitch uses 16-bit Big Endian addresses. - * The ordering of the words is reversed in the MII registers. - */ -static void wpa_driver_roboswitch_addr_be16(const u8 addr[ETH_ALEN], u16 *be) -{ - int i; - for (i = 0; i < ETH_ALEN; i += 2) - be[(ETH_ALEN - i) / 2 - 1] = WPA_GET_BE16(addr + i); -} - - -static u16 wpa_driver_roboswitch_mdio_read( - struct wpa_driver_roboswitch_data *drv, u8 reg) -{ - struct mii_ioctl_data *mii = if_mii(&drv->ifr); - - mii->phy_id = ROBO_PHY_ADDR; - mii->reg_num = reg; - - if (ioctl(drv->fd, SIOCGMIIREG, &drv->ifr) < 0) { - perror("ioctl[SIOCGMIIREG]"); - return 0x00; - } - return mii->val_out; -} - - -static void wpa_driver_roboswitch_mdio_write( - struct wpa_driver_roboswitch_data *drv, u8 reg, u16 val) -{ - struct mii_ioctl_data *mii = if_mii(&drv->ifr); - - mii->phy_id = ROBO_PHY_ADDR; - mii->reg_num = reg; - mii->val_in = val; - - if (ioctl(drv->fd, SIOCSMIIREG, &drv->ifr) < 0) { - perror("ioctl[SIOCSMIIREG"); - } -} - - -static int wpa_driver_roboswitch_reg(struct wpa_driver_roboswitch_data *drv, - u8 page, u8 reg, u8 op) -{ - int i; - - /* set page number */ - wpa_driver_roboswitch_mdio_write(drv, ROBO_MII_PAGE, - (page << 8) | ROBO_MII_PAGE_ENABLE); - /* set register address */ - wpa_driver_roboswitch_mdio_write(drv, ROBO_MII_ADDR, (reg << 8) | op); - - /* check if operation completed */ - for (i = 0; i < ROBO_MII_RETRY_MAX; ++i) { - if ((wpa_driver_roboswitch_mdio_read(drv, ROBO_MII_ADDR) & 3) - == 0) - return 0; - } - /* timeout */ - return -1; -} - - -static int wpa_driver_roboswitch_read(struct wpa_driver_roboswitch_data *drv, - u8 page, u8 reg, u16 *val, int len) -{ - int i; - - if (len > ROBO_MII_DATA_MAX || - wpa_driver_roboswitch_reg(drv, page, reg, ROBO_MII_ADDR_READ) < 0) - return -1; - - for (i = 0; i < len; ++i) { - val[i] = wpa_driver_roboswitch_mdio_read( - drv, ROBO_MII_DATA_OFFSET + i); - } - - return 0; -} - - -static int wpa_driver_roboswitch_write(struct wpa_driver_roboswitch_data *drv, - u8 page, u8 reg, u16 *val, int len) -{ - int i; - - if (len > ROBO_MII_DATA_MAX) return -1; - for (i = 0; i < len; ++i) { - wpa_driver_roboswitch_mdio_write(drv, ROBO_MII_DATA_OFFSET + i, - val[i]); - } - return wpa_driver_roboswitch_reg(drv, page, reg, ROBO_MII_ADDR_WRITE); -} - - -static void wpa_driver_roboswitch_receive(void *priv, const u8 *src_addr, - const u8 *buf, size_t len) -{ - struct wpa_driver_roboswitch_data *drv = priv; - - if (len > 14 && WPA_GET_BE16(buf + 12) == ETH_P_EAPOL && - os_memcmp(buf, drv->own_addr, ETH_ALEN) == 0) { - wpa_supplicant_rx_eapol(drv->ctx, src_addr, buf + 14, - len - 14); - } -} - - -static int wpa_driver_roboswitch_get_ssid(void *priv, u8 *ssid) -{ - ssid[0] = 0; - return 0; -} - - -static int wpa_driver_roboswitch_get_bssid(void *priv, u8 *bssid) -{ - /* Report PAE group address as the "BSSID" for wired connection. */ - os_memcpy(bssid, pae_group_addr, ETH_ALEN); - return 0; -} - - -static int wpa_driver_roboswitch_set_param(void *priv, const char *param) -{ - struct wpa_driver_roboswitch_data *drv = priv; - char *sep; - - if (param == NULL || os_strstr(param, "multicast_only=1") == NULL) { - sep = drv->ifname + os_strlen(drv->ifname); - *sep = '.'; - drv->l2 = l2_packet_init(drv->ifname, NULL, ETH_P_ALL, - wpa_driver_roboswitch_receive, drv, - 1); - if (drv->l2 == NULL) { - wpa_printf(MSG_INFO, "%s: Unable to listen on %s", - __func__, drv->ifname); - return -1; - } - *sep = '\0'; - l2_packet_get_own_addr(drv->l2, drv->own_addr); - } else { - wpa_printf(MSG_DEBUG, "%s: Ignoring unicast frames", __func__); - drv->l2 = NULL; - } - return 0; -} - - -static const char * wpa_driver_roboswitch_get_ifname(void *priv) -{ - struct wpa_driver_roboswitch_data *drv = priv; - return drv->ifname; -} - - -static int wpa_driver_roboswitch_join(struct wpa_driver_roboswitch_data *drv, - u16 ports, const u8 *addr) -{ - u16 read1[3], read2[3], addr_be16[3]; - - wpa_driver_roboswitch_addr_be16(addr, addr_be16); - - if (wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_CONF, read1, 1) < 0) - return -1; - if (!(read1[0] & (1 << 4))) { - /* multiport addresses are not yet enabled */ - read1[0] |= 1 << 4; - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, addr_be16, 3); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_1, &ports, 1); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_2, addr_be16, 3); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_2, &ports, 1); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_CONF, read1, 1); - } else { - /* if both multiport addresses are the same we can add */ - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, read1, 3); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_2, read2, 3); - if (os_memcmp(read1, read2, 6) != 0) - return -1; - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_1, read1, 1); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_2, read2, 1); - if (read1[0] != read2[0]) - return -1; - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, addr_be16, 3); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_1, &ports, 1); - } - return 0; -} - - -static int wpa_driver_roboswitch_leave(struct wpa_driver_roboswitch_data *drv, - u16 ports, const u8 *addr) -{ - u16 _read, addr_be16[3], addr_read[3], ports_read; - - wpa_driver_roboswitch_addr_be16(addr, addr_be16); - - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_CONF, - &_read, 1); - /* If ARL control is disabled, there is nothing to leave. */ - if (!(_read & (1 << 4))) return -1; - - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, addr_read, 3); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, ROBO_ARLCTRL_VEC_1, - &ports_read, 1); - /* check if we occupy multiport address 1 */ - if (os_memcmp(addr_read, addr_be16, 6) == 0 && ports_read == ports) { - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_2, addr_read, 3); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_2, &ports_read, 1); - /* and multiport address 2 */ - if (os_memcmp(addr_read, addr_be16, 6) == 0 && - ports_read == ports) { - _read &= ~(1 << 4); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_CONF, &_read, - 1); - } else { - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, - addr_read, 3); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_1, - &ports_read, 1); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_2, - addr_read, 3); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_2, - &ports_read, 1); - } - } else { - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_2, addr_read, 3); - wpa_driver_roboswitch_read(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_2, &ports_read, 1); - /* or multiport address 2 */ - if (os_memcmp(addr_read, addr_be16, 6) == 0 && - ports_read == ports) { - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_ADDR_1, - addr_read, 3); - wpa_driver_roboswitch_write(drv, ROBO_ARLCTRL_PAGE, - ROBO_ARLCTRL_VEC_1, - &ports_read, 1); - } else return -1; - } - return 0; -} - - -static void * wpa_driver_roboswitch_init(void *ctx, const char *ifname) -{ - struct wpa_driver_roboswitch_data *drv; - char *sep; - u16 vlan = 0, _read[2]; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) return NULL; - drv->ctx = ctx; - drv->own_addr[0] = '\0'; - - /* copy ifname and take a pointer to the second to last character */ - sep = drv->ifname + - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)) - 2; - /* find the '.' seperating <interface> and <vlan> */ - while (sep > drv->ifname && *sep != '.') sep--; - if (sep <= drv->ifname) { - wpa_printf(MSG_INFO, "%s: No <interface>.<vlan> pair in " - "interface name %s", __func__, drv->ifname); - os_free(drv); - return NULL; - } - *sep = '\0'; - while (*++sep) { - if (*sep < '0' || *sep > '9') { - wpa_printf(MSG_INFO, "%s: Invalid vlan specification " - "in interface name %s", __func__, ifname); - os_free(drv); - return NULL; - } - vlan *= 10; - vlan += *sep - '0'; - if (vlan > ROBO_VLAN_MAX) { - wpa_printf(MSG_INFO, "%s: VLAN out of range in " - "interface name %s", __func__, ifname); - os_free(drv); - return NULL; - } - } - - drv->fd = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->fd < 0) { - wpa_printf(MSG_INFO, "%s: Unable to create socket", __func__); - os_free(drv); - return NULL; - } - - os_memset(&drv->ifr, 0, sizeof(drv->ifr)); - os_strlcpy(drv->ifr.ifr_name, drv->ifname, IFNAMSIZ); - if (ioctl(drv->fd, SIOCGMIIPHY, &drv->ifr) < 0) { - perror("ioctl[SIOCGMIIPHY]"); - os_free(drv); - return NULL; - } - if (if_mii(&drv->ifr)->phy_id != ROBO_PHY_ADDR) { - wpa_printf(MSG_INFO, "%s: Invalid phy address (not a " - "RoboSwitch?)", __func__); - os_free(drv); - return NULL; - } - - /* set and read back to see if the register can be used */ - _read[0] = ROBO_VLAN_MAX; - wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, - _read, 1); - wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, - _read + 1, 1); - drv->is_5350 = _read[0] == _read[1]; - - /* set the read bit */ - vlan |= 1 << 13; - wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, - drv->is_5350 ? ROBO_VLAN_ACCESS_5350 - : ROBO_VLAN_ACCESS, - &vlan, 1); - wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ, _read, - drv->is_5350 ? 2 : 1); - if (!(drv->is_5350 ? _read[1] & (1 << 4) : _read[0] & (1 << 14))) { - wpa_printf(MSG_INFO, "%s: Could not get port information for " - "VLAN %d", __func__, vlan & ~(1 << 13)); - os_free(drv); - return NULL; - } - drv->ports = _read[0] & 0x001F; - /* add the MII port */ - drv->ports |= 1 << 8; - if (wpa_driver_roboswitch_join(drv, drv->ports, pae_group_addr) < 0) { - wpa_printf(MSG_INFO, "%s: Unable to join PAE group", __func__); - os_free(drv); - return NULL; - } else { - wpa_printf(MSG_DEBUG, "%s: Added PAE group address to " - "RoboSwitch ARL", __func__); - } - - return drv; -} - - -static void wpa_driver_roboswitch_deinit(void *priv) -{ - struct wpa_driver_roboswitch_data *drv = priv; - - if (drv->l2) { - l2_packet_deinit(drv->l2); - drv->l2 = NULL; - } - if (wpa_driver_roboswitch_leave(drv, drv->ports, pae_group_addr) < 0) { - wpa_printf(MSG_DEBUG, "%s: Unable to leave PAE group", - __func__); - } - - close(drv->fd); - os_free(drv); -} - - -const struct wpa_driver_ops wpa_driver_roboswitch_ops = { - .name = "roboswitch", - .desc = "wpa_supplicant roboswitch driver", - .get_ssid = wpa_driver_roboswitch_get_ssid, - .get_bssid = wpa_driver_roboswitch_get_bssid, - .init = wpa_driver_roboswitch_init, - .deinit = wpa_driver_roboswitch_deinit, - .set_param = wpa_driver_roboswitch_set_param, - .get_ifname = wpa_driver_roboswitch_get_ifname, -}; diff --git a/contrib/wpa/src/drivers/driver_test.c b/contrib/wpa/src/drivers/driver_test.c deleted file mode 100644 index 2a41cf2..0000000 --- a/contrib/wpa/src/drivers/driver_test.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * WPA Supplicant - testing driver interface - * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -/* Make dure we get winsock2.h for Windows build to get sockaddr_storage */ -#include "build_config.h" -#ifdef CONFIG_NATIVE_WINDOWS -#include <winsock2.h> -#endif /* CONFIG_NATIVE_WINDOWS */ - -#include "includes.h" - -#ifndef CONFIG_NATIVE_WINDOWS -#include <sys/un.h> -#include <dirent.h> -#include <sys/stat.h> -#define DRIVER_TEST_UNIX -#endif /* CONFIG_NATIVE_WINDOWS */ - -#include "common.h" -#include "driver.h" -#include "l2_packet/l2_packet.h" -#include "eloop.h" -#include "sha1.h" -#include "ieee802_11_defs.h" - - -struct wpa_driver_test_global { - int dummy; -}; - -struct wpa_driver_test_data { - struct wpa_driver_test_global *global; - void *ctx; - u8 own_addr[ETH_ALEN]; - int test_socket; -#ifdef DRIVER_TEST_UNIX - struct sockaddr_un hostapd_addr; -#endif /* DRIVER_TEST_UNIX */ - int hostapd_addr_set; - struct sockaddr_in hostapd_addr_udp; - int hostapd_addr_udp_set; - char *own_socket_path; - char *test_dir; - u8 bssid[ETH_ALEN]; - u8 ssid[32]; - size_t ssid_len; -#define MAX_SCAN_RESULTS 30 - struct wpa_scan_res *scanres[MAX_SCAN_RESULTS]; - size_t num_scanres; - int use_associnfo; - u8 assoc_wpa_ie[80]; - size_t assoc_wpa_ie_len; - int use_mlme; - int associated; - u8 *probe_req_ie; - size_t probe_req_ie_len; -}; - - -static void wpa_driver_test_poll(void *eloop_ctx, void *timeout_ctx) -{ - struct wpa_driver_test_data *drv = eloop_ctx; - -#ifdef DRIVER_TEST_UNIX - if (drv->associated && drv->hostapd_addr_set) { - struct stat st; - if (stat(drv->hostapd_addr.sun_path, &st) < 0) { - wpa_printf(MSG_DEBUG, "%s: lost connection to AP: %s", - __func__, strerror(errno)); - drv->associated = 0; - wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); - } - } -#endif /* DRIVER_TEST_UNIX */ - - eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL); -} - - -static int wpa_driver_test_set_wpa(void *priv, int enabled) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return 0; -} - - -static void wpa_driver_test_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - - -#ifdef DRIVER_TEST_UNIX -static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv, - const char *path) -{ - struct dirent *dent; - DIR *dir; - struct sockaddr_un addr; - char cmd[512], *pos, *end; - int ret; - - dir = opendir(path); - if (dir == NULL) - return; - - end = cmd + sizeof(cmd); - pos = cmd; - ret = os_snprintf(pos, end - pos, "SCAN " MACSTR, - MAC2STR(drv->own_addr)); - if (ret >= 0 && ret < end - pos) - pos += ret; - if (drv->probe_req_ie) { - ret = os_snprintf(pos, end - pos, " "); - if (ret >= 0 && ret < end - pos) - pos += ret; - pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie, - drv->probe_req_ie_len); - } - end[-1] = '\0'; - - while ((dent = readdir(dir))) { - if (os_strncmp(dent->d_name, "AP-", 3) != 0) - continue; - wpa_printf(MSG_DEBUG, "%s: SCAN %s", __func__, dent->d_name); - - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", - path, dent->d_name); - - if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0, - (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("sendto(test_socket)"); - } - } - closedir(dir); -} -#endif /* DRIVER_TEST_UNIX */ - - -static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_test_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv); - - drv->num_scanres = 0; - -#ifdef DRIVER_TEST_UNIX - if (drv->test_socket >= 0 && drv->test_dir) - wpa_driver_scan_dir(drv, drv->test_dir); - - if (drv->test_socket >= 0 && drv->hostapd_addr_set && - sendto(drv->test_socket, "SCAN", 4, 0, - (struct sockaddr *) &drv->hostapd_addr, - sizeof(drv->hostapd_addr)) < 0) { - perror("sendto(test_socket)"); - } -#endif /* DRIVER_TEST_UNIX */ - - if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set && - sendto(drv->test_socket, "SCAN", 4, 0, - (struct sockaddr *) &drv->hostapd_addr_udp, - sizeof(drv->hostapd_addr_udp)) < 0) { - perror("sendto(test_socket)"); - } - - eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); - eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv, - drv->ctx); - return 0; -} - - -static struct wpa_scan_results * wpa_driver_test_get_scan_results2(void *priv) -{ - struct wpa_driver_test_data *drv = priv; - struct wpa_scan_results *res; - size_t i; - - res = os_zalloc(sizeof(*res)); - if (res == NULL) - return NULL; - - res->res = os_zalloc(drv->num_scanres * sizeof(struct wpa_scan_res *)); - if (res->res == NULL) { - os_free(res); - return NULL; - } - - for (i = 0; i < drv->num_scanres; i++) { - struct wpa_scan_res *r; - if (drv->scanres[i] == NULL) - continue; - r = os_malloc(sizeof(*r) + drv->scanres[i]->ie_len); - if (r == NULL) - break; - os_memcpy(r, drv->scanres[i], - sizeof(*r) + drv->scanres[i]->ie_len); - res->res[res->num++] = r; - } - - return res; -} - - -static int wpa_driver_test_set_key(void *priv, wpa_alg alg, const u8 *addr, - int key_idx, int set_tx, - const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d", - __func__, priv, alg, key_idx, set_tx); - if (addr) { - wpa_printf(MSG_DEBUG, " addr=" MACSTR, MAC2STR(addr)); - } - if (seq) { - wpa_hexdump(MSG_DEBUG, " seq", seq, seq_len); - } - if (key) { - wpa_hexdump(MSG_DEBUG, " key", key, key_len); - } - return 0; -} - - -static int wpa_driver_test_associate( - void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_test_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d " - "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d", - __func__, priv, params->freq, params->pairwise_suite, - params->group_suite, params->key_mgmt_suite, - params->auth_alg, params->mode); - if (params->bssid) { - wpa_printf(MSG_DEBUG, " bssid=" MACSTR, - MAC2STR(params->bssid)); - } - if (params->ssid) { - wpa_hexdump_ascii(MSG_DEBUG, " ssid", - params->ssid, params->ssid_len); - } - if (params->wpa_ie) { - wpa_hexdump(MSG_DEBUG, " wpa_ie", - params->wpa_ie, params->wpa_ie_len); - drv->assoc_wpa_ie_len = params->wpa_ie_len; - if (drv->assoc_wpa_ie_len > sizeof(drv->assoc_wpa_ie)) - drv->assoc_wpa_ie_len = sizeof(drv->assoc_wpa_ie); - os_memcpy(drv->assoc_wpa_ie, params->wpa_ie, - drv->assoc_wpa_ie_len); - } else - drv->assoc_wpa_ie_len = 0; - -#ifdef DRIVER_TEST_UNIX - if (drv->test_dir && params->bssid) { - os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); - drv->hostapd_addr.sun_family = AF_UNIX; - os_snprintf(drv->hostapd_addr.sun_path, - sizeof(drv->hostapd_addr.sun_path), - "%s/AP-" MACSTR, - drv->test_dir, MAC2STR(params->bssid)); - drv->hostapd_addr_set = 1; - } -#endif /* DRIVER_TEST_UNIX */ - - if (drv->test_socket >= 0 && - (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) { - char cmd[200], *pos, *end; - int ret; - end = cmd + sizeof(cmd); - pos = cmd; - ret = os_snprintf(pos, end - pos, "ASSOC " MACSTR " ", - MAC2STR(drv->own_addr)); - if (ret >= 0 && ret < end - pos) - pos += ret; - pos += wpa_snprintf_hex(pos, end - pos, params->ssid, - params->ssid_len); - ret = os_snprintf(pos, end - pos, " "); - if (ret >= 0 && ret < end - pos) - pos += ret; - pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie, - params->wpa_ie_len); - end[-1] = '\0'; -#ifdef DRIVER_TEST_UNIX - if (drv->hostapd_addr_set && - sendto(drv->test_socket, cmd, os_strlen(cmd), 0, - (struct sockaddr *) &drv->hostapd_addr, - sizeof(drv->hostapd_addr)) < 0) { - perror("sendto(test_socket)"); - return -1; - } -#endif /* DRIVER_TEST_UNIX */ - if (drv->hostapd_addr_udp_set && - sendto(drv->test_socket, cmd, os_strlen(cmd), 0, - (struct sockaddr *) &drv->hostapd_addr_udp, - sizeof(drv->hostapd_addr_udp)) < 0) { - perror("sendto(test_socket)"); - return -1; - } - - os_memcpy(drv->ssid, params->ssid, params->ssid_len); - drv->ssid_len = params->ssid_len; - } else { - drv->associated = 1; - wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); - } - - return 0; -} - - -static int wpa_driver_test_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_test_data *drv = priv; - os_memcpy(bssid, drv->bssid, ETH_ALEN); - return 0; -} - - -static int wpa_driver_test_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_test_data *drv = priv; - os_memcpy(ssid, drv->ssid, 32); - return drv->ssid_len; -} - - -static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv) -{ -#ifdef DRIVER_TEST_UNIX - if (drv->test_socket >= 0 && - sendto(drv->test_socket, "DISASSOC", 8, 0, - (struct sockaddr *) &drv->hostapd_addr, - sizeof(drv->hostapd_addr)) < 0) { - perror("sendto(test_socket)"); - return -1; - } -#endif /* DRIVER_TEST_UNIX */ - if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set && - sendto(drv->test_socket, "DISASSOC", 8, 0, - (struct sockaddr *) &drv->hostapd_addr_udp, - sizeof(drv->hostapd_addr_udp)) < 0) { - perror("sendto(test_socket)"); - return -1; - } - return 0; -} - - -static int wpa_driver_test_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_test_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", - __func__, MAC2STR(addr), reason_code); - os_memset(drv->bssid, 0, ETH_ALEN); - drv->associated = 0; - wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); - return wpa_driver_test_send_disassoc(drv); -} - - -static int wpa_driver_test_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_test_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d", - __func__, MAC2STR(addr), reason_code); - os_memset(drv->bssid, 0, ETH_ALEN); - drv->associated = 0; - wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); - return wpa_driver_test_send_disassoc(drv); -} - - -static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv, - struct sockaddr *from, - socklen_t fromlen, - const char *data) -{ - struct wpa_scan_res *res; - const char *pos, *pos2; - size_t len; - u8 *ie_pos, *ie_start, *ie_end; -#define MAX_IE_LEN 1000 - - wpa_printf(MSG_DEBUG, "test_driver: SCANRESP %s", data); - if (drv->num_scanres >= MAX_SCAN_RESULTS) { - wpa_printf(MSG_DEBUG, "test_driver: No room for the new scan " - "result"); - return; - } - - /* SCANRESP BSSID SSID IEs */ - - res = os_zalloc(sizeof(*res) + MAX_IE_LEN); - if (res == NULL) - return; - ie_start = ie_pos = (u8 *) (res + 1); - ie_end = ie_pos + MAX_IE_LEN; - - if (hwaddr_aton(data, res->bssid)) { - wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in scanres"); - os_free(res); - return; - } - - pos = data + 17; - while (*pos == ' ') - pos++; - pos2 = os_strchr(pos, ' '); - if (pos2 == NULL) { - wpa_printf(MSG_DEBUG, "test_driver: invalid SSID termination " - "in scanres"); - os_free(res); - return; - } - len = (pos2 - pos) / 2; - if (len > 32) - len = 32; - /* - * Generate SSID IE from the SSID field since this IE is not included - * in the main IE field. - */ - *ie_pos++ = WLAN_EID_SSID; - *ie_pos++ = len; - if (hexstr2bin(pos, ie_pos, len) < 0) { - wpa_printf(MSG_DEBUG, "test_driver: invalid SSID in scanres"); - os_free(res); - return; - } - ie_pos += len; - - pos = pos2 + 1; - pos2 = os_strchr(pos, ' '); - if (pos2 == NULL) - len = os_strlen(pos) / 2; - else - len = (pos2 - pos) / 2; - if ((int) len > ie_end - ie_pos) - len = ie_end - ie_pos; - if (hexstr2bin(pos, ie_pos, len) < 0) { - wpa_printf(MSG_DEBUG, "test_driver: invalid IEs in scanres"); - os_free(res); - return; - } - ie_pos += len; - res->ie_len = ie_pos - ie_start; - - if (pos2) { - pos = pos2 + 1; - while (*pos == ' ') - pos++; - if (os_strncmp(pos, "PRIVACY", 7) == 0) - res->caps |= IEEE80211_CAP_PRIVACY; - } - - os_free(drv->scanres[drv->num_scanres]); - drv->scanres[drv->num_scanres++] = res; -} - - -static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv, - struct sockaddr *from, - socklen_t fromlen, - const char *data) -{ - /* ASSOCRESP BSSID <res> */ - if (hwaddr_aton(data, drv->bssid)) { - wpa_printf(MSG_DEBUG, "test_driver: invalid BSSID in " - "assocresp"); - } - if (drv->use_associnfo) { - union wpa_event_data event; - os_memset(&event, 0, sizeof(event)); - event.assoc_info.req_ies = drv->assoc_wpa_ie; - event.assoc_info.req_ies_len = drv->assoc_wpa_ie_len; - wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &event); - } - drv->associated = 1; - wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); -} - - -static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv, - struct sockaddr *from, - socklen_t fromlen) -{ - drv->associated = 0; - wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); -} - - -static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv, - struct sockaddr *from, - socklen_t fromlen, - const u8 *data, size_t data_len) -{ - const u8 *src = drv->bssid; - - if (data_len > 14) { - /* Skip Ethernet header */ - src = data + ETH_ALEN; - data += 14; - data_len -= 14; - } - wpa_supplicant_rx_eapol(drv->ctx, src, data, data_len); -} - - -static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv, - struct sockaddr *from, - socklen_t fromlen, - const u8 *data, size_t data_len) -{ -#ifdef CONFIG_CLIENT_MLME - struct ieee80211_rx_status rx_status; - os_memset(&rx_status, 0, sizeof(rx_status)); - wpa_supplicant_sta_rx(drv->ctx, data, data_len, &rx_status); -#endif /* CONFIG_CLIENT_MLME */ -} - - -static void wpa_driver_test_receive_unix(int sock, void *eloop_ctx, - void *sock_ctx) -{ - struct wpa_driver_test_data *drv = eloop_ctx; - char *buf; - int res; - struct sockaddr_storage from; - socklen_t fromlen = sizeof(from); - const size_t buflen = 2000; - - buf = os_malloc(buflen); - if (buf == NULL) - return; - res = recvfrom(sock, buf, buflen - 1, 0, - (struct sockaddr *) &from, &fromlen); - if (res < 0) { - perror("recvfrom(test_socket)"); - os_free(buf); - return; - } - buf[res] = '\0'; - - wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res); - - if (os_strncmp(buf, "SCANRESP ", 9) == 0) { - wpa_driver_test_scanresp(drv, (struct sockaddr *) &from, - fromlen, buf + 9); - } else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) { - wpa_driver_test_assocresp(drv, (struct sockaddr *) &from, - fromlen, buf + 10); - } else if (os_strcmp(buf, "DISASSOC") == 0) { - wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, - fromlen); - } else if (os_strcmp(buf, "DEAUTH") == 0) { - wpa_driver_test_disassoc(drv, (struct sockaddr *) &from, - fromlen); - } else if (os_strncmp(buf, "EAPOL ", 6) == 0) { - wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen, - (const u8 *) buf + 6, res - 6); - } else if (os_strncmp(buf, "MLME ", 5) == 0) { - wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen, - (const u8 *) buf + 5, res - 5); - } else { - wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command", - (u8 *) buf, res); - } - os_free(buf); -} - - -static void * wpa_driver_test_init2(void *ctx, const char *ifname, - void *global_priv) -{ - struct wpa_driver_test_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->global = global_priv; - drv->ctx = ctx; - drv->test_socket = -1; - - /* Set dummy BSSID and SSID for testing. */ - drv->bssid[0] = 0x02; - drv->bssid[1] = 0x00; - drv->bssid[2] = 0x00; - drv->bssid[3] = 0x00; - drv->bssid[4] = 0x00; - drv->bssid[5] = 0x01; - os_memcpy(drv->ssid, "test", 5); - drv->ssid_len = 4; - - /* Generate a MAC address to help testing with multiple STAs */ - drv->own_addr[0] = 0x02; /* locally administered */ - sha1_prf((const u8 *) ifname, os_strlen(ifname), - "wpa_supplicant test mac addr generation", - NULL, 0, drv->own_addr + 1, ETH_ALEN - 1); - eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL); - - return drv; -} - - -static void wpa_driver_test_close_test_socket(struct wpa_driver_test_data *drv) -{ - if (drv->test_socket >= 0) { - eloop_unregister_read_sock(drv->test_socket); - close(drv->test_socket); - drv->test_socket = -1; - } - - if (drv->own_socket_path) { - unlink(drv->own_socket_path); - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - } -} - - -static void wpa_driver_test_deinit(void *priv) -{ - struct wpa_driver_test_data *drv = priv; - int i; - wpa_driver_test_close_test_socket(drv); - eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx); - eloop_cancel_timeout(wpa_driver_test_poll, drv, NULL); - os_free(drv->test_dir); - for (i = 0; i < MAX_SCAN_RESULTS; i++) - os_free(drv->scanres[i]); - os_free(drv->probe_req_ie); - os_free(drv); -} - - -static int wpa_driver_test_attach(struct wpa_driver_test_data *drv, - const char *dir) -{ -#ifdef DRIVER_TEST_UNIX - static unsigned int counter = 0; - struct sockaddr_un addr; - size_t len; - - os_free(drv->own_socket_path); - if (dir) { - len = os_strlen(dir) + 30; - drv->own_socket_path = os_malloc(len); - if (drv->own_socket_path == NULL) - return -1; - os_snprintf(drv->own_socket_path, len, "%s/STA-" MACSTR, - dir, MAC2STR(drv->own_addr)); - } else { - drv->own_socket_path = os_malloc(100); - if (drv->own_socket_path == NULL) - return -1; - os_snprintf(drv->own_socket_path, 100, - "/tmp/wpa_supplicant_test-%d-%d", - getpid(), counter++); - } - - drv->test_socket = socket(PF_UNIX, SOCK_DGRAM, 0); - if (drv->test_socket < 0) { - perror("socket(PF_UNIX)"); - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - return -1; - } - - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); - if (bind(drv->test_socket, (struct sockaddr *) &addr, - sizeof(addr)) < 0) { - perror("bind(PF_UNIX)"); - close(drv->test_socket); - unlink(drv->own_socket_path); - os_free(drv->own_socket_path); - drv->own_socket_path = NULL; - return -1; - } - - eloop_register_read_sock(drv->test_socket, - wpa_driver_test_receive_unix, drv, NULL); - - return 0; -#else /* DRIVER_TEST_UNIX */ - return -1; -#endif /* DRIVER_TEST_UNIX */ -} - - -static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv, - char *dst) -{ - char *pos; - - pos = os_strchr(dst, ':'); - if (pos == NULL) - return -1; - *pos++ = '\0'; - wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos); - - drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->test_socket < 0) { - perror("socket(PF_INET)"); - return -1; - } - - os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp)); - drv->hostapd_addr_udp.sin_family = AF_INET; -#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA) - { - int a[4]; - u8 *pos; - sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]); - pos = (u8 *) &drv->hostapd_addr_udp.sin_addr; - *pos++ = a[0]; - *pos++ = a[1]; - *pos++ = a[2]; - *pos++ = a[3]; - } -#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ - inet_aton(dst, &drv->hostapd_addr_udp.sin_addr); -#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */ - drv->hostapd_addr_udp.sin_port = htons(atoi(pos)); - - drv->hostapd_addr_udp_set = 1; - - eloop_register_read_sock(drv->test_socket, - wpa_driver_test_receive_unix, drv, NULL); - - return 0; -} - - -static int wpa_driver_test_set_param(void *priv, const char *param) -{ - struct wpa_driver_test_data *drv = priv; - const char *pos; - - wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); - if (param == NULL) - return 0; - - wpa_driver_test_close_test_socket(drv); - -#ifdef DRIVER_TEST_UNIX - pos = os_strstr(param, "test_socket="); - if (pos) { - const char *pos2; - size_t len; - - pos += 12; - pos2 = os_strchr(pos, ' '); - if (pos2) - len = pos2 - pos; - else - len = os_strlen(pos); - if (len > sizeof(drv->hostapd_addr.sun_path)) - return -1; - os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr)); - drv->hostapd_addr.sun_family = AF_UNIX; - os_memcpy(drv->hostapd_addr.sun_path, pos, len); - drv->hostapd_addr_set = 1; - } -#endif /* DRIVER_TEST_UNIX */ - - pos = os_strstr(param, "test_dir="); - if (pos) { - char *end; - os_free(drv->test_dir); - drv->test_dir = os_strdup(pos + 9); - if (drv->test_dir == NULL) - return -1; - end = os_strchr(drv->test_dir, ' '); - if (end) - *end = '\0'; - if (wpa_driver_test_attach(drv, drv->test_dir)) - return -1; - } else { - pos = os_strstr(param, "test_udp="); - if (pos) { - char *dst, *epos; - dst = os_strdup(pos + 9); - if (dst == NULL) - return -1; - epos = os_strchr(dst, ' '); - if (epos) - *epos = '\0'; - if (wpa_driver_test_attach_udp(drv, dst)) - return -1; - os_free(dst); - } else if (wpa_driver_test_attach(drv, NULL)) - return -1; - } - - if (os_strstr(param, "use_associnfo=1")) { - wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events"); - drv->use_associnfo = 1; - } - -#ifdef CONFIG_CLIENT_MLME - if (os_strstr(param, "use_mlme=1")) { - wpa_printf(MSG_DEBUG, "test_driver: Use internal MLME"); - drv->use_mlme = 1; - } -#endif /* CONFIG_CLIENT_MLME */ - - return 0; -} - - -static const u8 * wpa_driver_test_get_mac_addr(void *priv) -{ - struct wpa_driver_test_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __func__); - return drv->own_addr; -} - - -static int wpa_driver_test_send_eapol(void *priv, const u8 *dest, u16 proto, - const u8 *data, size_t data_len) -{ - struct wpa_driver_test_data *drv = priv; - char *msg; - size_t msg_len; - struct l2_ethhdr eth; - struct sockaddr *addr; - socklen_t alen; -#ifdef DRIVER_TEST_UNIX - struct sockaddr_un addr_un; -#endif /* DRIVER_TEST_UNIX */ - - wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len); - - os_memset(ð, 0, sizeof(eth)); - os_memcpy(eth.h_dest, dest, ETH_ALEN); - os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN); - eth.h_proto = host_to_be16(proto); - - msg_len = 6 + sizeof(eth) + data_len; - msg = os_malloc(msg_len); - if (msg == NULL) - return -1; - os_memcpy(msg, "EAPOL ", 6); - os_memcpy(msg + 6, ð, sizeof(eth)); - os_memcpy(msg + 6 + sizeof(eth), data, data_len); - - if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 || - drv->test_dir == NULL) { - if (drv->hostapd_addr_udp_set) { - addr = (struct sockaddr *) &drv->hostapd_addr_udp; - alen = sizeof(drv->hostapd_addr_udp); - } else { -#ifdef DRIVER_TEST_UNIX - addr = (struct sockaddr *) &drv->hostapd_addr; - alen = sizeof(drv->hostapd_addr); -#else /* DRIVER_TEST_UNIX */ - os_free(msg); - return -1; -#endif /* DRIVER_TEST_UNIX */ - } - } else { -#ifdef DRIVER_TEST_UNIX - struct stat st; - os_memset(&addr_un, 0, sizeof(addr_un)); - addr_un.sun_family = AF_UNIX; - os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), - "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest)); - if (stat(addr_un.sun_path, &st) < 0) { - os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path), - "%s/AP-" MACSTR, - drv->test_dir, MAC2STR(dest)); - } - addr = (struct sockaddr *) &addr_un; - alen = sizeof(addr_un); -#else /* DRIVER_TEST_UNIX */ - os_free(msg); - return -1; -#endif /* DRIVER_TEST_UNIX */ - } - - if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) { - perror("sendmsg(test_socket)"); - os_free(msg); - return -1; - } - - os_free(msg); - return 0; -} - - -static int wpa_driver_test_get_capa(void *priv, struct wpa_driver_capa *capa) -{ - struct wpa_driver_test_data *drv = priv; - os_memset(capa, 0, sizeof(*capa)); - capa->key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE | - WPA_DRIVER_CAPA_KEY_MGMT_FT | - WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK; - capa->enc = WPA_DRIVER_CAPA_ENC_WEP40 | - WPA_DRIVER_CAPA_ENC_WEP104 | - WPA_DRIVER_CAPA_ENC_TKIP | - WPA_DRIVER_CAPA_ENC_CCMP; - capa->auth = WPA_DRIVER_AUTH_OPEN | - WPA_DRIVER_AUTH_SHARED | - WPA_DRIVER_AUTH_LEAP; - if (drv->use_mlme) - capa->flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; - - return 0; -} - - -static int wpa_driver_test_mlme_setprotection(void *priv, const u8 *addr, - int protect_type, - int key_type) -{ - wpa_printf(MSG_DEBUG, "%s: protect_type=%d key_type=%d", - __func__, protect_type, key_type); - - if (addr) { - wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, - __func__, MAC2STR(addr)); - } - - return 0; -} - - -#ifdef CONFIG_CLIENT_MLME -static struct wpa_hw_modes * -wpa_driver_test_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) -{ - struct wpa_hw_modes *modes; - - *num_modes = 1; - *flags = 0; - modes = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes)); - if (modes == NULL) - return NULL; - modes[0].mode = WPA_MODE_IEEE80211G; - modes[0].num_channels = 1; - modes[0].num_rates = 1; - modes[0].channels = os_zalloc(sizeof(struct wpa_channel_data)); - modes[0].rates = os_zalloc(sizeof(struct wpa_rate_data)); - if (modes[0].channels == NULL || modes[0].rates == NULL) { - wpa_supplicant_sta_free_hw_features(modes, *num_modes); - return NULL; - } - modes[0].channels[0].chan = 1; - modes[0].channels[0].freq = 2412; - modes[0].channels[0].flag = WPA_CHAN_W_SCAN | WPA_CHAN_W_ACTIVE_SCAN; - modes[0].rates[0].rate = 10; - modes[0].rates[0].flags = WPA_RATE_BASIC | WPA_RATE_SUPPORTED | - WPA_RATE_CCK | WPA_RATE_MANDATORY; - - return modes; -} - - -static int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode, - int chan, int freq) -{ - wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d", - __func__, phymode, chan, freq); - return 0; -} - - -static int wpa_driver_test_send_mlme(void *priv, const u8 *data, - size_t data_len) -{ - struct wpa_driver_test_data *drv = priv; - struct msghdr msg; - struct iovec io[2]; - struct sockaddr_un addr; - const u8 *dest; - struct dirent *dent; - DIR *dir; - - wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len); - if (data_len < 10) - return -1; - dest = data + 4; - - io[0].iov_base = "MLME "; - io[0].iov_len = 5; - io[1].iov_base = (u8 *) data; - io[1].iov_len = data_len; - - os_memset(&msg, 0, sizeof(msg)); - msg.msg_iov = io; - msg.msg_iovlen = 2; - if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 || - drv->test_dir == NULL) { - if (drv->hostapd_addr_udp_set) { - msg.msg_name = &drv->hostapd_addr_udp; - msg.msg_namelen = sizeof(drv->hostapd_addr_udp); - } else { -#ifdef DRIVER_TEST_UNIX - msg.msg_name = &drv->hostapd_addr; - msg.msg_namelen = sizeof(drv->hostapd_addr); -#endif /* DRIVER_TEST_UNIX */ - } - } else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) - { - dir = opendir(drv->test_dir); - if (dir == NULL) - return -1; - while ((dent = readdir(dir))) { -#ifdef _DIRENT_HAVE_D_TYPE - /* Skip the file if it is not a socket. - * Also accept DT_UNKNOWN (0) in case - * the C library or underlying file - * system does not support d_type. */ - if (dent->d_type != DT_SOCK && - dent->d_type != DT_UNKNOWN) - continue; -#endif /* _DIRENT_HAVE_D_TYPE */ - if (os_strcmp(dent->d_name, ".") == 0 || - os_strcmp(dent->d_name, "..") == 0) - continue; - wpa_printf(MSG_DEBUG, "%s: Send broadcast MLME to %s", - __func__, dent->d_name); - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_snprintf(addr.sun_path, sizeof(addr.sun_path), - "%s/%s", drv->test_dir, dent->d_name); - - msg.msg_name = &addr; - msg.msg_namelen = sizeof(addr); - - if (sendmsg(drv->test_socket, &msg, 0) < 0) - perror("sendmsg(test_socket)"); - } - closedir(dir); - return 0; - } else { - struct stat st; - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_snprintf(addr.sun_path, sizeof(addr.sun_path), - "%s/AP-" MACSTR, drv->test_dir, MAC2STR(dest)); - if (stat(addr.sun_path, &st) < 0) { - os_snprintf(addr.sun_path, sizeof(addr.sun_path), - "%s/STA-" MACSTR, - drv->test_dir, MAC2STR(dest)); - } - msg.msg_name = &addr; - msg.msg_namelen = sizeof(addr); - } - - if (sendmsg(drv->test_socket, &msg, 0) < 0) { - perror("sendmsg(test_socket)"); - return -1; - } - - return 0; -} - - -static int wpa_driver_test_mlme_add_sta(void *priv, const u8 *addr, - const u8 *supp_rates, - size_t supp_rates_len) -{ - wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr)); - return 0; -} - - -static int wpa_driver_test_mlme_remove_sta(void *priv, const u8 *addr) -{ - wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, MAC2STR(addr)); - return 0; -} - - -static int wpa_driver_test_set_ssid(void *priv, const u8 *ssid, - size_t ssid_len) -{ - wpa_printf(MSG_DEBUG, "%s", __func__); - return 0; -} - - -static int wpa_driver_test_set_bssid(void *priv, const u8 *bssid) -{ - wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid)); - return 0; -} -#endif /* CONFIG_CLIENT_MLME */ - - -static int wpa_driver_test_set_probe_req_ie(void *priv, const u8 *ies, - size_t ies_len) -{ - struct wpa_driver_test_data *drv = priv; - - os_free(drv->probe_req_ie); - if (ies) { - drv->probe_req_ie = os_malloc(ies_len); - if (drv->probe_req_ie == NULL) { - drv->probe_req_ie_len = 0; - return -1; - } - os_memcpy(drv->probe_req_ie, ies, ies_len); - drv->probe_req_ie_len = ies_len; - } else { - drv->probe_req_ie = NULL; - drv->probe_req_ie_len = 0; - } - return 0; -} - - -static void * wpa_driver_test_global_init(void) -{ - struct wpa_driver_test_global *global; - - global = os_zalloc(sizeof(*global)); - return global; -} - - -static void wpa_driver_test_global_deinit(void *priv) -{ - struct wpa_driver_test_global *global = priv; - os_free(global); -} - - -static struct wpa_interface_info * -wpa_driver_test_get_interfaces(void *global_priv) -{ - /* struct wpa_driver_test_global *global = priv; */ - struct wpa_interface_info *iface; - - iface = os_zalloc(sizeof(*iface)); - if (iface == NULL) - return iface; - iface->ifname = os_strdup("sta0"); - iface->desc = os_strdup("test interface 0"); - iface->drv_name = "test"; - iface->next = os_zalloc(sizeof(*iface)); - if (iface->next) { - iface->next->ifname = os_strdup("sta1"); - iface->next->desc = os_strdup("test interface 1"); - iface->next->drv_name = "test"; - } - - return iface; -} - - -const struct wpa_driver_ops wpa_driver_test_ops = { - "test", - "wpa_supplicant test driver", - wpa_driver_test_get_bssid, - wpa_driver_test_get_ssid, - wpa_driver_test_set_wpa, - wpa_driver_test_set_key, - NULL /* init */, - wpa_driver_test_deinit, - wpa_driver_test_set_param, - NULL /* set_countermeasures */, - NULL /* set_drop_unencrypted */, - wpa_driver_test_scan, - NULL /* get_scan_results */, - wpa_driver_test_deauthenticate, - wpa_driver_test_disassociate, - wpa_driver_test_associate, - NULL /* set_auth_alg */, - NULL /* add_pmkid */, - NULL /* remove_pmkid */, - NULL /* flush_pmkid */, - wpa_driver_test_get_capa, - NULL /* poll */, - NULL /* get_ifname */, - wpa_driver_test_get_mac_addr, - wpa_driver_test_send_eapol, - NULL /* set_operstate */, - wpa_driver_test_mlme_setprotection, -#ifdef CONFIG_CLIENT_MLME - wpa_driver_test_get_hw_feature_data, - wpa_driver_test_set_channel, - wpa_driver_test_set_ssid, - wpa_driver_test_set_bssid, - wpa_driver_test_send_mlme, - wpa_driver_test_mlme_add_sta, - wpa_driver_test_mlme_remove_sta, -#else /* CONFIG_CLIENT_MLME */ - NULL /* get_hw_feature_data */, - NULL /* set_channel */, - NULL /* set_ssid */, - NULL /* set_bssid */, - NULL /* send_mlme */, - NULL /* mlme_add_sta */, - NULL /* mlme_remove_sta */, -#endif /* CONFIG_CLIENT_MLME */ - NULL /* update_ft_ies */, - NULL /* send_ft_action */, - wpa_driver_test_get_scan_results2, - wpa_driver_test_set_probe_req_ie, - NULL /* set_mode */, - NULL /* set_country */, - wpa_driver_test_global_init, - wpa_driver_test_global_deinit, - wpa_driver_test_init2, - wpa_driver_test_get_interfaces -}; diff --git a/contrib/wpa/src/drivers/driver_wext.c b/contrib/wpa/src/drivers/driver_wext.c deleted file mode 100644 index e771d37..0000000 --- a/contrib/wpa/src/drivers/driver_wext.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* - * WPA Supplicant - driver interaction with generic Linux Wireless Extensions - * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * This file implements a driver interface for the Linux Wireless Extensions. - * When used with WE-18 or newer, this interface can be used as-is with number - * of drivers. In addition to this, some of the common functions in this file - * can be used by other driver interface implementations that use generic WE - * ioctls, but require private ioctls for some of the functionality. - */ - -#include "includes.h" -#include <sys/ioctl.h> -#include <net/if_arp.h> - -#include "wireless_copy.h" -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "priv_netlink.h" -#include "driver_wext.h" -#include "ieee802_11_defs.h" -#include "wpa_common.h" - - -static int wpa_driver_wext_flush_pmkid(void *priv); -static int wpa_driver_wext_get_range(void *priv); -static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv); -static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv); - - -static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv, - int linkmode, int operstate) -{ - struct { - struct nlmsghdr hdr; - struct ifinfomsg ifinfo; - char opts[16]; - } req; - struct rtattr *rta; - static int nl_seq; - ssize_t ret; - - os_memset(&req, 0, sizeof(req)); - - req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - req.hdr.nlmsg_type = RTM_SETLINK; - req.hdr.nlmsg_flags = NLM_F_REQUEST; - req.hdr.nlmsg_seq = ++nl_seq; - req.hdr.nlmsg_pid = 0; - - req.ifinfo.ifi_family = AF_UNSPEC; - req.ifinfo.ifi_type = 0; - req.ifinfo.ifi_index = drv->ifindex; - req.ifinfo.ifi_flags = 0; - req.ifinfo.ifi_change = 0; - - if (linkmode != -1) { - rta = aliasing_hide_typecast( - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)), - struct rtattr); - rta->rta_type = IFLA_LINKMODE; - rta->rta_len = RTA_LENGTH(sizeof(char)); - *((char *) RTA_DATA(rta)) = linkmode; - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_LENGTH(sizeof(char)); - } - if (operstate != -1) { - rta = (struct rtattr *) - ((char *) &req + NLMSG_ALIGN(req.hdr.nlmsg_len)); - rta->rta_type = IFLA_OPERSTATE; - rta->rta_len = RTA_LENGTH(sizeof(char)); - *((char *) RTA_DATA(rta)) = operstate; - req.hdr.nlmsg_len = NLMSG_ALIGN(req.hdr.nlmsg_len) + - RTA_LENGTH(sizeof(char)); - } - - wpa_printf(MSG_DEBUG, "WEXT: Operstate: linkmode=%d, operstate=%d", - linkmode, operstate); - - ret = send(drv->event_sock, &req, req.hdr.nlmsg_len, 0); - if (ret < 0) { - wpa_printf(MSG_DEBUG, "WEXT: Sending operstate IFLA failed: " - "%s (assume operstate is not supported)", - strerror(errno)); - } - - return ret < 0 ? -1 : 0; -} - - -int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv, - int idx, u32 value) -{ - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.param.flags = idx & IW_AUTH_INDEX; - iwr.u.param.value = value; - - if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) { - if (errno != EOPNOTSUPP) { - wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d " - "value 0x%x) failed: %s)", - idx, value, strerror(errno)); - } - ret = errno == EOPNOTSUPP ? -2 : -1; - } - - return ret; -} - - -/** - * wpa_driver_wext_get_bssid - Get BSSID, SIOCGIWAP - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @bssid: Buffer for BSSID - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) { - perror("ioctl[SIOCGIWAP]"); - ret = -1; - } - os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN); - - return ret; -} - - -/** - * wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @bssid: BSSID - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.ap_addr.sa_family = ARPHRD_ETHER; - if (bssid) - os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN); - else - os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN); - - if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) { - perror("ioctl[SIOCSIWAP]"); - ret = -1; - } - - return ret; -} - - -/** - * wpa_driver_wext_get_ssid - Get SSID, SIOCGIWESSID - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @ssid: Buffer for the SSID; must be at least 32 bytes long - * Returns: SSID length on success, -1 on failure - */ -int wpa_driver_wext_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.essid.pointer = (caddr_t) ssid; - iwr.u.essid.length = 32; - - if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { - perror("ioctl[SIOCGIWESSID]"); - ret = -1; - } else { - ret = iwr.u.essid.length; - if (ret > 32) - ret = 32; - /* Some drivers include nul termination in the SSID, so let's - * remove it here before further processing. WE-21 changes this - * to explicitly require the length _not_ to include nul - * termination. */ - if (ret > 0 && ssid[ret - 1] == '\0' && - drv->we_version_compiled < 21) - ret--; - } - - return ret; -} - - -/** - * wpa_driver_wext_set_ssid - Set SSID, SIOCSIWESSID - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @ssid: SSID - * @ssid_len: Length of SSID (0..32) - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - char buf[33]; - - if (ssid_len > 32) - return -1; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - /* flags: 1 = ESSID is active, 0 = not (promiscuous) */ - iwr.u.essid.flags = (ssid_len != 0); - os_memset(buf, 0, sizeof(buf)); - os_memcpy(buf, ssid, ssid_len); - iwr.u.essid.pointer = (caddr_t) buf; - if (drv->we_version_compiled < 21) { - /* For historic reasons, set SSID length to include one extra - * character, C string nul termination, even though SSID is - * really an octet string that should not be presented as a C - * string. Some Linux drivers decrement the length by one and - * can thus end up missing the last octet of the SSID if the - * length is not incremented here. WE-21 changes this to - * explicitly require the length _not_ to include nul - * termination. */ - if (ssid_len) - ssid_len++; - } - iwr.u.essid.length = ssid_len; - - if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { - perror("ioctl[SIOCSIWESSID]"); - ret = -1; - } - - return ret; -} - - -/** - * wpa_driver_wext_set_freq - Set frequency/channel, SIOCSIWFREQ - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @freq: Frequency in MHz - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_set_freq(void *priv, int freq) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.freq.m = freq * 100000; - iwr.u.freq.e = 1; - - if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) { - perror("ioctl[SIOCSIWFREQ]"); - ret = -1; - } - - return ret; -} - - -static void -wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) -{ - union wpa_event_data data; - - wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'", - custom); - - os_memset(&data, 0, sizeof(data)); - /* Host AP driver */ - if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { - data.michael_mic_failure.unicast = - os_strstr(custom, " unicast ") != NULL; - /* TODO: parse parameters(?) */ - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) { - char *spos; - int bytes; - - spos = custom + 17; - - bytes = strspn(spos, "0123456789abcdefABCDEF"); - if (!bytes || (bytes & 1)) - return; - bytes /= 2; - - data.assoc_info.req_ies = os_malloc(bytes); - if (data.assoc_info.req_ies == NULL) - return; - - data.assoc_info.req_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.req_ies, bytes); - - spos += bytes * 2; - - data.assoc_info.resp_ies = NULL; - data.assoc_info.resp_ies_len = 0; - - if (os_strncmp(spos, " RespIEs=", 9) == 0) { - spos += 9; - - bytes = strspn(spos, "0123456789abcdefABCDEF"); - if (!bytes || (bytes & 1)) - goto done; - bytes /= 2; - - data.assoc_info.resp_ies = os_malloc(bytes); - if (data.assoc_info.resp_ies == NULL) - goto done; - - data.assoc_info.resp_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.resp_ies, bytes); - } - - wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - - done: - os_free(data.assoc_info.resp_ies); - os_free(data.assoc_info.req_ies); -#ifdef CONFIG_PEERKEY - } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) { - if (hwaddr_aton(custom + 17, data.stkstart.peer)) { - wpa_printf(MSG_DEBUG, "WEXT: unrecognized " - "STKSTART.request '%s'", custom + 17); - return; - } - wpa_supplicant_event(ctx, EVENT_STKSTART, &data); -#endif /* CONFIG_PEERKEY */ - } -} - - -static int wpa_driver_wext_event_wireless_michaelmicfailure( - void *ctx, const char *ev, size_t len) -{ - const struct iw_michaelmicfailure *mic; - union wpa_event_data data; - - if (len < sizeof(*mic)) - return -1; - - mic = (const struct iw_michaelmicfailure *) ev; - - wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: " - "flags=0x%x src_addr=" MACSTR, mic->flags, - MAC2STR(mic->src_addr.sa_data)); - - os_memset(&data, 0, sizeof(data)); - data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP); - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); - - return 0; -} - - -static int wpa_driver_wext_event_wireless_pmkidcand( - struct wpa_driver_wext_data *drv, const char *ev, size_t len) -{ - const struct iw_pmkid_cand *cand; - union wpa_event_data data; - const u8 *addr; - - if (len < sizeof(*cand)) - return -1; - - cand = (const struct iw_pmkid_cand *) ev; - addr = (const u8 *) cand->bssid.sa_data; - - wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: " - "flags=0x%x index=%d bssid=" MACSTR, cand->flags, - cand->index, MAC2STR(addr)); - - os_memset(&data, 0, sizeof(data)); - os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN); - data.pmkid_candidate.index = cand->index; - data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH; - wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data); - - return 0; -} - - -static int wpa_driver_wext_event_wireless_assocreqie( - struct wpa_driver_wext_data *drv, const char *ev, int len) -{ - if (len < 0) - return -1; - - wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev, - len); - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = os_malloc(len); - if (drv->assoc_req_ies == NULL) { - drv->assoc_req_ies_len = 0; - return -1; - } - os_memcpy(drv->assoc_req_ies, ev, len); - drv->assoc_req_ies_len = len; - - return 0; -} - - -static int wpa_driver_wext_event_wireless_assocrespie( - struct wpa_driver_wext_data *drv, const char *ev, int len) -{ - if (len < 0) - return -1; - - wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev, - len); - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = os_malloc(len); - if (drv->assoc_resp_ies == NULL) { - drv->assoc_resp_ies_len = 0; - return -1; - } - os_memcpy(drv->assoc_resp_ies, ev, len); - drv->assoc_resp_ies_len = len; - - return 0; -} - - -static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv) -{ - union wpa_event_data data; - - if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL) - return; - - os_memset(&data, 0, sizeof(data)); - if (drv->assoc_req_ies) { - data.assoc_info.req_ies = drv->assoc_req_ies; - drv->assoc_req_ies = NULL; - data.assoc_info.req_ies_len = drv->assoc_req_ies_len; - } - if (drv->assoc_resp_ies) { - data.assoc_info.resp_ies = drv->assoc_resp_ies; - drv->assoc_resp_ies = NULL; - data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len; - } - - wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); - - os_free(data.assoc_info.req_ies); - os_free(data.assoc_info.resp_ies); -} - - -static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv, - void *ctx, char *data, int len) -{ - struct iw_event iwe_buf, *iwe = &iwe_buf; - char *pos, *end, *custom, *buf; - - pos = data; - end = data + len; - - while (pos + IW_EV_LCP_LEN <= end) { - /* Event data may be unaligned, so make a local, aligned copy - * before processing. */ - os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); - wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", - iwe->cmd, iwe->len); - if (iwe->len <= IW_EV_LCP_LEN) - return; - - custom = pos + IW_EV_POINT_LEN; - if (drv->we_version_compiled > 18 && - (iwe->cmd == IWEVMICHAELMICFAILURE || - iwe->cmd == IWEVCUSTOM || - iwe->cmd == IWEVASSOCREQIE || - iwe->cmd == IWEVASSOCRESPIE || - iwe->cmd == IWEVPMKIDCAND)) { - /* WE-19 removed the pointer from struct iw_point */ - char *dpos = (char *) &iwe_buf.u.data.length; - int dlen = dpos - (char *) &iwe_buf; - os_memcpy(dpos, pos + IW_EV_LCP_LEN, - sizeof(struct iw_event) - dlen); - } else { - os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); - custom += IW_EV_POINT_OFF; - } - - switch (iwe->cmd) { - case SIOCGIWAP: - wpa_printf(MSG_DEBUG, "Wireless event: new AP: " - MACSTR, - MAC2STR((u8 *) iwe->u.ap_addr.sa_data)); - if (is_zero_ether_addr( - (const u8 *) iwe->u.ap_addr.sa_data) || - os_memcmp(iwe->u.ap_addr.sa_data, - "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == - 0) { - os_free(drv->assoc_req_ies); - drv->assoc_req_ies = NULL; - os_free(drv->assoc_resp_ies); - drv->assoc_resp_ies = NULL; - wpa_supplicant_event(ctx, EVENT_DISASSOC, - NULL); - - } else { - wpa_driver_wext_event_assoc_ies(drv); - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - } - break; - case IWEVMICHAELMICFAILURE: - if (custom + iwe->u.data.length > end) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid " - "IWEVMICHAELMICFAILURE length"); - return; - } - wpa_driver_wext_event_wireless_michaelmicfailure( - ctx, custom, iwe->u.data.length); - break; - case IWEVCUSTOM: - if (custom + iwe->u.data.length > end) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid " - "IWEVCUSTOM length"); - return; - } - buf = os_malloc(iwe->u.data.length + 1); - if (buf == NULL) - return; - os_memcpy(buf, custom, iwe->u.data.length); - buf[iwe->u.data.length] = '\0'; - wpa_driver_wext_event_wireless_custom(ctx, buf); - os_free(buf); - break; - case SIOCGIWSCAN: - drv->scan_complete_events = 1; - eloop_cancel_timeout(wpa_driver_wext_scan_timeout, - drv, ctx); - wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); - break; - case IWEVASSOCREQIE: - if (custom + iwe->u.data.length > end) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid " - "IWEVASSOCREQIE length"); - return; - } - wpa_driver_wext_event_wireless_assocreqie( - drv, custom, iwe->u.data.length); - break; - case IWEVASSOCRESPIE: - if (custom + iwe->u.data.length > end) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid " - "IWEVASSOCRESPIE length"); - return; - } - wpa_driver_wext_event_wireless_assocrespie( - drv, custom, iwe->u.data.length); - break; - case IWEVPMKIDCAND: - if (custom + iwe->u.data.length > end) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid " - "IWEVPMKIDCAND length"); - return; - } - wpa_driver_wext_event_wireless_pmkidcand( - drv, custom, iwe->u.data.length); - break; - } - - pos += iwe->len; - } -} - - -static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv, - void *ctx, char *buf, size_t len, - int del) -{ - union wpa_event_data event; - - os_memset(&event, 0, sizeof(event)); - if (len > sizeof(event.interface_status.ifname)) - len = sizeof(event.interface_status.ifname) - 1; - os_memcpy(event.interface_status.ifname, buf, len); - event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED : - EVENT_INTERFACE_ADDED; - - wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s", - del ? "DEL" : "NEW", - event.interface_status.ifname, - del ? "removed" : "added"); - - if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) { - if (del) - drv->if_removed = 1; - else - drv->if_removed = 0; - } - - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); -} - - -static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv, - struct nlmsghdr *h) -{ - struct ifinfomsg *ifi; - int attrlen, nlmsg_len, rta_len; - struct rtattr *attr; - - ifi = NLMSG_DATA(h); - - nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - nlmsg_len; - if (attrlen < 0) - return 0; - - attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_IFNAME) { - if (os_strcmp(((char *) attr) + rta_len, drv->ifname) - == 0) - return 1; - else - break; - } - attr = RTA_NEXT(attr, attrlen); - } - - return 0; -} - - -static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv, - int ifindex, struct nlmsghdr *h) -{ - if (drv->ifindex == ifindex || drv->ifindex2 == ifindex) - return 1; - - if (drv->if_removed && wpa_driver_wext_own_ifname(drv, h)) { - drv->ifindex = if_nametoindex(drv->ifname); - wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed " - "interface"); - wpa_driver_wext_finish_drv_init(drv); - return 1; - } - - return 0; -} - - -static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv, - void *ctx, struct nlmsghdr *h, - size_t len) -{ - struct ifinfomsg *ifi; - int attrlen, nlmsg_len, rta_len; - struct rtattr * attr; - - if (len < sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); - - if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) { - wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d", - ifi->ifi_index); - return; - } - - wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x " - "(%s%s%s%s)", - drv->operstate, ifi->ifi_flags, - (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", - (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", - (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", - (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); - /* - * Some drivers send the association event before the operup event--in - * this case, lifting operstate in wpa_driver_wext_set_operstate() - * fails. This will hit us when wpa_supplicant does not need to do - * IEEE 802.1X authentication - */ - if (drv->operstate == 1 && - (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP && - !(ifi->ifi_flags & IFF_RUNNING)) - wpa_driver_wext_send_oper_ifla(drv, -1, IF_OPER_UP); - - nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - nlmsg_len; - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_WIRELESS) { - wpa_driver_wext_event_wireless( - drv, ctx, ((char *) attr) + rta_len, - attr->rta_len - rta_len); - } else if (attr->rta_type == IFLA_IFNAME) { - wpa_driver_wext_event_link(drv, ctx, - ((char *) attr) + rta_len, - attr->rta_len - rta_len, 0); - } - attr = RTA_NEXT(attr, attrlen); - } -} - - -static void wpa_driver_wext_event_rtm_dellink(struct wpa_driver_wext_data *drv, - void *ctx, struct nlmsghdr *h, - size_t len) -{ - struct ifinfomsg *ifi; - int attrlen, nlmsg_len, rta_len; - struct rtattr * attr; - - if (len < sizeof(*ifi)) - return; - - ifi = NLMSG_DATA(h); - - nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg)); - - attrlen = h->nlmsg_len - nlmsg_len; - if (attrlen < 0) - return; - - attr = (struct rtattr *) (((char *) ifi) + nlmsg_len); - - rta_len = RTA_ALIGN(sizeof(struct rtattr)); - while (RTA_OK(attr, attrlen)) { - if (attr->rta_type == IFLA_IFNAME) { - wpa_driver_wext_event_link(drv, ctx, - ((char *) attr) + rta_len, - attr->rta_len - rta_len, 1); - } - attr = RTA_NEXT(attr, attrlen); - } -} - - -static void wpa_driver_wext_event_receive(int sock, void *eloop_ctx, - void *sock_ctx) -{ - char buf[8192]; - int left; - struct sockaddr_nl from; - socklen_t fromlen; - struct nlmsghdr *h; - int max_events = 10; - -try_again: - fromlen = sizeof(from); - left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT, - (struct sockaddr *) &from, &fromlen); - if (left < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("recvfrom(netlink)"); - return; - } - - h = (struct nlmsghdr *) buf; - while (left >= (int) sizeof(*h)) { - int len, plen; - - len = h->nlmsg_len; - plen = len - sizeof(*h); - if (len > left || plen < 0) { - wpa_printf(MSG_DEBUG, "Malformed netlink message: " - "len=%d left=%d plen=%d", - len, left, plen); - break; - } - - switch (h->nlmsg_type) { - case RTM_NEWLINK: - wpa_driver_wext_event_rtm_newlink(eloop_ctx, sock_ctx, - h, plen); - break; - case RTM_DELLINK: - wpa_driver_wext_event_rtm_dellink(eloop_ctx, sock_ctx, - h, plen); - break; - } - - len = NLMSG_ALIGN(len); - left -= len; - h = (struct nlmsghdr *) ((char *) h + len); - } - - if (left > 0) { - wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink " - "message", left); - } - - if (--max_events > 0) { - /* - * Try to receive all events in one eloop call in order to - * limit race condition on cases where AssocInfo event, Assoc - * event, and EAPOL frames are received more or less at the - * same time. We want to process the event messages first - * before starting EAPOL processing. - */ - goto try_again; - } -} - - -static int wpa_driver_wext_get_ifflags_ifname(struct wpa_driver_wext_data *drv, - const char *ifname, int *flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { - perror("ioctl[SIOCGIFFLAGS]"); - return -1; - } - *flags = ifr.ifr_flags & 0xffff; - return 0; -} - - -/** - * wpa_driver_wext_get_ifflags - Get interface flags (SIOCGIFFLAGS) - * @drv: driver_wext private data - * @flags: Pointer to returned flags value - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags) -{ - return wpa_driver_wext_get_ifflags_ifname(drv, drv->ifname, flags); -} - - -static int wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data *drv, - const char *ifname, int flags) -{ - struct ifreq ifr; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_flags = flags & 0xffff; - if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { - perror("SIOCSIFFLAGS"); - return -1; - } - return 0; -} - - -/** - * wpa_driver_wext_set_ifflags - Set interface flags (SIOCSIFFLAGS) - * @drv: driver_wext private data - * @flags: New value for flags - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags) -{ - return wpa_driver_wext_set_ifflags_ifname(drv, drv->ifname, flags); -} - - -/** - * wpa_driver_wext_init - Initialize WE driver interface - * @ctx: context to be used when calling wpa_supplicant functions, - * e.g., wpa_supplicant_event() - * @ifname: interface name, e.g., wlan0 - * Returns: Pointer to private data, %NULL on failure - */ -void * wpa_driver_wext_init(void *ctx, const char *ifname) -{ - int s; - struct sockaddr_nl local; - struct wpa_driver_wext_data *drv; - - drv = os_zalloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - drv->ctx = ctx; - os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); - - drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->ioctl_sock < 0) { - perror("socket(PF_INET,SOCK_DGRAM)"); - os_free(drv); - return NULL; - } - - s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (s < 0) { - perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)"); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - os_memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = RTMGRP_LINK; - if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) { - perror("bind(netlink)"); - close(s); - close(drv->ioctl_sock); - os_free(drv); - return NULL; - } - - eloop_register_read_sock(s, wpa_driver_wext_event_receive, drv, ctx); - drv->event_sock = s; - - drv->mlme_sock = -1; - - wpa_driver_wext_finish_drv_init(drv); - - return drv; -} - - -static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) -{ - int flags; - - if (wpa_driver_wext_get_ifflags(drv, &flags) != 0) - printf("Could not get interface '%s' flags\n", drv->ifname); - else if (!(flags & IFF_UP)) { - if (wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) { - printf("Could not set interface '%s' UP\n", - drv->ifname); - } else { - /* - * Wait some time to allow driver to initialize before - * starting configuring the driver. This seems to be - * needed at least some drivers that load firmware etc. - * when the interface is set up. - */ - wpa_printf(MSG_DEBUG, "Interface %s set UP - waiting " - "a second for the driver to complete " - "initialization", drv->ifname); - sleep(1); - } - } - - /* - * Make sure that the driver does not have any obsolete PMKID entries. - */ - wpa_driver_wext_flush_pmkid(drv); - - if (wpa_driver_wext_set_mode(drv, 0) < 0) { - printf("Could not configure driver to use managed mode\n"); - } - - wpa_driver_wext_get_range(drv); - - /* - * Unlock the driver's BSSID and force to a random SSID to clear any - * previous association the driver might have when the supplicant - * starts up. - */ - wpa_driver_wext_disconnect(drv); - - drv->ifindex = if_nametoindex(drv->ifname); - - if (os_strncmp(drv->ifname, "wlan", 4) == 0) { - /* - * Host AP driver may use both wlan# and wifi# interface in - * wireless events. Since some of the versions included WE-18 - * support, let's add the alternative ifindex also from - * driver_wext.c for the time being. This may be removed at - * some point once it is believed that old versions of the - * driver are not in use anymore. - */ - char ifname2[IFNAMSIZ + 1]; - os_strlcpy(ifname2, drv->ifname, sizeof(ifname2)); - os_memcpy(ifname2, "wifi", 4); - wpa_driver_wext_alternative_ifindex(drv, ifname2); - } - - wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT); -} - - -/** - * wpa_driver_wext_deinit - Deinitialize WE driver interface - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * - * Shut down driver interface and processing of driver events. Free - * private data buffer if one was allocated in wpa_driver_wext_init(). - */ -void wpa_driver_wext_deinit(void *priv) -{ - struct wpa_driver_wext_data *drv = priv; - int flags; - - eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); - - /* - * Clear possibly configured driver parameters in order to make it - * easier to use the driver after wpa_supplicant has been terminated. - */ - wpa_driver_wext_disconnect(drv); - - wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP); - - eloop_unregister_read_sock(drv->event_sock); - if (drv->mlme_sock >= 0) - eloop_unregister_read_sock(drv->mlme_sock); - - if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) - (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP); - - close(drv->event_sock); - close(drv->ioctl_sock); - if (drv->mlme_sock >= 0) - close(drv->mlme_sock); - os_free(drv->assoc_req_ies); - os_free(drv->assoc_resp_ies); - os_free(drv); -} - - -/** - * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion - * @eloop_ctx: Unused - * @timeout_ctx: ctx argument given to wpa_driver_wext_init() - * - * This function can be used as registered timeout when starting a scan to - * generate a scan completed event if the driver does not report this. - */ -void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx) -{ - wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); - wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); -} - - -/** - * wpa_driver_wext_scan - Request the driver to initiate scan - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @ssid: Specific SSID to scan for (ProbeReq) or %NULL to scan for - * all SSIDs (either active scan with broadcast SSID or passive - * scan - * @ssid_len: Length of the SSID - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0, timeout; - struct iw_scan_req req; - - if (ssid_len > IW_ESSID_MAX_SIZE) { - wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)", - __FUNCTION__, (unsigned long) ssid_len); - return -1; - } - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - if (ssid && ssid_len) { - os_memset(&req, 0, sizeof(req)); - req.essid_len = ssid_len; - req.bssid.sa_family = ARPHRD_ETHER; - os_memset(req.bssid.sa_data, 0xff, ETH_ALEN); - os_memcpy(req.essid, ssid, ssid_len); - iwr.u.data.pointer = (caddr_t) &req; - iwr.u.data.length = sizeof(req); - iwr.u.data.flags = IW_SCAN_THIS_ESSID; - } - - if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) { - perror("ioctl[SIOCSIWSCAN]"); - ret = -1; - } - - /* Not all drivers generate "scan completed" wireless event, so try to - * read results after a timeout. */ - timeout = 5; - if (drv->scan_complete_events) { - /* - * The driver seems to deliver SIOCGIWSCAN events to notify - * when scan is complete, so use longer timeout to avoid race - * conditions with scanning and following association request. - */ - timeout = 30; - } - wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d " - "seconds", ret, timeout); - eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); - eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv, - drv->ctx); - - return ret; -} - - -static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv, - size_t *len) -{ - struct iwreq iwr; - u8 *res_buf; - size_t res_buf_len; - - res_buf_len = IW_SCAN_MAX_DATA; - for (;;) { - res_buf = os_malloc(res_buf_len); - if (res_buf == NULL) - return NULL; - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = res_buf; - iwr.u.data.length = res_buf_len; - - if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0) - break; - - if (errno == E2BIG && res_buf_len < 65535) { - os_free(res_buf); - res_buf = NULL; - res_buf_len *= 2; - if (res_buf_len > 65535) - res_buf_len = 65535; /* 16-bit length field */ - wpa_printf(MSG_DEBUG, "Scan results did not fit - " - "trying larger buffer (%lu bytes)", - (unsigned long) res_buf_len); - } else { - perror("ioctl[SIOCGIWSCAN]"); - os_free(res_buf); - return NULL; - } - } - - if (iwr.u.data.length > res_buf_len) { - os_free(res_buf); - return NULL; - } - *len = iwr.u.data.length; - - return res_buf; -} - - -/* - * Data structure for collecting WEXT scan results. This is needed to allow - * the various methods of reporting IEs to be combined into a single IE buffer. - */ -struct wext_scan_data { - struct wpa_scan_res res; - u8 *ie; - size_t ie_len; - u8 ssid[32]; - size_t ssid_len; - int maxrate; -}; - - -static void wext_get_scan_mode(struct iw_event *iwe, - struct wext_scan_data *res) -{ - if (iwe->u.mode == IW_MODE_ADHOC) - res->res.caps |= IEEE80211_CAP_IBSS; - else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA) - res->res.caps |= IEEE80211_CAP_ESS; -} - - -static void wext_get_scan_ssid(struct iw_event *iwe, - struct wext_scan_data *res, char *custom, - char *end) -{ - int ssid_len = iwe->u.essid.length; - if (custom + ssid_len > end) - return; - if (iwe->u.essid.flags && - ssid_len > 0 && - ssid_len <= IW_ESSID_MAX_SIZE) { - os_memcpy(res->ssid, custom, ssid_len); - res->ssid_len = ssid_len; - } -} - - -static void wext_get_scan_freq(struct iw_event *iwe, - struct wext_scan_data *res) -{ - int divi = 1000000, i; - - if (iwe->u.freq.e == 0) { - /* - * Some drivers do not report frequency, but a channel. - * Try to map this to frequency by assuming they are using - * IEEE 802.11b/g. But don't overwrite a previously parsed - * frequency if the driver sends both frequency and channel, - * since the driver may be sending an A-band channel that we - * don't handle here. - */ - - if (res->res.freq) - return; - - if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) { - res->res.freq = 2407 + 5 * iwe->u.freq.m; - return; - } else if (iwe->u.freq.m == 14) { - res->res.freq = 2484; - return; - } - } - - if (iwe->u.freq.e > 6) { - wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID=" - MACSTR " m=%d e=%d)", - MAC2STR(res->res.bssid), iwe->u.freq.m, - iwe->u.freq.e); - return; - } - - for (i = 0; i < iwe->u.freq.e; i++) - divi /= 10; - res->res.freq = iwe->u.freq.m / divi; -} - - -static void wext_get_scan_qual(struct iw_event *iwe, - struct wext_scan_data *res) -{ - res->res.qual = iwe->u.qual.qual; - res->res.noise = iwe->u.qual.noise; - res->res.level = iwe->u.qual.level; -} - - -static void wext_get_scan_encode(struct iw_event *iwe, - struct wext_scan_data *res) -{ - if (!(iwe->u.data.flags & IW_ENCODE_DISABLED)) - res->res.caps |= IEEE80211_CAP_PRIVACY; -} - - -static void wext_get_scan_rate(struct iw_event *iwe, - struct wext_scan_data *res, char *pos, - char *end) -{ - int maxrate; - char *custom = pos + IW_EV_LCP_LEN; - struct iw_param p; - size_t clen; - - clen = iwe->len; - if (custom + clen > end) - return; - maxrate = 0; - while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) { - /* Note: may be misaligned, make a local, aligned copy */ - os_memcpy(&p, custom, sizeof(struct iw_param)); - if (p.value > maxrate) - maxrate = p.value; - clen -= sizeof(struct iw_param); - custom += sizeof(struct iw_param); - } - - /* Convert the maxrate from WE-style (b/s units) to - * 802.11 rates (500000 b/s units). - */ - res->maxrate = maxrate / 500000; -} - - -static void wext_get_scan_iwevgenie(struct iw_event *iwe, - struct wext_scan_data *res, char *custom, - char *end) -{ - char *genie, *gpos, *gend; - u8 *tmp; - - if (iwe->u.data.length == 0) - return; - - gpos = genie = custom; - gend = genie + iwe->u.data.length; - if (gend > end) { - wpa_printf(MSG_INFO, "IWEVGENIE overflow"); - return; - } - - tmp = os_realloc(res->ie, res->ie_len + gend - gpos); - if (tmp == NULL) - return; - os_memcpy(tmp + res->ie_len, gpos, gend - gpos); - res->ie = tmp; - res->ie_len += gend - gpos; -} - - -static void wext_get_scan_custom(struct iw_event *iwe, - struct wext_scan_data *res, char *custom, - char *end) -{ - size_t clen; - u8 *tmp; - - clen = iwe->u.data.length; - if (custom + clen > end) - return; - - if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) { - char *spos; - int bytes; - spos = custom + 7; - bytes = custom + clen - spos; - if (bytes & 1 || bytes == 0) - return; - bytes /= 2; - tmp = os_realloc(res->ie, res->ie_len + bytes); - if (tmp == NULL) - return; - hexstr2bin(spos, tmp + res->ie_len, bytes); - res->ie = tmp; - res->ie_len += bytes; - } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) { - char *spos; - int bytes; - spos = custom + 7; - bytes = custom + clen - spos; - if (bytes & 1 || bytes == 0) - return; - bytes /= 2; - tmp = os_realloc(res->ie, res->ie_len + bytes); - if (tmp == NULL) - return; - hexstr2bin(spos, tmp + res->ie_len, bytes); - res->ie = tmp; - res->ie_len += bytes; - } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) { - char *spos; - int bytes; - u8 bin[8]; - spos = custom + 4; - bytes = custom + clen - spos; - if (bytes != 16) { - wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes); - return; - } - bytes /= 2; - hexstr2bin(spos, bin, bytes); - res->res.tsf += WPA_GET_BE64(bin); - } -} - - -static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd) -{ - return drv->we_version_compiled > 18 && - (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE || - cmd == IWEVGENIE || cmd == IWEVCUSTOM); -} - - -static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res, - struct wext_scan_data *data) -{ - struct wpa_scan_res **tmp; - struct wpa_scan_res *r; - size_t extra_len; - u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL; - - /* Figure out whether we need to fake any IEs */ - pos = data->ie; - end = pos + data->ie_len; - while (pos && pos + 1 < end) { - if (pos + 2 + pos[1] > end) - break; - if (pos[0] == WLAN_EID_SSID) - ssid_ie = pos; - else if (pos[0] == WLAN_EID_SUPP_RATES) - rate_ie = pos; - else if (pos[0] == WLAN_EID_EXT_SUPP_RATES) - rate_ie = pos; - pos += 2 + pos[1]; - } - - extra_len = 0; - if (ssid_ie == NULL) - extra_len += 2 + data->ssid_len; - if (rate_ie == NULL && data->maxrate) - extra_len += 3; - - r = os_zalloc(sizeof(*r) + extra_len + data->ie_len); - if (r == NULL) - return; - os_memcpy(r, &data->res, sizeof(*r)); - r->ie_len = extra_len + data->ie_len; - pos = (u8 *) (r + 1); - if (ssid_ie == NULL) { - /* - * Generate a fake SSID IE since the driver did not report - * a full IE list. - */ - *pos++ = WLAN_EID_SSID; - *pos++ = data->ssid_len; - os_memcpy(pos, data->ssid, data->ssid_len); - pos += data->ssid_len; - } - if (rate_ie == NULL && data->maxrate) { - /* - * Generate a fake Supported Rates IE since the driver did not - * report a full IE list. - */ - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = 1; - *pos++ = data->maxrate; - } - if (data->ie) - os_memcpy(pos, data->ie, data->ie_len); - - tmp = os_realloc(res->res, - (res->num + 1) * sizeof(struct wpa_scan_res *)); - if (tmp == NULL) { - os_free(r); - return; - } - tmp[res->num++] = r; - res->res = tmp; -} - - -/** - * wpa_driver_wext_get_scan_results - Fetch the latest scan results - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * Returns: Scan results on success, -1 on failure - */ -struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv) -{ - struct wpa_driver_wext_data *drv = priv; - size_t ap_num = 0, len; - int first; - u8 *res_buf; - struct iw_event iwe_buf, *iwe = &iwe_buf; - char *pos, *end, *custom; - struct wpa_scan_results *res; - struct wext_scan_data data; - - res_buf = wpa_driver_wext_giwscan(drv, &len); - if (res_buf == NULL) - return NULL; - - ap_num = 0; - first = 1; - - res = os_zalloc(sizeof(*res)); - if (res == NULL) { - os_free(res_buf); - return NULL; - } - - pos = (char *) res_buf; - end = (char *) res_buf + len; - os_memset(&data, 0, sizeof(data)); - - while (pos + IW_EV_LCP_LEN <= end) { - /* Event data may be unaligned, so make a local, aligned copy - * before processing. */ - os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); - if (iwe->len <= IW_EV_LCP_LEN) - break; - - custom = pos + IW_EV_POINT_LEN; - if (wext_19_iw_point(drv, iwe->cmd)) { - /* WE-19 removed the pointer from struct iw_point */ - char *dpos = (char *) &iwe_buf.u.data.length; - int dlen = dpos - (char *) &iwe_buf; - os_memcpy(dpos, pos + IW_EV_LCP_LEN, - sizeof(struct iw_event) - dlen); - } else { - os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); - custom += IW_EV_POINT_OFF; - } - - switch (iwe->cmd) { - case SIOCGIWAP: - if (!first) - wpa_driver_wext_add_scan_entry(res, &data); - first = 0; - os_free(data.ie); - os_memset(&data, 0, sizeof(data)); - os_memcpy(data.res.bssid, - iwe->u.ap_addr.sa_data, ETH_ALEN); - break; - case SIOCGIWMODE: - wext_get_scan_mode(iwe, &data); - break; - case SIOCGIWESSID: - wext_get_scan_ssid(iwe, &data, custom, end); - break; - case SIOCGIWFREQ: - wext_get_scan_freq(iwe, &data); - break; - case IWEVQUAL: - wext_get_scan_qual(iwe, &data); - break; - case SIOCGIWENCODE: - wext_get_scan_encode(iwe, &data); - break; - case SIOCGIWRATE: - wext_get_scan_rate(iwe, &data, pos, end); - break; - case IWEVGENIE: - wext_get_scan_iwevgenie(iwe, &data, custom, end); - break; - case IWEVCUSTOM: - wext_get_scan_custom(iwe, &data, custom, end); - break; - } - - pos += iwe->len; - } - os_free(res_buf); - res_buf = NULL; - if (!first) - wpa_driver_wext_add_scan_entry(res, &data); - os_free(data.ie); - - wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)", - (unsigned long) len, (unsigned long) res->num); - - return res; -} - - -static int wpa_driver_wext_get_range(void *priv) -{ - struct wpa_driver_wext_data *drv = priv; - struct iw_range *range; - struct iwreq iwr; - int minlen; - size_t buflen; - - /* - * Use larger buffer than struct iw_range in order to allow the - * structure to grow in the future. - */ - buflen = sizeof(struct iw_range) + 500; - range = os_zalloc(buflen); - if (range == NULL) - return -1; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) range; - iwr.u.data.length = buflen; - - minlen = ((char *) &range->enc_capa) - (char *) range + - sizeof(range->enc_capa); - - if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { - perror("ioctl[SIOCGIWRANGE]"); - os_free(range); - return -1; - } else if (iwr.u.data.length >= minlen && - range->we_version_compiled >= 18) { - wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " - "WE(source)=%d enc_capa=0x%x", - range->we_version_compiled, - range->we_version_source, - range->enc_capa); - drv->has_capability = 1; - drv->we_version_compiled = range->we_version_compiled; - if (range->enc_capa & IW_ENC_CAPA_WPA) { - drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA | - WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; - } - if (range->enc_capa & IW_ENC_CAPA_WPA2) { - drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | - WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; - } - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | - WPA_DRIVER_CAPA_ENC_WEP104; - if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; - if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) - drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; - if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) - drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; - drv->capa.auth = WPA_DRIVER_AUTH_OPEN | - WPA_DRIVER_AUTH_SHARED | - WPA_DRIVER_AUTH_LEAP; - - wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x " - "flags 0x%x", - drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags); - } else { - wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - " - "assuming WPA is not supported"); - } - - os_free(range); - return 0; -} - - -static int wpa_driver_wext_set_wpa(void *priv, int enabled) -{ - struct wpa_driver_wext_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - return wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, - enabled); -} - - -static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv, - const u8 *psk) -{ - struct iw_encode_ext *ext; - struct iwreq iwr; - int ret; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) - return 0; - - if (!psk) - return 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - - ext = os_zalloc(sizeof(*ext) + PMK_LEN); - if (ext == NULL) - return -1; - - iwr.u.encoding.pointer = (caddr_t) ext; - iwr.u.encoding.length = sizeof(*ext) + PMK_LEN; - ext->key_len = PMK_LEN; - os_memcpy(&ext->key, psk, ext->key_len); - ext->alg = IW_ENCODE_ALG_PMK; - - ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr); - if (ret < 0) - perror("ioctl[SIOCSIWENCODEEXT] PMK"); - os_free(ext); - - return ret; -} - - -static int wpa_driver_wext_set_key_ext(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, - size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - struct iw_encode_ext *ext; - - if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) { - wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu", - __FUNCTION__, (unsigned long) seq_len); - return -1; - } - - ext = os_zalloc(sizeof(*ext) + key_len); - if (ext == NULL) - return -1; - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = key_idx + 1; - iwr.u.encoding.flags |= IW_ENCODE_TEMP; - if (alg == WPA_ALG_NONE) - iwr.u.encoding.flags |= IW_ENCODE_DISABLED; - iwr.u.encoding.pointer = (caddr_t) ext; - iwr.u.encoding.length = sizeof(*ext) + key_len; - - if (addr == NULL || - os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) - ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY; - if (set_tx) - ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY; - - ext->addr.sa_family = ARPHRD_ETHER; - if (addr) - os_memcpy(ext->addr.sa_data, addr, ETH_ALEN); - else - os_memset(ext->addr.sa_data, 0xff, ETH_ALEN); - if (key && key_len) { - os_memcpy(ext + 1, key, key_len); - ext->key_len = key_len; - } - switch (alg) { - case WPA_ALG_NONE: - ext->alg = IW_ENCODE_ALG_NONE; - break; - case WPA_ALG_WEP: - ext->alg = IW_ENCODE_ALG_WEP; - break; - case WPA_ALG_TKIP: - ext->alg = IW_ENCODE_ALG_TKIP; - break; - case WPA_ALG_CCMP: - ext->alg = IW_ENCODE_ALG_CCMP; - break; - case WPA_ALG_PMK: - ext->alg = IW_ENCODE_ALG_PMK; - break; -#ifdef CONFIG_IEEE80211W - case WPA_ALG_IGTK: - ext->alg = IW_ENCODE_ALG_AES_CMAC; - break; -#endif /* CONFIG_IEEE80211W */ - default: - wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d", - __FUNCTION__, alg); - os_free(ext); - return -1; - } - - if (seq && seq_len) { - ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID; - os_memcpy(ext->rx_seq, seq, seq_len); - } - - if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) { - ret = errno == EOPNOTSUPP ? -2 : -1; - if (errno == ENODEV) { - /* - * ndiswrapper seems to be returning incorrect error - * code.. */ - ret = -2; - } - - perror("ioctl[SIOCSIWENCODEEXT]"); - } - - os_free(ext); - return ret; -} - - -/** - * wpa_driver_wext_set_key - Configure encryption key - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @priv: Private driver interface data - * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, - * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key. - * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for - * broadcast/default keys - * @key_idx: key index (0..3), usually 0 for unicast keys - * @set_tx: Configure this key as the default Tx key (only used when - * driver does not support separate unicast/individual key - * @seq: Sequence number/packet number, seq_len octets, the next - * packet number to be used for in replay protection; configured - * for Rx keys (in most cases, this is only used with broadcast - * keys and set to zero for unicast keys) - * @seq_len: Length of the seq, depends on the algorithm: - * TKIP: 6 octets, CCMP: 6 octets - * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, - * 8-byte Rx Mic Key - * @key_len: Length of the key buffer in octets (WEP: 5 or 13, - * TKIP: 32, CCMP: 16) - * Returns: 0 on success, -1 on failure - * - * This function uses SIOCSIWENCODEEXT by default, but tries to use - * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. - */ -int wpa_driver_wext_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " - "key_len=%lu", - __FUNCTION__, alg, key_idx, set_tx, - (unsigned long) seq_len, (unsigned long) key_len); - - ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx, - seq, seq_len, key, key_len); - if (ret == 0) - return 0; - - if (ret == -2 && - (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) { - wpa_printf(MSG_DEBUG, "Driver did not support " - "SIOCSIWENCODEEXT, trying SIOCSIWENCODE"); - ret = 0; - } else { - wpa_printf(MSG_DEBUG, "Driver did not support " - "SIOCSIWENCODEEXT"); - return ret; - } - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = key_idx + 1; - iwr.u.encoding.flags |= IW_ENCODE_TEMP; - if (alg == WPA_ALG_NONE) - iwr.u.encoding.flags |= IW_ENCODE_DISABLED; - iwr.u.encoding.pointer = (caddr_t) key; - iwr.u.encoding.length = key_len; - - if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { - perror("ioctl[SIOCSIWENCODE]"); - ret = -1; - } - - if (set_tx && alg != WPA_ALG_NONE) { - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.encoding.flags = key_idx + 1; - iwr.u.encoding.flags |= IW_ENCODE_TEMP; - iwr.u.encoding.pointer = (caddr_t) NULL; - iwr.u.encoding.length = 0; - if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { - perror("ioctl[SIOCSIWENCODE] (set_tx)"); - ret = -1; - } - } - - return ret; -} - - -static int wpa_driver_wext_set_countermeasures(void *priv, - int enabled) -{ - struct wpa_driver_wext_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - return wpa_driver_wext_set_auth_param(drv, - IW_AUTH_TKIP_COUNTERMEASURES, - enabled); -} - - -static int wpa_driver_wext_set_drop_unencrypted(void *priv, - int enabled) -{ - struct wpa_driver_wext_data *drv = priv; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - drv->use_crypt = enabled; - return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, - enabled); -} - - -static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv, - const u8 *addr, int cmd, int reason_code) -{ - struct iwreq iwr; - struct iw_mlme mlme; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - os_memset(&mlme, 0, sizeof(mlme)); - mlme.cmd = cmd; - mlme.reason_code = reason_code; - mlme.addr.sa_family = ARPHRD_ETHER; - os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN); - iwr.u.data.pointer = (caddr_t) &mlme; - iwr.u.data.length = sizeof(mlme); - - if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) { - perror("ioctl[SIOCSIWMLME]"); - ret = -1; - } - - return ret; -} - - -static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv) -{ - struct iwreq iwr; - const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; - u8 ssid[32]; - int i; - - /* - * Only force-disconnect when the card is in infrastructure mode, - * otherwise the driver might interpret the cleared BSSID and random - * SSID as an attempt to create a new ad-hoc network. - */ - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { - perror("ioctl[SIOCGIWMODE]"); - iwr.u.mode = IW_MODE_INFRA; - } - - if (iwr.u.mode == IW_MODE_INFRA) { - /* - * Clear the BSSID selection and set a random SSID to make sure - * the driver will not be trying to associate with something - * even if it does not understand SIOCSIWMLME commands (or - * tries to associate automatically after deauth/disassoc). - */ - wpa_driver_wext_set_bssid(drv, null_bssid); - - for (i = 0; i < 32; i++) - ssid[i] = rand() & 0xFF; - wpa_driver_wext_set_ssid(drv, ssid, 32); - } -} - - -static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_wext_data *drv = priv; - int ret; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code); - wpa_driver_wext_disconnect(drv); - return ret; -} - - -static int wpa_driver_wext_disassociate(void *priv, const u8 *addr, - int reason_code) -{ - struct wpa_driver_wext_data *drv = priv; - int ret; - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code); - wpa_driver_wext_disconnect(drv); - return ret; -} - - -static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie, - size_t ie_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) ie; - iwr.u.data.length = ie_len; - - if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) { - perror("ioctl[SIOCSIWGENIE]"); - ret = -1; - } - - return ret; -} - - -int wpa_driver_wext_cipher2wext(int cipher) -{ - switch (cipher) { - case CIPHER_NONE: - return IW_AUTH_CIPHER_NONE; - case CIPHER_WEP40: - return IW_AUTH_CIPHER_WEP40; - case CIPHER_TKIP: - return IW_AUTH_CIPHER_TKIP; - case CIPHER_CCMP: - return IW_AUTH_CIPHER_CCMP; - case CIPHER_WEP104: - return IW_AUTH_CIPHER_WEP104; - default: - return 0; - } -} - - -int wpa_driver_wext_keymgmt2wext(int keymgmt) -{ - switch (keymgmt) { - case KEY_MGMT_802_1X: - case KEY_MGMT_802_1X_NO_WPA: - return IW_AUTH_KEY_MGMT_802_1X; - case KEY_MGMT_PSK: - return IW_AUTH_KEY_MGMT_PSK; - default: - return 0; - } -} - - -static int -wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv, - struct wpa_driver_associate_params *params) -{ - struct iwreq iwr; - int ret = 0; - - wpa_printf(MSG_DEBUG, "WEXT: Driver did not support " - "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE"); - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - /* Just changing mode, not actual keys */ - iwr.u.encoding.flags = 0; - iwr.u.encoding.pointer = (caddr_t) NULL; - iwr.u.encoding.length = 0; - - /* - * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two - * different things. Here they are used to indicate Open System vs. - * Shared Key authentication algorithm. However, some drivers may use - * them to select between open/restricted WEP encrypted (open = allow - * both unencrypted and encrypted frames; restricted = only allow - * encrypted frames). - */ - - if (!drv->use_crypt) { - iwr.u.encoding.flags |= IW_ENCODE_DISABLED; - } else { - if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM) - iwr.u.encoding.flags |= IW_ENCODE_OPEN; - if (params->auth_alg & AUTH_ALG_SHARED_KEY) - iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; - } - - if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { - perror("ioctl[SIOCSIWENCODE]"); - ret = -1; - } - - return ret; -} - - -int wpa_driver_wext_associate(void *priv, - struct wpa_driver_associate_params *params) -{ - struct wpa_driver_wext_data *drv = priv; - int ret = 0; - int allow_unencrypted_eapol; - int value; - - wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); - - /* - * If the driver did not support SIOCSIWAUTH, fallback to - * SIOCSIWENCODE here. - */ - if (drv->auth_alg_fallback && - wpa_driver_wext_auth_alg_fallback(drv, params) < 0) - ret = -1; - - if (!params->bssid && - wpa_driver_wext_set_bssid(drv, NULL) < 0) - ret = -1; - - /* TODO: should consider getting wpa version and cipher/key_mgmt suites - * from configuration, not from here, where only the selected suite is - * available */ - if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len) - < 0) - ret = -1; - if (params->wpa_ie == NULL || params->wpa_ie_len == 0) - value = IW_AUTH_WPA_VERSION_DISABLED; - else if (params->wpa_ie[0] == WLAN_EID_RSN) - value = IW_AUTH_WPA_VERSION_WPA2; - else - value = IW_AUTH_WPA_VERSION_WPA; - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_WPA_VERSION, value) < 0) - ret = -1; - value = wpa_driver_wext_cipher2wext(params->pairwise_suite); - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_CIPHER_PAIRWISE, value) < 0) - ret = -1; - value = wpa_driver_wext_cipher2wext(params->group_suite); - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_CIPHER_GROUP, value) < 0) - ret = -1; - value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite); - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_KEY_MGMT, value) < 0) - ret = -1; - value = params->key_mgmt_suite != KEY_MGMT_NONE || - params->pairwise_suite != CIPHER_NONE || - params->group_suite != CIPHER_NONE || - params->wpa_ie_len; - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_PRIVACY_INVOKED, value) < 0) - ret = -1; - - /* Allow unencrypted EAPOL messages even if pairwise keys are set when - * not using WPA. IEEE 802.1X specifies that these frames are not - * encrypted, but WPA encrypts them when pairwise keys are in use. */ - if (params->key_mgmt_suite == KEY_MGMT_802_1X || - params->key_mgmt_suite == KEY_MGMT_PSK) - allow_unencrypted_eapol = 0; - else - allow_unencrypted_eapol = 1; - - if (wpa_driver_wext_set_psk(drv, params->psk) < 0) - ret = -1; - if (wpa_driver_wext_set_auth_param(drv, - IW_AUTH_RX_UNENCRYPTED_EAPOL, - allow_unencrypted_eapol) < 0) - ret = -1; -#ifdef CONFIG_IEEE80211W - switch (params->mgmt_frame_protection) { - case NO_MGMT_FRAME_PROTECTION: - value = IW_AUTH_MFP_DISABLED; - break; - case MGMT_FRAME_PROTECTION_OPTIONAL: - value = IW_AUTH_MFP_OPTIONAL; - break; - case MGMT_FRAME_PROTECTION_REQUIRED: - value = IW_AUTH_MFP_REQUIRED; - break; - }; - if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0) - ret = -1; -#endif /* CONFIG_IEEE80211W */ - if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0) - ret = -1; - if (wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) - ret = -1; - if (params->bssid && - wpa_driver_wext_set_bssid(drv, params->bssid) < 0) - ret = -1; - - return ret; -} - - -static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_wext_data *drv = priv; - int algs = 0, res; - - if (auth_alg & AUTH_ALG_OPEN_SYSTEM) - algs |= IW_AUTH_ALG_OPEN_SYSTEM; - if (auth_alg & AUTH_ALG_SHARED_KEY) - algs |= IW_AUTH_ALG_SHARED_KEY; - if (auth_alg & AUTH_ALG_LEAP) - algs |= IW_AUTH_ALG_LEAP; - if (algs == 0) { - /* at least one algorithm should be set */ - algs = IW_AUTH_ALG_OPEN_SYSTEM; - } - - res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, - algs); - drv->auth_alg_fallback = res == -2; - return res; -} - - -/** - * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE - * @priv: Pointer to private wext data from wpa_driver_wext_init() - * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS - * Returns: 0 on success, -1 on failure - */ -int wpa_driver_wext_set_mode(void *priv, int mode) -{ - struct wpa_driver_wext_data *drv = priv; - struct iwreq iwr; - int ret = -1, flags; - unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.mode = new_mode; - if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) { - ret = 0; - goto done; - } - - if (errno != EBUSY) { - perror("ioctl[SIOCSIWMODE]"); - goto done; - } - - /* mac80211 doesn't allow mode changes while the device is up, so if - * the device isn't in the mode we're about to change to, take device - * down, try to set the mode again, and bring it back up. - */ - if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { - perror("ioctl[SIOCGIWMODE]"); - goto done; - } - - if (iwr.u.mode == new_mode) { - ret = 0; - goto done; - } - - if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) { - (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP); - - /* Try to set the mode again while the interface is down */ - iwr.u.mode = new_mode; - if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) - perror("ioctl[SIOCSIWMODE]"); - else - ret = 0; - - /* Ignore return value of get_ifflags to ensure that the device - * is always up like it was before this function was called. - */ - (void) wpa_driver_wext_get_ifflags(drv, &flags); - (void) wpa_driver_wext_set_ifflags(drv, flags | IFF_UP); - } - -done: - return ret; -} - - -static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv, - u32 cmd, const u8 *bssid, const u8 *pmkid) -{ - struct iwreq iwr; - struct iw_pmksa pmksa; - int ret = 0; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - os_memset(&pmksa, 0, sizeof(pmksa)); - pmksa.cmd = cmd; - pmksa.bssid.sa_family = ARPHRD_ETHER; - if (bssid) - os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); - if (pmkid) - os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); - iwr.u.data.pointer = (caddr_t) &pmksa; - iwr.u.data.length = sizeof(pmksa); - - if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { - if (errno != EOPNOTSUPP) - perror("ioctl[SIOCSIWPMKSA]"); - ret = -1; - } - - return ret; -} - - -static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_wext_data *drv = priv; - return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid); -} - - -static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid, - const u8 *pmkid) -{ - struct wpa_driver_wext_data *drv = priv; - return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid); -} - - -static int wpa_driver_wext_flush_pmkid(void *priv) -{ - struct wpa_driver_wext_data *drv = priv; - return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL); -} - - -int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa) -{ - struct wpa_driver_wext_data *drv = priv; - if (!drv->has_capability) - return -1; - os_memcpy(capa, &drv->capa, sizeof(*capa)); - return 0; -} - - -int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, - const char *ifname) -{ - if (ifname == NULL) { - drv->ifindex2 = -1; - return 0; - } - - drv->ifindex2 = if_nametoindex(ifname); - if (drv->ifindex2 <= 0) - return -1; - - wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for " - "wireless events", drv->ifindex2, ifname); - - return 0; -} - - -int wpa_driver_wext_set_operstate(void *priv, int state) -{ - struct wpa_driver_wext_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)", - __func__, drv->operstate, state, state ? "UP" : "DORMANT"); - drv->operstate = state; - return wpa_driver_wext_send_oper_ifla( - drv, -1, state ? IF_OPER_UP : IF_OPER_DORMANT); -} - - -int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv) -{ - return drv->we_version_compiled; -} - - -const struct wpa_driver_ops wpa_driver_wext_ops = { - .name = "wext", - .desc = "Linux wireless extensions (generic)", - .get_bssid = wpa_driver_wext_get_bssid, - .get_ssid = wpa_driver_wext_get_ssid, - .set_wpa = wpa_driver_wext_set_wpa, - .set_key = wpa_driver_wext_set_key, - .set_countermeasures = wpa_driver_wext_set_countermeasures, - .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted, - .scan = wpa_driver_wext_scan, - .get_scan_results2 = wpa_driver_wext_get_scan_results, - .deauthenticate = wpa_driver_wext_deauthenticate, - .disassociate = wpa_driver_wext_disassociate, - .set_mode = wpa_driver_wext_set_mode, - .associate = wpa_driver_wext_associate, - .set_auth_alg = wpa_driver_wext_set_auth_alg, - .init = wpa_driver_wext_init, - .deinit = wpa_driver_wext_deinit, - .add_pmkid = wpa_driver_wext_add_pmkid, - .remove_pmkid = wpa_driver_wext_remove_pmkid, - .flush_pmkid = wpa_driver_wext_flush_pmkid, - .get_capa = wpa_driver_wext_get_capa, - .set_operstate = wpa_driver_wext_set_operstate, -}; diff --git a/contrib/wpa/src/drivers/driver_wext.h b/contrib/wpa/src/drivers/driver_wext.h deleted file mode 100644 index b89c2cb..0000000 --- a/contrib/wpa/src/drivers/driver_wext.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * WPA Supplicant - driver_wext exported functions - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#ifndef DRIVER_WEXT_H -#define DRIVER_WEXT_H - -#include <net/if.h> - -struct wpa_driver_wext_data { - void *ctx; - int event_sock; - int ioctl_sock; - int mlme_sock; - char ifname[IFNAMSIZ + 1]; - int ifindex; - int ifindex2; - int if_removed; - u8 *assoc_req_ies; - size_t assoc_req_ies_len; - u8 *assoc_resp_ies; - size_t assoc_resp_ies_len; - struct wpa_driver_capa capa; - int has_capability; - int we_version_compiled; - - /* for set_auth_alg fallback */ - int use_crypt; - int auth_alg_fallback; - - int operstate; - - char mlmedev[IFNAMSIZ + 1]; - - int scan_complete_events; -}; - -int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags); -int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags); -int wpa_driver_wext_get_bssid(void *priv, u8 *bssid); -int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid); -int wpa_driver_wext_get_ssid(void *priv, u8 *ssid); -int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len); -int wpa_driver_wext_set_freq(void *priv, int freq); -int wpa_driver_wext_set_mode(void *priv, int mode); -int wpa_driver_wext_set_key(void *priv, wpa_alg alg, - const u8 *addr, int key_idx, - int set_tx, const u8 *seq, size_t seq_len, - const u8 *key, size_t key_len); -int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len); -struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv); - -void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx); - -int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, - const char *ifname); - -void * wpa_driver_wext_init(void *ctx, const char *ifname); -void wpa_driver_wext_deinit(void *priv); - -int wpa_driver_wext_set_operstate(void *priv, int state); -int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv); - -int wpa_driver_wext_associate(void *priv, - struct wpa_driver_associate_params *params); -int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa); -int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv, - int idx, u32 value); -int wpa_driver_wext_cipher2wext(int cipher); -int wpa_driver_wext_keymgmt2wext(int keymgmt); - -#endif /* DRIVER_WEXT_H */ diff --git a/contrib/wpa/src/drivers/priv_netlink.h b/contrib/wpa/src/drivers/priv_netlink.h deleted file mode 100644 index 2a31e25..0000000 --- a/contrib/wpa/src/drivers/priv_netlink.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * wpa_supplicant - Private copy of Linux netlink/rtnetlink definitions. - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#ifndef PRIV_NETLINK_H -#define PRIV_NETLINK_H - -/* - * This should be replaced with user space header once one is available with C - * library, etc.. - */ - -#ifndef IFF_LOWER_UP -#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */ -#endif -#ifndef IFF_DORMANT -#define IFF_DORMANT 0x20000 /* driver signals dormant */ -#endif - -#ifndef IFLA_IFNAME -#define IFLA_IFNAME 3 -#endif -#ifndef IFLA_WIRELESS -#define IFLA_WIRELESS 11 -#endif -#ifndef IFLA_OPERSTATE -#define IFLA_OPERSTATE 16 -#endif -#ifndef IFLA_LINKMODE -#define IFLA_LINKMODE 17 -#define IF_OPER_DORMANT 5 -#define IF_OPER_UP 6 -#endif - -#define NLM_F_REQUEST 1 - -#define NETLINK_ROUTE 0 -#define RTMGRP_LINK 1 -#define RTM_BASE 0x10 -#define RTM_NEWLINK (RTM_BASE + 0) -#define RTM_DELLINK (RTM_BASE + 1) -#define RTM_SETLINK (RTM_BASE + 3) - -#define NLMSG_ALIGNTO 4 -#define NLMSG_ALIGN(len) (((len) + NLMSG_ALIGNTO - 1) & ~(NLMSG_ALIGNTO - 1)) -#define NLMSG_LENGTH(len) ((len) + NLMSG_ALIGN(sizeof(struct nlmsghdr))) -#define NLMSG_DATA(nlh) ((void*) (((char*) nlh) + NLMSG_LENGTH(0))) - -#define RTA_ALIGNTO 4 -#define RTA_ALIGN(len) (((len) + RTA_ALIGNTO - 1) & ~(RTA_ALIGNTO - 1)) -#define RTA_OK(rta,len) \ -((len) > 0 && (rta)->rta_len >= sizeof(struct rtattr) && \ -(rta)->rta_len <= (len)) -#define RTA_NEXT(rta,attrlen) \ -((attrlen) -= RTA_ALIGN((rta)->rta_len), \ -(struct rtattr *) (((char *)(rta)) + RTA_ALIGN((rta)->rta_len))) -#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) -#define RTA_DATA(rta) ((void *) (((char *) (rta)) + RTA_LENGTH(0))) - - -struct sockaddr_nl -{ - sa_family_t nl_family; - unsigned short nl_pad; - u32 nl_pid; - u32 nl_groups; -}; - -struct nlmsghdr -{ - u32 nlmsg_len; - u16 nlmsg_type; - u16 nlmsg_flags; - u32 nlmsg_seq; - u32 nlmsg_pid; -}; - -struct ifinfomsg -{ - unsigned char ifi_family; - unsigned char __ifi_pad; - unsigned short ifi_type; - int ifi_index; - unsigned ifi_flags; - unsigned ifi_change; -}; - -struct rtattr -{ - unsigned short rta_len; - unsigned short rta_type; -}; - -#endif /* PRIV_NETLINK_H */ diff --git a/contrib/wpa/src/l2_packet/l2_packet_linux.c b/contrib/wpa/src/l2_packet/l2_packet_linux.c deleted file mode 100644 index 48d1bde..0000000 --- a/contrib/wpa/src/l2_packet/l2_packet_linux.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * WPA Supplicant - Layer2 packet handling with Linux packet sockets - * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/ioctl.h> -#include <netpacket/packet.h> -#include <net/if.h> - -#include "common.h" -#include "eloop.h" -#include "l2_packet.h" - - -struct l2_packet_data { - int fd; /* packet socket for EAPOL frames */ - char ifname[IFNAMSIZ + 1]; - int ifindex; - u8 own_addr[ETH_ALEN]; - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len); - void *rx_callback_ctx; - int l2_hdr; /* whether to include layer 2 (Ethernet) header data - * buffers */ -}; - - -int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) -{ - os_memcpy(addr, l2->own_addr, ETH_ALEN); - return 0; -} - - -int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, - const u8 *buf, size_t len) -{ - int ret; - if (l2 == NULL) - return -1; - if (l2->l2_hdr) { - ret = send(l2->fd, buf, len, 0); - if (ret < 0) - perror("l2_packet_send - send"); - } else { - struct sockaddr_ll ll; - os_memset(&ll, 0, sizeof(ll)); - ll.sll_family = AF_PACKET; - ll.sll_ifindex = l2->ifindex; - ll.sll_protocol = htons(proto); - ll.sll_halen = ETH_ALEN; - os_memcpy(ll.sll_addr, dst_addr, ETH_ALEN); - ret = sendto(l2->fd, buf, len, 0, (struct sockaddr *) &ll, - sizeof(ll)); - if (ret < 0) - perror("l2_packet_send - sendto"); - } - return ret; -} - - -static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct l2_packet_data *l2 = eloop_ctx; - u8 buf[2300]; - int res; - struct sockaddr_ll ll; - socklen_t fromlen; - - os_memset(&ll, 0, sizeof(ll)); - fromlen = sizeof(ll); - res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &ll, - &fromlen); - if (res < 0) { - perror("l2_packet_receive - recvfrom"); - return; - } - - l2->rx_callback(l2->rx_callback_ctx, ll.sll_addr, buf, res); -} - - -struct l2_packet_data * l2_packet_init( - const char *ifname, const u8 *own_addr, unsigned short protocol, - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len), - void *rx_callback_ctx, int l2_hdr) -{ - struct l2_packet_data *l2; - struct ifreq ifr; - struct sockaddr_ll ll; - - l2 = os_zalloc(sizeof(struct l2_packet_data)); - if (l2 == NULL) - return NULL; - os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); - l2->rx_callback = rx_callback; - l2->rx_callback_ctx = rx_callback_ctx; - l2->l2_hdr = l2_hdr; - - l2->fd = socket(PF_PACKET, l2_hdr ? SOCK_RAW : SOCK_DGRAM, - htons(protocol)); - if (l2->fd < 0) { - perror("socket(PF_PACKET)"); - os_free(l2); - return NULL; - } - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name)); - if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) { - perror("ioctl[SIOCGIFINDEX]"); - close(l2->fd); - os_free(l2); - return NULL; - } - l2->ifindex = ifr.ifr_ifindex; - - os_memset(&ll, 0, sizeof(ll)); - ll.sll_family = PF_PACKET; - ll.sll_ifindex = ifr.ifr_ifindex; - ll.sll_protocol = htons(protocol); - if (bind(l2->fd, (struct sockaddr *) &ll, sizeof(ll)) < 0) { - perror("bind[PF_PACKET]"); - close(l2->fd); - os_free(l2); - return NULL; - } - - if (ioctl(l2->fd, SIOCGIFHWADDR, &ifr) < 0) { - perror("ioctl[SIOCGIFHWADDR]"); - close(l2->fd); - os_free(l2); - return NULL; - } - os_memcpy(l2->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); - - eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); - - return l2; -} - - -void l2_packet_deinit(struct l2_packet_data *l2) -{ - if (l2 == NULL) - return; - - if (l2->fd >= 0) { - eloop_unregister_read_sock(l2->fd); - close(l2->fd); - } - - os_free(l2); -} - - -int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) -{ - int s; - struct ifreq ifr; - struct sockaddr_in *saddr; - size_t res; - - s = socket(PF_INET, SOCK_DGRAM, 0); - if (s < 0) { - perror("socket"); - return -1; - } - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { - if (errno != EADDRNOTAVAIL) - perror("ioctl[SIOCGIFADDR]"); - close(s); - return -1; - } - close(s); - saddr = aliasing_hide_typecast(&ifr.ifr_addr, struct sockaddr_in); - if (saddr->sin_family != AF_INET) - return -1; - res = os_strlcpy(buf, inet_ntoa(saddr->sin_addr), len); - if (res >= len) - return -1; - return 0; -} - - -void l2_packet_notify_auth_start(struct l2_packet_data *l2) -{ -} diff --git a/contrib/wpa/src/l2_packet/l2_packet_pcap.c b/contrib/wpa/src/l2_packet/l2_packet_pcap.c deleted file mode 100644 index 8156e29..0000000 --- a/contrib/wpa/src/l2_packet/l2_packet_pcap.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * WPA Supplicant - Layer2 packet handling with libpcap/libdnet and WinPcap - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#ifndef CONFIG_NATIVE_WINDOWS -#include <sys/ioctl.h> -#endif /* CONFIG_NATIVE_WINDOWS */ -#include <pcap.h> -#ifndef CONFIG_WINPCAP -#include <dnet.h> -#endif /* CONFIG_WINPCAP */ - -#include "common.h" -#include "eloop.h" -#include "l2_packet.h" - - -static const u8 pae_group_addr[ETH_ALEN] = -{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; - -struct l2_packet_data { - pcap_t *pcap; -#ifdef CONFIG_WINPCAP - unsigned int num_fast_poll; -#else /* CONFIG_WINPCAP */ - eth_t *eth; -#endif /* CONFIG_WINPCAP */ - char ifname[100]; - u8 own_addr[ETH_ALEN]; - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len); - void *rx_callback_ctx; - int l2_hdr; /* whether to include layer 2 (Ethernet) header in calls - * to rx_callback */ -}; - - -int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) -{ - os_memcpy(addr, l2->own_addr, ETH_ALEN); - return 0; -} - - -#ifndef CONFIG_WINPCAP -static int l2_packet_init_libdnet(struct l2_packet_data *l2) -{ - eth_addr_t own_addr; - - l2->eth = eth_open(l2->ifname); - if (!l2->eth) { - printf("Failed to open interface '%s'.\n", l2->ifname); - perror("eth_open"); - return -1; - } - - if (eth_get(l2->eth, &own_addr) < 0) { - printf("Failed to get own hw address from interface '%s'.\n", - l2->ifname); - perror("eth_get"); - eth_close(l2->eth); - l2->eth = NULL; - return -1; - } - os_memcpy(l2->own_addr, own_addr.data, ETH_ALEN); - - return 0; -} -#endif /* CONFIG_WINPCAP */ - - -int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, - const u8 *buf, size_t len) -{ - int ret; - struct l2_ethhdr *eth; - - if (l2 == NULL) - return -1; - - if (l2->l2_hdr) { -#ifdef CONFIG_WINPCAP - ret = pcap_sendpacket(l2->pcap, buf, len); -#else /* CONFIG_WINPCAP */ - ret = eth_send(l2->eth, buf, len); -#endif /* CONFIG_WINPCAP */ - } else { - size_t mlen = sizeof(*eth) + len; - eth = os_malloc(mlen); - if (eth == NULL) - return -1; - - os_memcpy(eth->h_dest, dst_addr, ETH_ALEN); - os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN); - eth->h_proto = htons(proto); - os_memcpy(eth + 1, buf, len); - -#ifdef CONFIG_WINPCAP - ret = pcap_sendpacket(l2->pcap, (u8 *) eth, mlen); -#else /* CONFIG_WINPCAP */ - ret = eth_send(l2->eth, (u8 *) eth, mlen); -#endif /* CONFIG_WINPCAP */ - - os_free(eth); - } - - return ret; -} - - -#ifndef CONFIG_WINPCAP -static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct l2_packet_data *l2 = eloop_ctx; - pcap_t *pcap = sock_ctx; - struct pcap_pkthdr hdr; - const u_char *packet; - struct l2_ethhdr *ethhdr; - unsigned char *buf; - size_t len; - - packet = pcap_next(pcap, &hdr); - - if (packet == NULL || hdr.caplen < sizeof(*ethhdr)) - return; - - ethhdr = (struct l2_ethhdr *) packet; - if (l2->l2_hdr) { - buf = (unsigned char *) ethhdr; - len = hdr.caplen; - } else { - buf = (unsigned char *) (ethhdr + 1); - len = hdr.caplen - sizeof(*ethhdr); - } - l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len); -} -#endif /* CONFIG_WINPCAP */ - - -#ifdef CONFIG_WINPCAP -static void l2_packet_receive_cb(u_char *user, const struct pcap_pkthdr *hdr, - const u_char *pkt_data) -{ - struct l2_packet_data *l2 = (struct l2_packet_data *) user; - struct l2_ethhdr *ethhdr; - unsigned char *buf; - size_t len; - - if (pkt_data == NULL || hdr->caplen < sizeof(*ethhdr)) - return; - - ethhdr = (struct l2_ethhdr *) pkt_data; - if (l2->l2_hdr) { - buf = (unsigned char *) ethhdr; - len = hdr->caplen; - } else { - buf = (unsigned char *) (ethhdr + 1); - len = hdr->caplen - sizeof(*ethhdr); - } - l2->rx_callback(l2->rx_callback_ctx, ethhdr->h_source, buf, len); - /* - * Use shorter poll interval for 3 seconds to reduce latency during key - * handshake. - */ - l2->num_fast_poll = 3 * 50; -} - - -static void l2_packet_receive_timeout(void *eloop_ctx, void *timeout_ctx) -{ - struct l2_packet_data *l2 = eloop_ctx; - pcap_t *pcap = timeout_ctx; - int timeout; - - if (l2->num_fast_poll > 0) { - timeout = 20000; - l2->num_fast_poll--; - } else - timeout = 100000; - - /* Register new timeout before calling l2_packet_receive() since - * receive handler may free this l2_packet instance (which will - * cancel this timeout). */ - eloop_register_timeout(0, timeout, l2_packet_receive_timeout, - l2, pcap); - pcap_dispatch(pcap, 10, l2_packet_receive_cb, (u_char *) l2); -} -#endif /* CONFIG_WINPCAP */ - - -static int l2_packet_init_libpcap(struct l2_packet_data *l2, - unsigned short protocol) -{ - bpf_u_int32 pcap_maskp, pcap_netp; - char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE]; - struct bpf_program pcap_fp; - -#ifdef CONFIG_WINPCAP - char ifname[128]; - os_snprintf(ifname, sizeof(ifname), "\\Device\\NPF_%s", l2->ifname); - pcap_lookupnet(ifname, &pcap_netp, &pcap_maskp, pcap_err); - l2->pcap = pcap_open_live(ifname, 2500, 0, 10, pcap_err); - if (l2->pcap == NULL) { - fprintf(stderr, "pcap_open_live: %s\n", pcap_err); - fprintf(stderr, "ifname='%s'\n", ifname); - return -1; - } - if (pcap_setnonblock(l2->pcap, 1, pcap_err) < 0) - fprintf(stderr, "pcap_setnonblock: %s\n", - pcap_geterr(l2->pcap)); -#else /* CONFIG_WINPCAP */ - pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err); - l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 10, pcap_err); - if (l2->pcap == NULL) { - fprintf(stderr, "pcap_open_live: %s\n", pcap_err); - fprintf(stderr, "ifname='%s'\n", l2->ifname); - return -1; - } - if (pcap_datalink(l2->pcap) != DLT_EN10MB && - pcap_set_datalink(l2->pcap, DLT_EN10MB) < 0) { - fprintf(stderr, "pcap_set_datalink(DLT_EN10MB): %s\n", - pcap_geterr(l2->pcap)); - return -1; - } -#endif /* CONFIG_WINPCAP */ - os_snprintf(pcap_filter, sizeof(pcap_filter), - "not ether src " MACSTR " and " - "( ether dst " MACSTR " or ether dst " MACSTR " ) and " - "ether proto 0x%x", - MAC2STR(l2->own_addr), /* do not receive own packets */ - MAC2STR(l2->own_addr), MAC2STR(pae_group_addr), - protocol); - if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) { - fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap)); - return -1; - } - - if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) { - fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(l2->pcap)); - return -1; - } - - pcap_freecode(&pcap_fp); -#ifdef BIOCIMMEDIATE - /* - * When libpcap uses BPF we must enable "immediate mode" to - * receive frames right away; otherwise the system may - * buffer them for us. - */ - { - unsigned int on = 1; - if (ioctl(pcap_fileno(l2->pcap), BIOCIMMEDIATE, &on) < 0) { - fprintf(stderr, "%s: cannot enable immediate mode on " - "interface %s: %s\n", - __func__, l2->ifname, strerror(errno)); - /* XXX should we fail? */ - } - } -#endif /* BIOCIMMEDIATE */ - -#ifdef CONFIG_WINPCAP - eloop_register_timeout(0, 100000, l2_packet_receive_timeout, - l2, l2->pcap); -#else /* CONFIG_WINPCAP */ - eloop_register_read_sock(pcap_get_selectable_fd(l2->pcap), - l2_packet_receive, l2, l2->pcap); -#endif /* CONFIG_WINPCAP */ - - return 0; -} - - -struct l2_packet_data * l2_packet_init( - const char *ifname, const u8 *own_addr, unsigned short protocol, - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len), - void *rx_callback_ctx, int l2_hdr) -{ - struct l2_packet_data *l2; - - l2 = os_zalloc(sizeof(struct l2_packet_data)); - if (l2 == NULL) - return NULL; - os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); - l2->rx_callback = rx_callback; - l2->rx_callback_ctx = rx_callback_ctx; - l2->l2_hdr = l2_hdr; - -#ifdef CONFIG_WINPCAP - if (own_addr) - os_memcpy(l2->own_addr, own_addr, ETH_ALEN); -#else /* CONFIG_WINPCAP */ - if (l2_packet_init_libdnet(l2)) - return NULL; -#endif /* CONFIG_WINPCAP */ - - if (l2_packet_init_libpcap(l2, protocol)) { -#ifndef CONFIG_WINPCAP - eth_close(l2->eth); -#endif /* CONFIG_WINPCAP */ - os_free(l2); - return NULL; - } - - return l2; -} - - -void l2_packet_deinit(struct l2_packet_data *l2) -{ - if (l2 == NULL) - return; - -#ifdef CONFIG_WINPCAP - eloop_cancel_timeout(l2_packet_receive_timeout, l2, l2->pcap); -#else /* CONFIG_WINPCAP */ - if (l2->eth) - eth_close(l2->eth); - eloop_unregister_read_sock(pcap_get_selectable_fd(l2->pcap)); -#endif /* CONFIG_WINPCAP */ - if (l2->pcap) - pcap_close(l2->pcap); - os_free(l2); -} - - -int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) -{ - pcap_if_t *devs, *dev; - struct pcap_addr *addr; - struct sockaddr_in *saddr; - int found = 0; - char err[PCAP_ERRBUF_SIZE + 1]; - - if (pcap_findalldevs(&devs, err) < 0) { - wpa_printf(MSG_DEBUG, "pcap_findalldevs: %s\n", err); - return -1; - } - - for (dev = devs; dev && !found; dev = dev->next) { - if (os_strcmp(dev->name, l2->ifname) != 0) - continue; - - addr = dev->addresses; - while (addr) { - saddr = (struct sockaddr_in *) addr->addr; - if (saddr && saddr->sin_family == AF_INET) { - os_strlcpy(buf, inet_ntoa(saddr->sin_addr), - len); - found = 1; - break; - } - addr = addr->next; - } - } - - pcap_freealldevs(devs); - - return found ? 0 : -1; -} - - -void l2_packet_notify_auth_start(struct l2_packet_data *l2) -{ -#ifdef CONFIG_WINPCAP - /* - * Use shorter poll interval for 3 seconds to reduce latency during key - * handshake. - */ - l2->num_fast_poll = 3 * 50; - eloop_cancel_timeout(l2_packet_receive_timeout, l2, l2->pcap); - eloop_register_timeout(0, 10000, l2_packet_receive_timeout, - l2, l2->pcap); -#endif /* CONFIG_WINPCAP */ -} diff --git a/contrib/wpa/src/l2_packet/l2_packet_privsep.c b/contrib/wpa/src/l2_packet/l2_packet_privsep.c deleted file mode 100644 index c0e7c49..0000000 --- a/contrib/wpa/src/l2_packet/l2_packet_privsep.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * WPA Supplicant - Layer2 packet handling with privilege separation - * Copyright (c) 2007, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - */ - -#include "includes.h" -#include <sys/un.h> - -#include "common.h" -#include "eloop.h" -#include "l2_packet.h" -#include "privsep_commands.h" - - -struct l2_packet_data { - int fd; /* UNIX domain socket for privsep access */ - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len); - void *rx_callback_ctx; - u8 own_addr[ETH_ALEN]; - char *own_socket_path; - struct sockaddr_un priv_addr; -}; - - -static int wpa_priv_cmd(struct l2_packet_data *l2, int cmd, - const void *data, size_t data_len) -{ - struct msghdr msg; - struct iovec io[2]; - - io[0].iov_base = &cmd; - io[0].iov_len = sizeof(cmd); - io[1].iov_base = (u8 *) data; - io[1].iov_len = data_len; - - os_memset(&msg, 0, sizeof(msg)); - msg.msg_iov = io; - msg.msg_iovlen = data ? 2 : 1; - msg.msg_name = &l2->priv_addr; - msg.msg_namelen = sizeof(l2->priv_addr); - - if (sendmsg(l2->fd, &msg, 0) < 0) { - perror("L2: sendmsg(cmd)"); - return -1; - } - - return 0; -} - - -int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) -{ - os_memcpy(addr, l2->own_addr, ETH_ALEN); - return 0; -} - - -int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, - const u8 *buf, size_t len) -{ - struct msghdr msg; - struct iovec io[4]; - int cmd = PRIVSEP_CMD_L2_SEND; - - io[0].iov_base = &cmd; - io[0].iov_len = sizeof(cmd); - io[1].iov_base = &dst_addr; - io[1].iov_len = ETH_ALEN; - io[2].iov_base = &proto; - io[2].iov_len = 2; - io[3].iov_base = (u8 *) buf; - io[3].iov_len = len; - - os_memset(&msg, 0, sizeof(msg)); - msg.msg_iov = io; - msg.msg_iovlen = 4; - msg.msg_name = &l2->priv_addr; - msg.msg_namelen = sizeof(l2->priv_addr); - - if (sendmsg(l2->fd, &msg, 0) < 0) { - perror("L2: sendmsg(packet_send)"); - return -1; - } - - return 0; -} - - -static void l2_packet_receive(int sock, void *eloop_ctx, void *sock_ctx) -{ - struct l2_packet_data *l2 = eloop_ctx; - u8 buf[2300]; - int res; - struct sockaddr_un from; - socklen_t fromlen = sizeof(from); - - os_memset(&from, 0, sizeof(from)); - res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from, - &fromlen); - if (res < 0) { - perror("l2_packet_receive - recvfrom"); - return; - } - if (res < ETH_ALEN) { - wpa_printf(MSG_DEBUG, "L2: Too show packet received"); - return; - } - - if (from.sun_family != AF_UNIX || - os_strncmp(from.sun_path, l2->priv_addr.sun_path, - sizeof(from.sun_path)) != 0) { - wpa_printf(MSG_DEBUG, "L2: Received message from unexpected " - "source"); - return; - } - - l2->rx_callback(l2->rx_callback_ctx, buf, buf + ETH_ALEN, - res - ETH_ALEN); -} - - -struct l2_packet_data * l2_packet_init( - const char *ifname, const u8 *own_addr, unsigned short protocol, - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len), - void *rx_callback_ctx, int l2_hdr) -{ - struct l2_packet_data *l2; - char *own_dir = "/tmp"; - char *priv_dir = "/var/run/wpa_priv"; - size_t len; - static unsigned int counter = 0; - struct sockaddr_un addr; - fd_set rfds; - struct timeval tv; - int res; - u8 reply[ETH_ALEN + 1]; - int reg_cmd[2]; - - l2 = os_zalloc(sizeof(struct l2_packet_data)); - if (l2 == NULL) - return NULL; - l2->rx_callback = rx_callback; - l2->rx_callback_ctx = rx_callback_ctx; - - len = os_strlen(own_dir) + 50; - l2->own_socket_path = os_malloc(len); - if (l2->own_socket_path == NULL) { - os_free(l2); - return NULL; - } - os_snprintf(l2->own_socket_path, len, "%s/wpa_privsep-l2-%d-%d", - own_dir, getpid(), counter++); - - l2->priv_addr.sun_family = AF_UNIX; - os_snprintf(l2->priv_addr.sun_path, sizeof(l2->priv_addr.sun_path), - "%s/%s", priv_dir, ifname); - - l2->fd = socket(PF_UNIX, SOCK_DGRAM, 0); - if (l2->fd < 0) { - perror("socket(PF_UNIX)"); - os_free(l2->own_socket_path); - l2->own_socket_path = NULL; - os_free(l2); - return NULL; - } - - os_memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - os_strlcpy(addr.sun_path, l2->own_socket_path, sizeof(addr.sun_path)); - if (bind(l2->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("bind(PF_UNIX)"); - goto fail; - } - - reg_cmd[0] = protocol; - reg_cmd[1] = l2_hdr; - if (wpa_priv_cmd(l2, PRIVSEP_CMD_L2_REGISTER, reg_cmd, sizeof(reg_cmd)) - < 0) { - wpa_printf(MSG_ERROR, "L2: Failed to register with wpa_priv"); - goto fail; - } - - FD_ZERO(&rfds); - FD_SET(l2->fd, &rfds); - tv.tv_sec = 5; - tv.tv_usec = 0; - res = select(l2->fd + 1, &rfds, NULL, NULL, &tv); - if (res < 0 && errno != EINTR) { - perror("select"); - goto fail; - } - - if (FD_ISSET(l2->fd, &rfds)) { - res = recv(l2->fd, reply, sizeof(reply), 0); - if (res < 0) { - perror("recv"); - goto fail; - } - } else { - wpa_printf(MSG_DEBUG, "L2: Timeout while waiting for " - "registration reply"); - goto fail; - } - - if (res != ETH_ALEN) { - wpa_printf(MSG_DEBUG, "L2: Unexpected registration reply " - "(len=%d)", res); - } - os_memcpy(l2->own_addr, reply, ETH_ALEN); - - eloop_register_read_sock(l2->fd, l2_packet_receive, l2, NULL); - - return l2; - -fail: - close(l2->fd); - l2->fd = -1; - unlink(l2->own_socket_path); - os_free(l2->own_socket_path); - l2->own_socket_path = NULL; - os_free(l2); - return NULL; -} - - -void l2_packet_deinit(struct l2_packet_data *l2) -{ - if (l2 == NULL) - return; - - if (l2->fd >= 0) { - wpa_priv_cmd(l2, PRIVSEP_CMD_L2_UNREGISTER, NULL, 0); - eloop_unregister_read_sock(l2->fd); - close(l2->fd); - } - - if (l2->own_socket_path) { - unlink(l2->own_socket_path); - os_free(l2->own_socket_path); - } - - os_free(l2); -} - - -int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) -{ - /* TODO */ - return -1; -} - - -void l2_packet_notify_auth_start(struct l2_packet_data *l2) -{ - wpa_priv_cmd(l2, PRIVSEP_CMD_L2_NOTIFY_AUTH_START, NULL, 0); -} diff --git a/contrib/wpa/src/l2_packet/l2_packet_winpcap.c b/contrib/wpa/src/l2_packet/l2_packet_winpcap.c deleted file mode 100644 index f76b386..0000000 --- a/contrib/wpa/src/l2_packet/l2_packet_winpcap.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * WPA Supplicant - Layer2 packet handling with WinPcap RX thread - * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * This l2_packet implementation is explicitly for WinPcap and Windows events. - * l2_packet_pcap.c has support for WinPcap, but it requires polling to receive - * frames which means relatively long latency for EAPOL RX processing. The - * implementation here uses a separate thread to allow WinPcap to be receiving - * all the time to reduce latency for EAPOL receiving from about 100 ms to 3 ms - * when comparing l2_packet_pcap.c to l2_packet_winpcap.c. Extra sleep of 50 ms - * is added in to receive thread whenever no EAPOL frames has been received for - * a while. Whenever an EAPOL handshake is expected, this sleep is removed. - * - * The RX thread receives a frame and signals main thread through Windows event - * about the availability of a new frame. Processing the received frame is - * synchronized with pair of Windows events so that no extra buffer or queuing - * mechanism is needed. This implementation requires Windows specific event - * loop implementation, i.e., eloop_win.c. - * - * WinPcap has pcap_getevent() that could, in theory at least, be used to - * implement this kind of waiting with a simpler single-thread design. However, - * that event handle is not really signaled immediately when receiving each - * frame, so it does not really work for this kind of use. - */ - -#include "includes.h" -#include <pcap.h> - -#include "common.h" -#include "eloop.h" -#include "l2_packet.h" - - -static const u8 pae_group_addr[ETH_ALEN] = -{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; - -/* - * Number of pcap_dispatch() iterations to do without extra wait after each - * received EAPOL packet or authentication notification. This is used to reduce - * latency for EAPOL receive. - */ -static const size_t no_wait_count = 750; - -struct l2_packet_data { - pcap_t *pcap; - unsigned int num_fast_poll; - char ifname[100]; - u8 own_addr[ETH_ALEN]; - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len); - void *rx_callback_ctx; - int l2_hdr; /* whether to include layer 2 (Ethernet) header in calls to - * rx_callback and l2_packet_send() */ - int running; - HANDLE rx_avail, rx_done, rx_thread, rx_thread_done, rx_notify; - u8 *rx_buf, *rx_src; - size_t rx_len; - size_t rx_no_wait; -}; - - -int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) -{ - os_memcpy(addr, l2->own_addr, ETH_ALEN); - return 0; -} - - -int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto, - const u8 *buf, size_t len) -{ - int ret; - struct l2_ethhdr *eth; - - if (l2 == NULL) - return -1; - - if (l2->l2_hdr) { - ret = pcap_sendpacket(l2->pcap, buf, len); - } else { - size_t mlen = sizeof(*eth) + len; - eth = os_malloc(mlen); - if (eth == NULL) - return -1; - - os_memcpy(eth->h_dest, dst_addr, ETH_ALEN); - os_memcpy(eth->h_source, l2->own_addr, ETH_ALEN); - eth->h_proto = htons(proto); - os_memcpy(eth + 1, buf, len); - ret = pcap_sendpacket(l2->pcap, (u8 *) eth, mlen); - os_free(eth); - } - - return ret; -} - - -/* pcap_dispatch() callback for the RX thread */ -static void l2_packet_receive_cb(u_char *user, const struct pcap_pkthdr *hdr, - const u_char *pkt_data) -{ - struct l2_packet_data *l2 = (struct l2_packet_data *) user; - struct l2_ethhdr *ethhdr; - - if (pkt_data == NULL || hdr->caplen < sizeof(*ethhdr)) - return; - - ethhdr = (struct l2_ethhdr *) pkt_data; - if (l2->l2_hdr) { - l2->rx_buf = (u8 *) ethhdr; - l2->rx_len = hdr->caplen; - } else { - l2->rx_buf = (u8 *) (ethhdr + 1); - l2->rx_len = hdr->caplen - sizeof(*ethhdr); - } - l2->rx_src = ethhdr->h_source; - SetEvent(l2->rx_avail); - WaitForSingleObject(l2->rx_done, INFINITE); - ResetEvent(l2->rx_done); - l2->rx_no_wait = no_wait_count; -} - - -/* main RX loop that is running in a separate thread */ -static DWORD WINAPI l2_packet_receive_thread(LPVOID arg) -{ - struct l2_packet_data *l2 = arg; - - while (l2->running) { - pcap_dispatch(l2->pcap, 1, l2_packet_receive_cb, - (u_char *) l2); - if (l2->rx_no_wait > 0) - l2->rx_no_wait--; - if (WaitForSingleObject(l2->rx_notify, - l2->rx_no_wait ? 0 : 50) == - WAIT_OBJECT_0) { - l2->rx_no_wait = no_wait_count; - ResetEvent(l2->rx_notify); - } - } - SetEvent(l2->rx_thread_done); - ExitThread(0); - return 0; -} - - -/* main thread RX event handler */ -static void l2_packet_rx_event(void *eloop_data, void *user_data) -{ - struct l2_packet_data *l2 = eloop_data; - l2->rx_callback(l2->rx_callback_ctx, l2->rx_src, l2->rx_buf, - l2->rx_len); - ResetEvent(l2->rx_avail); - SetEvent(l2->rx_done); -} - - -static int l2_packet_init_libpcap(struct l2_packet_data *l2, - unsigned short protocol) -{ - bpf_u_int32 pcap_maskp, pcap_netp; - char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE]; - struct bpf_program pcap_fp; - - pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err); - l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 1, pcap_err); - if (l2->pcap == NULL) { - fprintf(stderr, "pcap_open_live: %s\n", pcap_err); - fprintf(stderr, "ifname='%s'\n", l2->ifname); - return -1; - } - os_snprintf(pcap_filter, sizeof(pcap_filter), - "not ether src " MACSTR " and " - "( ether dst " MACSTR " or ether dst " MACSTR " ) and " - "ether proto 0x%x", - MAC2STR(l2->own_addr), /* do not receive own packets */ - MAC2STR(l2->own_addr), MAC2STR(pae_group_addr), - protocol); - if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) { - fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap)); - return -1; - } - - if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) { - fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(l2->pcap)); - return -1; - } - - pcap_freecode(&pcap_fp); - - return 0; -} - - -struct l2_packet_data * l2_packet_init( - const char *ifname, const u8 *own_addr, unsigned short protocol, - void (*rx_callback)(void *ctx, const u8 *src_addr, - const u8 *buf, size_t len), - void *rx_callback_ctx, int l2_hdr) -{ - struct l2_packet_data *l2; - DWORD thread_id; - - l2 = os_zalloc(sizeof(struct l2_packet_data)); - if (l2 == NULL) - return NULL; - if (os_strncmp(ifname, "\\Device\\NPF_", 12) == 0) - os_strlcpy(l2->ifname, ifname, sizeof(l2->ifname)); - else - os_snprintf(l2->ifname, sizeof(l2->ifname), "\\Device\\NPF_%s", - ifname); - l2->rx_callback = rx_callback; - l2->rx_callback_ctx = rx_callback_ctx; - l2->l2_hdr = l2_hdr; - - if (own_addr) - os_memcpy(l2->own_addr, own_addr, ETH_ALEN); - - if (l2_packet_init_libpcap(l2, protocol)) { - os_free(l2); - return NULL; - } - - l2->rx_avail = CreateEvent(NULL, TRUE, FALSE, NULL); - l2->rx_done = CreateEvent(NULL, TRUE, FALSE, NULL); - l2->rx_notify = CreateEvent(NULL, TRUE, FALSE, NULL); - if (l2->rx_avail == NULL || l2->rx_done == NULL || - l2->rx_notify == NULL) { - CloseHandle(l2->rx_avail); - CloseHandle(l2->rx_done); - CloseHandle(l2->rx_notify); - pcap_close(l2->pcap); - os_free(l2); - return NULL; - } - - eloop_register_event(l2->rx_avail, sizeof(l2->rx_avail), - l2_packet_rx_event, l2, NULL); - - l2->running = 1; - l2->rx_thread = CreateThread(NULL, 0, l2_packet_receive_thread, l2, 0, - &thread_id); - - return l2; -} - - -static void l2_packet_deinit_timeout(void *eloop_ctx, void *timeout_ctx) -{ - struct l2_packet_data *l2 = eloop_ctx; - - if (l2->rx_thread_done && - WaitForSingleObject(l2->rx_thread_done, 2000) != WAIT_OBJECT_0) { - wpa_printf(MSG_DEBUG, "l2_packet_winpcap: RX thread did not " - "exit - kill it\n"); - TerminateThread(l2->rx_thread, 0); - } - CloseHandle(l2->rx_thread_done); - CloseHandle(l2->rx_thread); - if (l2->pcap) - pcap_close(l2->pcap); - eloop_unregister_event(l2->rx_avail, sizeof(l2->rx_avail)); - CloseHandle(l2->rx_avail); - CloseHandle(l2->rx_done); - CloseHandle(l2->rx_notify); - os_free(l2); -} - - -void l2_packet_deinit(struct l2_packet_data *l2) -{ - if (l2 == NULL) - return; - - l2->rx_thread_done = CreateEvent(NULL, TRUE, FALSE, NULL); - - l2->running = 0; - pcap_breakloop(l2->pcap); - - /* - * RX thread may be waiting in l2_packet_receive_cb() for l2->rx_done - * event and this event is set in l2_packet_rx_event(). However, - * l2_packet_deinit() may end up being called from l2->rx_callback(), - * so we need to return from here and complete deinitialization in - * a registered timeout to avoid having to forcefully kill the RX - * thread. - */ - eloop_register_timeout(0, 0, l2_packet_deinit_timeout, l2, NULL); -} - - -int l2_packet_get_ip_addr(struct l2_packet_data *l2, char *buf, size_t len) -{ - pcap_if_t *devs, *dev; - struct pcap_addr *addr; - struct sockaddr_in *saddr; - int found = 0; - char err[PCAP_ERRBUF_SIZE + 1]; - - if (pcap_findalldevs(&devs, err) < 0) { - wpa_printf(MSG_DEBUG, "pcap_findalldevs: %s\n", err); - return -1; - } - - for (dev = devs; dev && !found; dev = dev->next) { - if (os_strcmp(dev->name, l2->ifname) != 0) - continue; - - addr = dev->addresses; - while (addr) { - saddr = (struct sockaddr_in *) addr->addr; - if (saddr && saddr->sin_family == AF_INET) { - os_strlcpy(buf, inet_ntoa(saddr->sin_addr), - len); - found = 1; - break; - } - addr = addr->next; - } - } - - pcap_freealldevs(devs); - - return found ? 0 : -1; -} - - -void l2_packet_notify_auth_start(struct l2_packet_data *l2) -{ - if (l2) - SetEvent(l2->rx_notify); -} |