1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant - driver interaction with Linux Host AP driver 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <sys/ioctl.h> 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wireless_copy.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "driver.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "driver_wext.h" 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "driver_hostap.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_driver_hostap_data { 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *wext; /* private data for driver_wext */ 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *ctx; 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char ifname[IFNAMSIZ + 1]; 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int sock; 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int current_mode; /* infra/adhoc */ 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int hostapd_ioctl(struct wpa_driver_hostap_data *drv, 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct prism2_hostapd_param *param, 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int len, int show_err) 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct iwreq iwr; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iwr.u.data.pointer = (caddr_t) param; 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iwr.u.data.length = len; 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ioctl(drv->sock, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = errno; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (show_err) 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_wpa_ie(struct wpa_driver_hostap_data *drv, 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *wpa_ie, size_t wpa_ie_len) 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct prism2_hostapd_param *param; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int res; 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (blen < sizeof(*param)) 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt blen = sizeof(*param); 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param = os_zalloc(blen); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (param == NULL) 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT; 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->u.generic_elem.len = wpa_ie_len; 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = hostapd_ioctl(drv, param, blen, 1); 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(param); 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return res; 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int prism2param(struct wpa_driver_hostap_data *drv, int param, 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int value) 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct iwreq iwr; 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int *i, ret = 0; 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt i = (int *) iwr.u.name; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *i++ = param; 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *i++ = value; 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ioctl(drv->sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) { 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("ioctl[PRISM2_IOCTL_PRISM2_PARAM]"); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_wpa(void *priv, int enabled) 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = 0; 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!enabled && wpa_driver_hostap_set_wpa_ie(drv, NULL, 0) < 0) 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING, enabled ? 2 : 0) < 0) 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prism2param(drv, PRISM2_PARAM_WPA, enabled) < 0) 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void show_set_key_error(struct prism2_hostapd_param *param) 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (param->u.crypt.err) { 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_UNKNOWN_ALG: 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "Unknown algorithm '%s'.", 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->u.crypt.alg); 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "You may need to load kernel module to " 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "register that algorithm."); 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "E.g., 'modprobe hostap_crypt_wep' for " 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "WEP."); 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR: 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "Unknown address " MACSTR ".", 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MAC2STR(param->sta_addr)); 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED: 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "Crypt algorithm initialization failed."); 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_KEY_SET_FAILED: 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "Key setting failed."); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED: 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "TX key index setting failed."); 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED: 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "Card configuration failed."); 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_key(void *priv, wpa_alg alg, 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr, int key_idx, 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int set_tx, const u8 *seq, size_t seq_len, 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *key, size_t key_len) 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct prism2_hostapd_param *param; 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *buf; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t blen; 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = 0; 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *alg_name; 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (alg) { 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_NONE: 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt alg_name = "none"; 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_WEP: 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt alg_name = "WEP"; 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_TKIP: 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt alg_name = "TKIP"; 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_CCMP: 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt alg_name = "CCMP"; 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) seq_len, (unsigned long) key_len); 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (seq_len > 8) 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -2; 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt blen = sizeof(*param) + key_len; 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf = os_zalloc(blen); 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (buf == NULL) 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param = (struct prism2_hostapd_param *) buf; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->cmd = PRISM2_SET_ENCRYPTION; 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: In theory, STA in client mode can use five keys; four default 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * keys for receiving (with keyidx 0..3) and one individual key for 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * both transmitting and receiving (keyidx 0) _unicast_ packets. Now, 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * keyidx 0 is reserved for this unicast use and default keys can only 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported). 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This should be fine for more or less all cases, but for completeness 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * sake, the driver could be enhanced to support the missing key. */ 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (addr == NULL) 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(param->sta_addr, 0xff, ETH_ALEN); 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(param->sta_addr, addr, ETH_ALEN); 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(param->sta_addr, 0xff, ETH_ALEN); 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy((char *) param->u.crypt.alg, alg_name, 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HOSTAP_CRYPT_ALG_NAME_LEN); 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->u.crypt.idx = key_idx; 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(param->u.crypt.seq, seq, seq_len); 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param->u.crypt.key_len = key_len; 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy((u8 *) (param + 1), key, key_len); 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (hostapd_ioctl(drv, param, blen, 1)) { 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_WARNING, "Failed to set encryption."); 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt show_set_key_error(param); 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(buf); 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_countermeasures(void *priv, int enabled) 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return prism2param(drv, PRISM2_PARAM_TKIP_COUNTERMEASURES, enabled); 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_drop_unencrypted(void *priv, int enabled) 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return prism2param(drv, PRISM2_PARAM_DROP_UNENCRYPTED, enabled); 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_reset(struct wpa_driver_hostap_data *drv, 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int type) 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct iwreq iwr; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int *i, ret = 0; 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: type=%d", __FUNCTION__, type); 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&iwr, 0, sizeof(iwr)); 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt i = (int *) iwr.u.name; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *i++ = type; 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ioctl(drv->sock, PRISM2_IOCTL_RESET, &iwr) < 0) { 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("ioctl[PRISM2_IOCTL_RESET]"); 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_mlme(struct wpa_driver_hostap_data *drv, 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr, int cmd, int reason_code) 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct prism2_hostapd_param param; 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* There does not seem to be a better way of deauthenticating or 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * disassociating with Prism2/2.5/3 than sending the management frame 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * and then resetting the Port0 to make sure both the AP and the STA 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * end up in disconnected state. */ 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(¶m, 0, sizeof(param)); 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param.cmd = PRISM2_HOSTAPD_MLME; 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(param.sta_addr, addr, ETH_ALEN); 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param.u.mlme.cmd = cmd; 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param.u.mlme.reason_code = reason_code; 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1); 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret == 0) { 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_sleep(0, 100000); 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = wpa_driver_hostap_reset(drv, 2); 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_deauthenticate(void *priv, const u8 *addr, 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reason_code) 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DEAUTH, 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reason_code); 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_disassociate(void *priv, const u8 *addr, 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reason_code) 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DISASSOC, 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reason_code); 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_driver_hostap_associate(void *priv, 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_associate_params *params) 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = 0; 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int allow_unencrypted_eapol; 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (params->mode != drv->current_mode) { 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* At the moment, Host AP driver requires host_roaming=2 for 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * infrastructure mode and host_roaming=0 for adhoc. */ 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING, 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->mode == IEEE80211_MODE_IBSS ? 0 : 2) < 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0) { 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: failed to set host_roaming", 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__); 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->current_mode = params->mode; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prism2param(drv, PRISM2_PARAM_PRIVACY_INVOKED, 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->key_mgmt_suite != KEY_MGMT_NONE) < 0) 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_driver_hostap_set_wpa_ie(drv, params->wpa_ie, 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->wpa_ie_len) < 0) 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_driver_wext_set_mode(drv->wext, params->mode) < 0) 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (params->freq && 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt < 0) 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = -1; 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Allow unencrypted EAPOL messages even if pairwise keys are set when 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * not using WPA. IEEE 802.1X specifies that these frames are not 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * encrypted, but WPA encrypts them when pairwise keys are in use. */ 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (params->key_mgmt_suite == KEY_MGMT_802_1X || 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt params->key_mgmt_suite == KEY_MGMT_PSK) 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt allow_unencrypted_eapol = 0; 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt allow_unencrypted_eapol = 1; 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (prism2param(drv, PRISM2_PARAM_IEEE_802_1X, 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt allow_unencrypted_eapol) < 0) { 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "hostap: Failed to configure " 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "ieee_802_1x param"); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Ignore this error.. driver_hostap.c can also be used with 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * other drivers that do not support this prism2_param. */ 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_scan(void *priv, const u8 *ssid, size_t ssid_len) 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct prism2_hostapd_param param; 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ssid == NULL) { 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Use standard Linux Wireless Extensions ioctl if possible 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * because some drivers using hostap code in wpa_supplicant 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * might not support Host AP specific scan request (with SSID 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * info). */ 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_wext_scan(drv->wext, ssid, ssid_len); 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ssid_len > 32) 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ssid_len = 32; 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(¶m, 0, sizeof(param)); 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param.cmd = PRISM2_HOSTAPD_SCAN_REQ; 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt param.u.scan_req.ssid_len = ssid_len; 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(param.u.scan_req.ssid, ssid, ssid_len); 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1); 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Not all drivers generate "scan completed" wireless event, so try to 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * read results after a timeout. */ 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ctx); 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, drv->wext, 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ctx); 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_auth_alg(void *priv, int auth_alg) 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int algs = 0; 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (auth_alg & AUTH_ALG_OPEN_SYSTEM) 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt algs |= 1; 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (auth_alg & AUTH_ALG_SHARED_KEY) 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt algs |= 2; 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (auth_alg & AUTH_ALG_LEAP) 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt algs |= 4; 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (algs == 0) 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt algs = 1; /* at least one algorithm should be set */ 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return prism2param(drv, PRISM2_PARAM_AP_AUTH_ALGS, algs); 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_get_bssid(void *priv, u8 *bssid) 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_wext_get_bssid(drv->wext, bssid); 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_get_ssid(void *priv, u8 *ssid) 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_wext_get_ssid(drv->wext, ssid); 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic struct wpa_scan_results * wpa_driver_hostap_get_scan_results(void *priv) 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_wext_get_scan_results(drv->wext); 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_hostap_set_operstate(void *priv, int state) 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_driver_wext_set_operstate(drv->wext, state); 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void * wpa_driver_hostap_init(void *ctx, const char *ifname) 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv; 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv = os_zalloc(sizeof(*drv)); 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (drv == NULL) 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->wext = wpa_driver_wext_init(ctx, ifname); 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (drv->wext == NULL) { 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ctx = ctx; 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (drv->sock < 0) { 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("socket"); 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_driver_wext_deinit(drv->wext); 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_strncmp(ifname, "wlan", 4) == 0) { 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Host AP driver may use both wlan# and wifi# interface in 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wireless events. 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char ifname2[IFNAMSIZ + 1]; 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(ifname2, ifname, sizeof(ifname2)); 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(ifname2, "wifi", 4); 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_driver_wext_alternative_ifindex(drv->wext, ifname2); 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return drv; 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_driver_hostap_deinit(void *priv) 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_hostap_data *drv = priv; 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_driver_wext_deinit(drv->wext); 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(drv->sock); 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtconst struct wpa_driver_ops wpa_driver_hostap_ops = { 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .name = "hostap", 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .desc = "Host AP driver (Intersil Prism2/2.5/3)", 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_bssid = wpa_driver_hostap_get_bssid, 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_ssid = wpa_driver_hostap_get_ssid, 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_wpa = wpa_driver_hostap_set_wpa, 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_key = wpa_driver_hostap_set_key, 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_countermeasures = wpa_driver_hostap_set_countermeasures, 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_drop_unencrypted = wpa_driver_hostap_set_drop_unencrypted, 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .scan = wpa_driver_hostap_scan, 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_scan_results2 = wpa_driver_hostap_get_scan_results, 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .deauthenticate = wpa_driver_hostap_deauthenticate, 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .disassociate = wpa_driver_hostap_disassociate, 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .associate = wpa_driver_hostap_associate, 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_auth_alg = wpa_driver_hostap_set_auth_alg, 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .init = wpa_driver_hostap_init, 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .deinit = wpa_driver_hostap_deinit, 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_operstate = wpa_driver_hostap_set_operstate, 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 514