ieee802_11.c revision 96be6222df414a7dde5c5b1b72df22e67b1a77fc
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / IEEE 802.11 Management 3391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/crypto.h" 16a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#include "crypto/sha256.h" 17a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#include "crypto/random.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 21a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#include "common/sae.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wmm.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_mlme.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 39a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#include "wnm_ap.h" 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = eid; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, num, count; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates == NULL) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SUPP_RATES; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = hapd->iface->num_rates; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 55d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) 56d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt num++; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num > 8) { 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* rest of the rates are encoded in Extended supported 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rates element */ 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = 8; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = num; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0, count = 0; i < hapd->iface->num_rates && count < num; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = hapd->iface->current_rates[i].rate / 5; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos |= 0x80; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 74d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) { 75d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt count++; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; 77d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 78d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 79d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) { 80d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt count++; 81d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY; 82d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = eid; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, num, count; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates == NULL) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = hapd->iface->num_rates; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 99d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) 100d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt num++; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num <= 8) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num -= 8; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_EXT_SUPP_RATES; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = num; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count <= 8) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* already in SuppRates IE */ 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = hapd->iface->current_rates[i].rate / 5; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos |= 0x80; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 119d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) { 120d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt count++; 121d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (count > 8) 122d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; 123d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 124d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 125d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) { 126d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt count++; 127d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (count > 8) 128d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY; 129d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int probe) 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int capab = WLAN_CAPABILITY_ESS; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int privacy; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_no_short_preamble == 0 && 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->preamble == SHORT_PREAMBLE) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = hapd->conf->ssid.wep.keys_set; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x && 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (hapd->conf->default_wep_key_len || 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->individual_wep_key_len)) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 1; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 1; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) { 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int policy, def_klen; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (probe && sta->ssid_probe) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt policy = sta->ssid_probe->security_policy; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt def_klen = sta->ssid_probe->wep.default_len; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt policy = sta->ssid->security_policy; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt def_klen = sta->ssid->wep.default_len; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = policy != SECURITY_PLAINTEXT; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (policy == SECURITY_IEEE_802_1X && def_klen == 0) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 0; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (privacy) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_PRIVACY; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode && 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time == 0) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return capab; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta, 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_transaction, const u8 *challenge, 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int iswep) 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication (shared key, transaction %d)", 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_transaction == 1) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta->challenge) { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate a pseudo-random challenge */ 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 key[8]; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int r; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->challenge == NULL) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_random(); 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, &now.sec, 4); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key + 4, &r, 4); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(key, sizeof(key), 0, 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge, WLAN_AUTH_CHALLENGE_LEN); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_transaction != 3) 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Transaction 3 */ 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iswep || !sta->challenge || !challenge || 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) { 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "shared key authentication - invalid " 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "challenge-response"); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_CHALLENGE_FAIL; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication OK (shared key)"); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->challenge); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge = NULL; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_auth_reply(struct hostapd_data *hapd, 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dst, const u8 *bssid, 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, u16 auth_transaction, u16 resp, 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *reply; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(rlen); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = (struct ieee80211_mgmt *) buf; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_AUTH); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->da, dst, ETH_ALEN); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->bssid, bssid, ETH_ALEN); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.auth_alg = host_to_le16(auth_alg); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.auth_transaction = host_to_le16(auth_transaction); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.status_code = host_to_le16(resp); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies && ies_len) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->u.auth.variable, ies, ies_len); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)", 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dst), auth_alg, auth_transaction, 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp, (unsigned long) ies_len); 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0) 268cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "send_auth_reply: send"); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid, 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_transaction, u16 status, 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction, 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status, ies, ies_len); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != WLAN_STATUS_SUCCESS) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, dst); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 300d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 301d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 302a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic struct wpabuf * auth_process_sae_commit(struct hostapd_data *hapd, 303a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct sta_info *sta) 304d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 305d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 306d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 307a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (hapd->conf->ssid.wpa_passphrase == NULL) { 308a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: No password available"); 309d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 310a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 311a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 312a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_prepare_commit(hapd->own_addr, sta->addr, 313a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt (u8 *) hapd->conf->ssid.wpa_passphrase, 314a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_strlen(hapd->conf->ssid.wpa_passphrase), 315a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae) < 0) { 316a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE"); 317a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 318a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 319d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 320a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_process_commit(sta->sae) < 0) { 321a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit"); 322a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 323a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 324a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 325a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN); 326a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (buf == NULL) 327a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 328a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_write_commit(sta->sae, buf, NULL); 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 331d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 332d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 333d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 334d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd, 335d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct sta_info *sta) 336d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 337d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 338d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 339a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN); 340d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf == NULL) 341d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 342d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 343a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_write_confirm(sta->sae, buf); 344d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 345d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 346d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 347d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 348d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 349a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int use_sae_anti_clogging(struct hostapd_data *hapd) 350d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 351a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct sta_info *sta; 352a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt unsigned int open = 0; 353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 354a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (hapd->conf->sae_anti_clogging_threshold == 0) 355a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 1; 356a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 357a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 358a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!sta->sae) 359a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt continue; 360a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sta->sae->state != SAE_COMMITTED && 361a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae->state != SAE_CONFIRMED) 362a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt continue; 363a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt open++; 364a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (open >= hapd->conf->sae_anti_clogging_threshold) 365a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 1; 366d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 367d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 368a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 369a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt} 370a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 371a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 372a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int check_sae_token(struct hostapd_data *hapd, const u8 *addr, 373a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt const u8 *token, size_t token_len) 374a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{ 375a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 mac[SHA256_MAC_LEN]; 376a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 377a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (token_len != SHA256_MAC_LEN) 378a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 379a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key), 380a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt addr, ETH_ALEN, mac) < 0 || 381a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt os_memcmp(token, mac, SHA256_MAC_LEN) != 0) 382a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return -1; 383a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 384a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return 0; 385d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 386d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 387d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 388a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic struct wpabuf * auth_build_token_req(struct hostapd_data *hapd, 389a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt const u8 *addr) 390d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 391a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpabuf *buf; 392a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt u8 *token; 39304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt struct os_reltime now; 394d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 39504f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&now); 39604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt if (!os_reltime_initialized(&hapd->last_sae_token_key_update) || 39704f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60)) { 398a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (random_get_bytes(hapd->sae_token_key, 399a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sizeof(hapd->sae_token_key)) < 0) 400a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 401a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SAE: Updated token key", 402a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->sae_token_key, sizeof(hapd->sae_token_key)); 40304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt hapd->last_sae_token_key_update = now; 404a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 405d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 406a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt buf = wpabuf_alloc(SHA256_MAC_LEN); 407a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (buf == NULL) 408a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return NULL; 409d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 410a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt token = wpabuf_put(buf, SHA256_MAC_LEN); 411a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key), 412a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt addr, ETH_ALEN, token); 413a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 414a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return buf; 415d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta, 419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len, 420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u8 auth_transaction) 421d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 resp = WLAN_STATUS_SUCCESS; 423a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct wpabuf *data = NULL; 424a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 425a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!sta->sae) { 426a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (auth_transaction != 1) 427a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 428a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae = os_zalloc(sizeof(*sta->sae)); 429a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sta->sae == NULL) 430a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 431a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae->state = SAE_NOTHING; 432a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (auth_transaction == 1) { 435a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt const u8 *token = NULL; 436a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt size_t token_len = 0; 437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt HOSTAPD_LEVEL_DEBUG, 439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "start SAE authentication (RX commit)"); 440a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable, 441a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ((const u8 *) mgmt) + len - 442a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt mgmt->u.auth.variable, &token, 443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt &token_len, hapd->conf->sae_groups); 444a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (token && check_sae_token(hapd, sta->addr, token, token_len) 445a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt < 0) { 446a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Drop commit message with " 447a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "incorrect token from " MACSTR, 448a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt MAC2STR(sta->addr)); 449a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt return; 450a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 451a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 452a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (resp == WLAN_STATUS_SUCCESS) { 453a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (!token && use_sae_anti_clogging(hapd)) { 454a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Request anti-" 455a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "clogging token from " MACSTR, 456a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt MAC2STR(sta->addr)); 457a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt data = auth_build_token_req(hapd, sta->addr); 458a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ; 459a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 460a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt data = auth_process_sae_commit(hapd, sta); 461a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (data == NULL) 462a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 463a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else 464a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae->state = SAE_COMMITTED; 465a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 466a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 467d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (auth_transaction == 2) { 468a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sta->sae->state != SAE_COMMITTED) { 469d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_logger(hapd, sta->addr, 470d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt HOSTAPD_MODULE_IEEE80211, 471d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt HOSTAPD_LEVEL_DEBUG, 472d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "SAE confirm before commit"); 473d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 47496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt goto failed; 475d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 476d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 477d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt HOSTAPD_LEVEL_DEBUG, 478d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "SAE authentication (RX confirm)"); 479a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sae_check_confirm(sta->sae, mgmt->u.auth.variable, 480a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt ((u8 *) mgmt) + len - 481a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt mgmt->u.auth.variable) < 0) { 482a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 483a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } else { 484a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = WLAN_STATUS_SUCCESS; 485d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->flags |= WLAN_STA_AUTH; 486d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 487d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->auth_alg = WLAN_AUTH_SAE; 488d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt mlme_authenticate_indication(hapd, sta); 489a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 490a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt data = auth_build_sae_confirm(hapd, sta); 491a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (data == NULL) 492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 493a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt else { 494a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->sae->state = SAE_ACCEPTED; 495a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sae_clear_temp_data(sta->sae); 496a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 497d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 498d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else { 499d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 500d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt HOSTAPD_LEVEL_DEBUG, 501d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "unexpected SAE authentication transaction %u", 502d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt auth_transaction); 503d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 504d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 505d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 50696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtfailed: 507d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->auth_alg = WLAN_AUTH_SAE; 508d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 509d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE, 510d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt auth_transaction, resp, 511d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data ? wpabuf_head(data) : (u8 *) "", 512d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data ? wpabuf_len(data) : 0); 513d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(data); 514d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 515d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 516d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 517d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth(struct hostapd_data *hapd, 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, auth_transaction, status_code; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp = WLAN_STATUS_SUCCESS; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = NULL; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 fc; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *challenge = NULL; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 session_timeout, acct_interim_interval; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vlan_id = 0; 529d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct hostapd_sta_wpa_psk_short *psk = NULL; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t resp_ies_len = 0; 53261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *identity = NULL; 53361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *radius_cui = NULL; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 536cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", 537cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (unsigned long) len); 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5418da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 5428da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (hapd->iconf->ignore_auth_probability > 0.0d && 5438da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt drand48() < hapd->iconf->ignore_auth_probability) { 5448da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt wpa_printf(MSG_INFO, 5458da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt "TESTING: ignoring auth frame from " MACSTR, 5468da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt MAC2STR(mgmt->sa)); 5478da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt return; 5488da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 5498da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 5508da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code = le_to_host16(mgmt->u.auth.status_code); 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc = le_to_host16(mgmt->frame_control); 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + WLAN_AUTH_CHALLENGE_LEN && 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE && 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN) 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge = &mgmt->u.auth.variable[2]; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d " 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "auth_transaction=%d status_code=%d wep=%d%s", 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), auth_alg, auth_transaction, 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code, !!(fc & WLAN_FC_ISWEP), 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge ? " challenge" : ""); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) && 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_OPEN) || 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) && 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_FT) || 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 579d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 580d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) && 581d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt auth_alg == WLAN_AUTH_SAE) || 582d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) && 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_SHARED_KEY))) { 585cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)", 586cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt auth_alg); 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE || 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) { 593cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)", 594cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt auth_transaction); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { 600cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate", 601cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->sa)); 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len, 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &session_timeout, 6081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &acct_interim_interval, &vlan_id, 609d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt &psk, &identity, &radius_cui); 6101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_REJECT) { 612cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate", 613cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->sa)); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_PENDING) { 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " waiting for an external authentication", 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Authentication code will re-send the authentication frame 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after it has received (and cached) information from the 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * external source. */ 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_sta_add(hapd, mgmt->sa); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 6294b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vlan_id > 0) { 63434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (!hostapd_vlan_id_valid(hapd->conf->vlan, vlan_id)) { 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Invalid VLAN ID " 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d received from RADIUS server", 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_id); 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->vlan_id = vlan_id; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 647d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_free_psk_list(sta->psk); 648d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) { 649d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->psk = psk; 650d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt psk = NULL; 6511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 6521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->psk = NULL; 6531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 65561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->identity = identity; 65661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt identity = NULL; 65761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->radius_cui = radius_cui; 65861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt radius_cui = NULL; 65961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_PREAUTH; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval) 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_interim_interval = acct_interim_interval; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_session_timeout(hapd, sta, session_timeout); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_no_session_timeout(hapd, sta); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (auth_alg) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_OPEN: 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication OK (open system)"); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_OPEN; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_SHARED_KEY: 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = auth_shared_key(hapd, sta, auth_transaction, challenge, 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc & WLAN_FC_ISWEP); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_SHARED_KEY; 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->challenge && auth_transaction == 1) { 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies[0] = WLAN_EID_CHALLENGE; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp_ies + 2, sta->challenge, 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_AUTH_CHALLENGE_LEN); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_FT: 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_FT; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 698391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta->addr, NULL); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) { 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine"); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid, 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction, mgmt->u.auth.variable, 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - IEEE80211_HDRLEN - 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.auth), 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth_ft_finish, hapd); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle_auth_ft_finish() callback will complete auth. */ 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 713d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 714d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt case WLAN_AUTH_SAE: 715d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt handle_auth_sae(hapd, sta, mgmt, len, auth_transaction); 716d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 717d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 72161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(identity); 72261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(radius_cui); 723d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt hostapd_free_psk_list(psk); 72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg, 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction + 1, resp, resp_ies, resp_ies_len); 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta) 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j = 32, aid; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* get a unique AID */ 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->aid > 0) { 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " old AID %d", sta->aid); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < AID_WORDS; i++) { 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->sta_aid[i] == (u32) -1) 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 32; j++) { 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(hapd->sta_aid[i] & BIT(j))) 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j < 32) 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j == 32) 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aid = i * 32 + j + 1; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aid > 2007) 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->aid = aid; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->sta_aid[i] |= BIT(j); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " new AID %d", sta->aid); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta, 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid_ie, size_t ssid_ie_len) 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_ie == NULL) 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_ie_len != hapd->conf->ssid.ssid_len || 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) { 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Station tried to associate with unknown SSID " 7743c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len)); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wmm_ie, size_t wmm_ie_len) 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_WMM; 7861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->qosinfo = 0; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wmm_ie && hapd->conf->wmm_enabled) { 7881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wmm_information_element *wmm; 7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_WPA, 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid WMM element in association " 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request"); 7961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 7971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 7981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 7991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags |= WLAN_STA_WMM; 8001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wmm = (struct wmm_information_element *) wmm_ie; 8011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->qosinfo = wmm->qos_info; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems *elems) 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!elems->supp_rates) { 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "No supported rates element in AssocReq"); 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 81761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elems->supp_rates_len + elems->ext_supp_rates_len > 81861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(sta->supported_rates)) { 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 82161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Invalid supported rates element length %d+%d", 82261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->supp_rates_len, 82361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->ext_supp_rates_len); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 82761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->supported_rates_len = merge_byte_arrays( 82861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->supported_rates, sizeof(sta->supported_rates), 82961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->supp_rates, elems->supp_rates_len, 83061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->ext_supp_rates, elems->ext_supp_rates_len); 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 836051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, 837051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt const u8 *ext_capab_ie, size_t ext_capab_ie_len) 838051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{ 839051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef CONFIG_INTERWORKING 840051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt /* check for QoS Map support */ 841051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ext_capab_ie_len >= 5) { 842051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (ext_capab_ie[4] & 0x01) 843051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt sta->qos_map_enabled = 1; 844051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt } 845051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 846051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 847051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return WLAN_STATUS_SUCCESS; 848051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt} 849051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 850051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len, int reassoc) 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 858391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt const u8 *p2p_dev_addr = NULL; 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) { 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station sent an invalid " 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association request"); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len); 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len); 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 873051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len); 874051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 875051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return resp; 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = copy_supp_rates(hapd, sta, &elems); 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities, 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ht_capabilities_len); 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & WLAN_STA_HT)) { 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station does not support " 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mandatory HT PHY - reject association"); 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_ASSOC_DENIED_NO_HT; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 89361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211AC 89461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities, 89561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems.vht_capabilities_len); 89661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 89761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return resp; 89861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && 89961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !(sta->flags & WLAN_STA_VHT)) { 90061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 90161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station does not support " 90261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "mandatory VHT PHY - reject association"); 903fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return WLAN_STATUS_ASSOC_DENIED_NO_VHT; 90461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 90561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211AC */ 90661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 907391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#ifdef CONFIG_P2P 908391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (elems.p2p) { 909391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpabuf_free(sta->p2p_ie); 910391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 911391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt P2P_IE_VENDOR_TYPE); 912391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (sta->p2p_ie) 913391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie); 914391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } else { 915391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpabuf_free(sta->p2p_ie); 916391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta->p2p_ie = NULL; 917391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 918391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#endif /* CONFIG_P2P */ 919391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) { 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = elems.rsn_ie; 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = elems.rsn_ie_len; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if ((hapd->conf->wpa & WPA_PROTO_WPA) && 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.wpa_ie) { 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = elems.wpa_ie; 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = elems.wpa_ie_len; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = NULL; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = 0; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 9331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && elems.wps_ie) { 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association " 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request - assume WPS is used"); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_WPS; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sta->wps_ie); 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_IE_VENDOR_TYPE); 9411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta->wps_ie && wps_is_20(sta->wps_ie)) { 9421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0"); 9431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags |= WLAN_STA_WPS2; 9441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = NULL; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = 0; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) { 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in " 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Re)Association Request - reject"); 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_INVALID_IE; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->conf->wps_state && wpa_ie == NULL) { 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in " 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Re)Association Request - possible WPS use"); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_MAYBE_WPS; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && wpa_ie == NULL) { 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "No WPA/RSN IE in association request"); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_INVALID_IE; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && wpa_ie) { 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie -= 2; 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len += 2; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 971391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt sta->addr, 972391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt p2p_dev_addr); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to initialize WPA " 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine"); 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie, wpa_ie_len, 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.mdie, elems.mdie_len); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == WPA_INVALID_GROUP) 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_PAIRWISE) 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_AKMP) 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_AKMP_NOT_VALID; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_ALLOC_FAIL) 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_MDIE) 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_INVALID_MDIE; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res != WPA_IE_OK) 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_INVALID_IE; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->sa_query_count > 0) 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_check_sa_query_timeout(hapd, sta); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * STA has already been associated with MFP and SA 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query timeout has not been reached. Reject the 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association attempt temporarily and start SA Query, 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one is not pending. 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->sa_query_count == 0) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_start_sa_query(hapd, sta); 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_uses_mfp(sta->wpa_sm)) 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_MFP; 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_MFP; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg == WLAN_AUTH_FT) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!reassoc) { 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried " 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to use association (not " 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "re-association) with FT auth_alg", 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies, 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies_len); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1043d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 1044d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_auth_uses_sae(sta->wpa_sm) && 1045fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sta->auth_alg != WLAN_AUTH_SAE && 1046fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt !(sta->auth_alg == WLAN_AUTH_FT && 1047fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_auth_uses_ft_sae(sta->wpa_sm))) { 1048d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use " 1049d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "SAE AKM after non-SAE auth_alg %u", 1050d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt MAC2STR(sta->addr), sta->auth_alg); 1051d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 1052d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 1053d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 1054d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 105661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) && 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) { 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE80211, 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Station tried to use TKIP with HT " 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association"); 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_no_wpa(sta->wpa_sm); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1073d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_HS20 1074d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(sta->hs20_ie); 1075d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (elems.hs20 && elems.hs20_len > 4) { 1076d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4, 1077d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt elems.hs20_len - 4); 1078d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else 1079d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sta->hs20_ie = NULL; 1080d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_HS20 */ 1081d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_deauth(struct hostapd_data *hapd, const u8 *addr, 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 reason_code) 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int send_len; 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt reply; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&reply, 0, sizeof(reply)); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply.frame_control = 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.da, addr, ETH_ALEN); 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN); 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN); 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply.u.deauth.reason_code = host_to_le16(reason_code); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0) 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to send deauth: %s", 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 status_code, int reassoc, const u8 *ies, 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ies_len) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int send_len; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *reply; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *p; 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(buf, 0, sizeof(buf)); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = (struct ieee80211_mgmt *) buf; 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->frame_control = 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_FC(WLAN_FC_TYPE_MGMT, 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (reassoc ? WLAN_FC_STYPE_REASSOC_RESP : 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_ASSOC_RESP)); 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->da, sta->addr, ETH_ALEN); 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN); 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = IEEE80211_HDRLEN; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len += sizeof(reply->u.assoc_resp); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.assoc_resp.capab_info = 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(hostapd_own_capab_info(hapd, sta, 0)); 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.assoc_resp.status_code = host_to_le16(status_code); 113296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt reply->u.assoc_resp.aid = host_to_le16(sta->aid | BIT(14) | BIT(15)); 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supported rates */ 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extended supported rates */ 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ext_supp_rates(hapd, p); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_SUCCESS) { 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11r: Mobility Domain Information, Fast BSS 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Transition Information, RSN, [RIC Response] */ 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p, 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + sizeof(buf) - p, 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg, ies, ies_len); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_assoc_comeback_time(hapd, sta, p); 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ht_capabilities(hapd, p); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ht_operation(hapd, p); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 115861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211AC 115961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p = hostapd_eid_vht_capabilities(hapd, p); 116061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p = hostapd_eid_vht_operation(hapd, p); 116161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211AC */ 116261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ext_capab(hapd, p); 116404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p = hostapd_eid_bss_max_idle_period(hapd, p); 1165051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (sta->qos_map_enabled) 1166051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt p = hostapd_eid_qos_map_set(hapd, p); 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_WMM) 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_wmm(hapd, p); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((sta->flags & WLAN_STA_WPS) || 11731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) { 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps = wps_build_assoc_resp_ie(); 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps)); 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p += wpabuf_len(wps); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps); 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie) { 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_resp_ie; 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_status_code status; 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status_code) { 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_STATUS_SUCCESS: 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_SUCCESS; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA: 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_LIMIT_REACHED; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status); 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_resp_ie) { 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p, wpabuf_head(p2p_resp_ie), 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(p2p_resp_ie)); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p += wpabuf_len(p2p_resp_ie); 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_resp_ie); 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->p2p & P2P_MANAGE) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_p2p_manage(hapd, p); 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len += p - reply->u.assoc_resp.variable; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to send assoc resp: %s", 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_assoc(struct hostapd_data *hapd, 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len, 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 capab_info, listen_interval; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp = WLAN_STATUS_SUCCESS; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int left, i; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.assoc_req))) { 1233cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)", 1234cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt reassoc, (unsigned long) len); 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12388da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 12398da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (reassoc) { 12408da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (hapd->iconf->ignore_reassoc_probability > 0.0d && 12418da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt drand48() < hapd->iconf->ignore_reassoc_probability) { 12428da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt wpa_printf(MSG_INFO, 12438da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt "TESTING: ignoring reassoc request from " 12448da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt MACSTR, MAC2STR(mgmt->sa)); 12458da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt return; 12468da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 12478da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } else { 12488da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt if (hapd->iconf->ignore_assoc_probability > 0.0d && 12498da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt drand48() < hapd->iconf->ignore_assoc_probability) { 12508da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt wpa_printf(MSG_INFO, 12518da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt "TESTING: ignoring assoc request from " 12528da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt MACSTR, MAC2STR(mgmt->sa)); 12538da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt return; 12548da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 12558da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt } 12568da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 12578da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval = le_to_host16( 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.reassoc_req.listen_interval); 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " capab_info=0x%02x listen_interval=%d current_ap=" 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), capab_info, listen_interval, 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->u.reassoc_req.current_ap)); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = mgmt->u.reassoc_req.variable; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval = le_to_host16( 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.assoc_req.listen_interval); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " capab_info=0x%02x listen_interval=%d", 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), capab_info, listen_interval); 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = mgmt->u.assoc_req.variable; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && sta->auth_alg == WLAN_AUTH_FT && 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sta->flags & WLAN_STA_AUTH) == 0) { 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate " 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "prior to authentication since it is using " 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over-the-DS FT", MAC2STR(mgmt->sa)); 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station tried to " 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associate before authentication " 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(aid=%d flags=0x%x)", 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta ? sta->aid : -1, 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta ? sta->flags : 0); 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_deauth(hapd, mgmt->sa, 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (listen_interval > hapd->conf->max_listen_interval) { 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Too large Listen Interval (%d)", 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval); 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* followed by SSID and Supported rates; and HT capabilities if 802.11n 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is used */ 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_assoc_ies(hapd, sta, pos, left, reassoc); 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_aid(hapd, sta) < 0) { 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "No room for more AIDs"); 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->capability = capab_info; 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->listen_interval = listen_interval; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_NONERP; 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < sta->supported_rates_len; i++) { 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->supported_rates[i] & 0x7f) > 22) { 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_NONERP; 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) { 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->nonerp_set = 1; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_non_erp++; 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_non_erp == 1) 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) && 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sta->no_short_slot_time_set) { 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_short_slot_time_set = 1; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time++; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODE_IEEE80211G && 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time == 1) 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_SHORT_PREAMBLE; 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sta->no_short_preamble_set) { 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_short_preamble_set = 1; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_preamble++; 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt && hapd->iface->num_sta_no_short_preamble == 1) 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt update_ht_state(hapd, sta); 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association OK (aid %d)", sta->aid); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Station will be marked associated, after it acknowledges AssocResp 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_ASSOC_REQ_OK; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) { 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out " 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SA Query procedure", reassoc ? "re" : ""); 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: Send a protected Disassociate frame to the STA using 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the old key and Reason Code "Previous Authentication no 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * longer valid". Make sure this is only sent protected since 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unprotected frame would be received by the STA that is now 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trying to associate. 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap, 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->last_assoc_req); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->last_assoc_req = os_malloc(len); 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sta->last_assoc_req, mgmt, len); 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure that the previously registered inactivity timer will not 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remove the STA immediately. */ 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next = STA_NULLFUNC; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_assoc_resp(hapd, sta, resp, reassoc, pos, left); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_disassoc(struct hostapd_data *hapd, 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { 1420cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)", 1421cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (unsigned long) len); 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt le_to_host16(mgmt->u.disassoc.reason_code)); 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) { 1431cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated", 1432cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->sa)); 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_set_authorized(hapd, sta, 0); 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "disassociated"); 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Stop Accounting and IEEE 802.1X sessions, but leave the STA 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authenticated. */ 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_stop(hapd, sta); 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_free_station(sta); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_remove(hapd, sta->addr); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->timeout_next == STA_NULLFUNC || 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next == STA_DISASSOC) { 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next = STA_DEAUTH; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_disassociate_indication( 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code)); 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_deauth(struct hostapd_data *hapd, 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) { 14681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short " 14691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "payload (len=%lu)", (unsigned long) len); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%d", 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) { 14791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " 14801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "to deauthenticate, but it is not authenticated", 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_set_authorized(hapd, sta, 0); 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STA_ASSOC_REQ_OK); 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "deauthenticated"); 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_deauthenticate_indication( 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta, le_to_host16(mgmt->u.deauth.reason_code)); 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_free_sta(hapd, sta); 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_beacon(struct hostapd_data *hapd, 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len, 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_frame_info *fi) 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) { 1506cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)", 1507cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (unsigned long) len); 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (void) ieee802_11_parse_elems(mgmt->u.beacon.variable, 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - (IEEE80211_HDRLEN + 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.beacon)), &elems, 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1522fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int hostapd_sa_query_action(struct hostapd_data *hapd, 1523fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 1524fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt size_t len) 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end; 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = mgmt->u.action.u.sa_query_resp.trans_id + 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_SA_QUERY_TR_ID_LEN; 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (((u8 *) mgmt) + len < end) { 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action " 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame (len=%lu)", (unsigned long) len); 1533fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ieee802_11_sa_query_action(hapd, mgmt->sa, 15371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.sa_query_resp.action, 15381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.sa_query_resp.trans_id); 1539fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int robust_action_frame(u8 category) 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return category != WLAN_ACTION_PUBLIC && 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt category != WLAN_ACTION_HT; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1551fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtstatic int handle_action(struct hostapd_data *hapd, 1552fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 15551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + 1) { 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handle_action - too short payload (len=%lu)", 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 1562fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1565a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (mgmt->u.action.category != WLAN_ACTION_PUBLIC && 1566a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) { 1567a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action " 1568a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "frame (category=%u) from unassociated STA " MACSTR, 1569a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt MAC2STR(mgmt->sa), mgmt->u.action.category); 1570fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 1571a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt } 1572a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_MFP) && 15751846323989242844f0e857458a8939fa5836429cDmitry Shmidt !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) && 15761846323989242844f0e857458a8939fa5836429cDmitry Shmidt robust_action_frame(mgmt->u.action.category)) { 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Dropped unprotected Robust Action frame from " 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "an MFP STA"); 1581fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (mgmt->u.action.category) { 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_FT: 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - IEEE80211_HDRLEN)) 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1591fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_WMM: 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_wmm_action(hapd, mgmt, len); 1595fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_SA_QUERY: 1598fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return hostapd_sa_query_action(hapd, mgmt, len); 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 1600a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_WNM 1601a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt case WLAN_ACTION_WNM: 1602fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ieee802_11_rx_wnm_action_ap(hapd, mgmt, len); 1603fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 1604a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_WNM */ 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_PUBLIC: 16061846323989242844f0e857458a8939fa5836429cDmitry Shmidt case WLAN_ACTION_PROTECTED_DUAL: 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->public_action_cb) { 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->public_action_cb(hapd->public_action_cb_ctx, 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) mgmt, len, 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->freq); 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16124b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (hapd->public_action_cb2) { 1613f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt hapd->public_action_cb2(hapd->public_action_cb2_ctx, 16144b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt (u8 *) mgmt, len, 16154b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt hapd->iface->freq); 16164b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt } 16174b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt if (hapd->public_action_cb || hapd->public_action_cb2) 1618fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_VENDOR_SPECIFIC: 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->vendor_action_cb) { 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx, 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) mgmt, len, 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->freq) == 0) 1625fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handle_action - unknown action category %d or invalid " 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame", 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.action.category); 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) && 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(mgmt->sa[0] & 0x01)) { 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11-REVma/D9.0 - 7.3.1.11 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return the Action frame to the source without change 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * except that MSB of the Category set to 1. 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action " 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame back to sender"); 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = os_malloc(len); 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 1648fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp, mgmt, len); 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, resp->sa, ETH_ALEN); 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.action.category |= 0x80; 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 165561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) { 165661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send " 165761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Action frame"); 165861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(resp); 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1661fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1662fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_11_mgmt - process incoming IEEE 802.11 management frames 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data structure (the BSS to which the management frame was 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sent to) 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: management frame data (starting from IEEE 802.11 header) 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: length of frame data in octets 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @fi: meta data about received frame (signal level, etc.) 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Process all incoming IEEE 802.11 management frames. This will be called for 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * each frame received from the kernel driver through wlan#ap interface. In 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, it can be called to re-inserted pending frames (e.g., when using 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * external RADIUS server as an MAC ACL). 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1679fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidtint ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, 1680fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt struct hostapd_frame_info *fi) 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *mgmt; 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int broadcast; 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 fc, stype; 1685fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt int ret = 0; 1686fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1687fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 1688fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (hapd->ext_mgmt_frame_handling) { 1689fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt size_t hex_len = 2 * len + 1; 1690fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt char *hex = os_malloc(hex_len); 1691fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (hex) { 1692fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_snprintf_hex(hex, hex_len, buf, len); 1693fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex); 1694fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_free(hex); 1695fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1696fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 1697fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 1698fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 24) 1701fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt = (struct ieee80211_mgmt *) buf; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc = le_to_host16(mgmt->frame_control); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt stype = WLAN_FC_GET_STYPE(fc); 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (stype == WLAN_FC_STYPE_BEACON) { 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_beacon(hapd, mgmt, len, fi); 1709fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff && 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff && 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff; 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!broadcast && 17171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 17181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Invitation responses can be sent with the peer MAC as BSSID */ 17191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !((hapd->conf->p2p & P2P_GROUP_OWNER) && 17201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt stype == WLAN_FC_STYPE_ACTION) && 17211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) { 1723cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address", 1724cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->bssid)); 1725fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (stype == WLAN_FC_STYPE_PROBE_REQ) { 173004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt handle_probe_req(hapd, mgmt, len, fi->ssi_signal); 1731fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 1; 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) { 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MGMT: DA=" MACSTR " not our address", 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->da)); 1739fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return 0; 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (stype) { 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_AUTH: 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::auth"); 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth(hapd, mgmt, len); 1746fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = 1; 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ASSOC_REQ: 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc(hapd, mgmt, len, 0); 1751fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = 1; 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_REASSOC_REQ: 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc(hapd, mgmt, len, 1); 1756fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = 1; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DISASSOC: 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::disassoc"); 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_disassoc(hapd, mgmt, len); 1761fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = 1; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DEAUTH: 17641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth"); 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_deauth(hapd, mgmt, len); 1766fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = 1; 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ACTION: 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::action"); 1770fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt ret = handle_action(hapd, mgmt, len); 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown mgmt frame subtype %d", stype); 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1778fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 1779fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return ret; 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth_cb(struct hostapd_data *hapd, 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int ok) 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, auth_transaction, status_code; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_NOTICE, 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "did not acknowledge authentication response"); 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 1798cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)", 1799cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt (unsigned long) len); 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code = le_to_host16(mgmt->u.auth.status_code); 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 1809cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_auth_cb: STA " MACSTR " not found", 1810cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->da)); 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_SUCCESS && 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) || 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) { 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "authenticated"); 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1824c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtstatic void hostapd_set_wds_encryption(struct hostapd_data *hapd, 1825c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt struct sta_info *sta, 1826c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt char *ifname_wds) 1827c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt{ 1828c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int i; 1829c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt struct hostapd_ssid *ssid = sta->ssid; 1830c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1831c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (hapd->conf->ieee802_1x || hapd->conf->wpa) 1832c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt return; 1833c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1834c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt for (i = 0; i < 4; i++) { 1835c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (ssid->wep.key[i] && 1836c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i, 1837c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt i == ssid->wep.idx, NULL, 0, 1838c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ssid->wep.key[i], ssid->wep.len[i])) { 1839c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt wpa_printf(MSG_WARNING, 1840c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt "Could not set WEP keys for WDS interface; %s", 1841c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ifname_wds); 1842c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt break; 1843c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 1844c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 1845c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt} 1846c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1847c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_assoc_cb(struct hostapd_data *hapd, 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int reassoc, int ok) 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 status; 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int new_assoc = 1; 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_ht_capabilities ht_cap; 1856a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt struct ieee80211_vht_capabilities vht_cap; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) : 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.assoc_resp))) { 1860cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)", 1861cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt reassoc, (unsigned long) len); 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 1867cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found", 1868cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt MAC2STR(mgmt->da)); 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1872aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!ok) { 1873aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 1874aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 1875aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "did not acknowledge association response"); 1876aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt sta->flags &= ~WLAN_STA_ASSOC_REQ_OK; 1877aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt return; 1878aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 1879aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 1880aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (reassoc) 1881aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt status = le_to_host16(mgmt->u.reassoc_resp.status_code); 1882aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt else 1883aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt status = le_to_host16(mgmt->u.assoc_resp.status_code); 1884aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != WLAN_STATUS_SUCCESS) 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Stop previous accounting session, if one is started, and allocate 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new session id for the new session. */ 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_stop(hapd, sta); 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associated (aid %d)", 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->aid); 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_ASSOC) 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt new_assoc = 0; 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_ASSOC; 1900fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE; 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg == WLAN_AUTH_FT) { 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Open, static WEP, or FT protocol; no separate authorization 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * step. 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_reassociate_indication(hapd, sta); 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_associate_indication(hapd, sta); 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->sa_query_timed_out = 0; 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove the STA entry in order to make sure the STA PS state gets 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cleared and configuration gets updated in case of reassociation back 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the same AP. 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_remove(hapd, sta->addr); 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_HT) 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap); 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 1930a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_IEEE80211AC 1931a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt if (sta->flags & WLAN_STA_VHT) 1932a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap); 1933a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_IEEE80211AC */ 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability, 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->supported_rates, sta->supported_rates_len, 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->listen_interval, 19381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags & WLAN_STA_HT ? &ht_cap : NULL, 1939a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt sta->flags & WLAN_STA_VHT ? &vht_cap : NULL, 19401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags, sta->qosinfo)) { 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_NOTICE, 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Could not add STA to kernel driver"); 19441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_disconnect(hapd, sta, sta->addr, 19461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_REASON_DISASSOC_AP_BUSY); 19471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 19481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto fail; 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1951c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (sta->flags & WLAN_STA_WDS) { 1952c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int ret; 1953c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt char ifname_wds[IFNAMSIZ + 1]; 1954c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 1955c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr, 1956c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt sta->aid, 1); 1957c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!ret) 1958c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt hostapd_set_wds_encryption(hapd, sta, ifname_wds); 1959c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt } 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm == NULL) { 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This STA does not use RADIUS server for EAP authentication, 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so bind it to the selected VLAN interface now, since the 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface selection is not going to change anymore. 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sta->vlan_id) { 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */ 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_sta_flags(hapd, sta); 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg == WLAN_AUTH_FT) 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb(hapd, sta, !new_assoc); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Copy of the association request is not needed anymore */ 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) { 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->last_assoc_req); 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->last_assoc_req = NULL; 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void handle_deauth_cb(struct hostapd_data *hapd, 19951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct ieee80211_mgmt *mgmt, 19961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int ok) 19971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 19981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 19991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (mgmt->da[0] & 0x01) 20001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 20011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 20021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!sta) { 20031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR 20041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " not found", MAC2STR(mgmt->da)); 20051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 20061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ok) 20081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth", 20091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sta->addr)); 20101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 20111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge " 20121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "deauth", MAC2STR(sta->addr)); 20131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_deauth_cb(hapd, sta); 20151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 20161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void handle_disassoc_cb(struct hostapd_data *hapd, 20191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct ieee80211_mgmt *mgmt, 20201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int ok) 20211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 20221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 20231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (mgmt->da[0] & 0x01) 20241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 20251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 20261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!sta) { 20271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR 20281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " not found", MAC2STR(mgmt->da)); 20291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 20301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 20311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ok) 20321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc", 20331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sta->addr)); 20341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 20351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge " 20361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "disassoc", MAC2STR(sta->addr)); 20371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_disassoc_cb(hapd, sta); 20391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 20401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_11_mgmt_cb - Process management frame TX status callback 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data structure (the BSS from which the management frame 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * was sent from) 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: management frame data (starting from IEEE 802.11 header) 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: length of frame data in octets 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @stype: management frame subtype from frame control field 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ok: Whether the frame was ACK'ed 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 stype, int ok) 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt; 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt = (const struct ieee80211_mgmt *) buf; 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2057fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 2058fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (hapd->ext_mgmt_frame_handling) { 2059fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d", 2060fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt stype, ok); 2061fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return; 2062fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } 2063fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 2064fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (stype) { 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_AUTH: 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::auth cb"); 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth_cb(hapd, mgmt, len, ok); 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ASSOC_RESP: 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb"); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc_cb(hapd, mgmt, len, 0, ok); 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_REASSOC_RESP: 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb"); 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc_cb(hapd, mgmt, len, 1, ok); 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_PROBE_RESP: 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb"); 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DEAUTH: 20821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::deauth cb"); 20831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt handle_deauth_cb(hapd, mgmt, len, ok); 20841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 20851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_STYPE_DISASSOC: 20861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::disassoc cb"); 20871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt handle_disassoc_cb(hapd, mgmt, len, ok); 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ACTION: 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::action cb"); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2093cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype); 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len, int ack) 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *iface = hapd->iface; 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2130c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_PENDING_POLL) { 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending " 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "activity poll", MAC2STR(sta->addr), 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ack ? "ACKed" : "did not ACK"); 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ack) 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_PENDING_POLL; 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_tx_status(hapd, sta, buf, len, ack); 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst, 21451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *data, size_t len, int ack) 21461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 21471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 21481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 21491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, dst); 21511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 21521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t j; 21531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 21541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd = iface->bss[j]; 21551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, dst); 21561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta) 21571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 21581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2160c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 2161c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA " 2162c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt MACSTR " that is not currently associated", 2163c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt MAC2STR(dst)); 21641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 2165c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 21661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack); 21681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 21691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr) 21721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 21731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 21741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 21751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, addr); 21771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 21781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t j; 21791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 21801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd = iface->bss[j]; 21811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, addr); 21821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta) 21831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 21841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 21861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL) 21871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 21881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!(sta->flags & WLAN_STA_PENDING_POLL)) 21891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 21901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending " 21921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "activity poll", MAC2STR(sta->addr)); 21931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags &= ~WLAN_STA_PENDING_POLL; 21941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 21951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wds) 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, src); 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_ASSOC)) { 2204aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!hapd->conf->wds_sta) 2205aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt return; 2206aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wds && !(sta->flags & WLAN_STA_WDS)) { 2208c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt int ret; 2209c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt char ifname_wds[IFNAMSIZ + 1]; 2210c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for " 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "STA " MACSTR " (aid %u)", 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr), sta->aid); 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_WDS; 2215c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ret = hostapd_set_wds_sta(hapd, ifname_wds, 2216c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt sta->addr, sta->aid, 1); 2217c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt if (!ret) 2218c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt hostapd_set_wds_encryption(hapd, sta, 2219c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt ifname_wds); 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA " 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(src)); 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (src[0] & 0x01) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Broadcast bit set in SA?! Ignore the frame silently. */ 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) { 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Association Response to the STA has " 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already been sent, but no TX status yet known - " 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore Class 3 frame issue with " MACSTR, 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(src)); 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_AUTH)) 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_disassoc( 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, src, 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth( 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, src, 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 2251