18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / IEEE 802.11 Management 3c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Copyright (c) 2002-2012, 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" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wmm.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_mlme.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = eid; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, num, count; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates == NULL) 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SUPP_RATES; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = hapd->iface->num_rates; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num > 8) { 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* rest of the rates are encoded in Extended supported 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * rates element */ 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = 8; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = num; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0, count = 0; i < hapd->iface->num_rates && count < num; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = hapd->iface->current_rates[i].rate / 5; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos |= 0x80; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_rates < 8) 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = eid; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, num, count; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates == NULL) 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num = hapd->iface->num_rates; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num++; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num <= 8) 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num -= 8; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_EXT_SUPP_RATES; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = num; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i++) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count <= 8) 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* already in SuppRates IE */ 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = hapd->iface->current_rates[i].rate / 5; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos |= 0x80; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_rates >= 8) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int probe) 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int capab = WLAN_CAPABILITY_ESS; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int privacy; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_no_short_preamble == 0 && 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->preamble == SHORT_PREAMBLE) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = hapd->conf->ssid.wep.keys_set; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x && 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (hapd->conf->default_wep_key_len || 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->individual_wep_key_len)) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 1; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa) 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 1; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int policy, def_klen; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (probe && sta->ssid_probe) { 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt policy = sta->ssid_probe->security_policy; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt def_klen = sta->ssid_probe->wep.default_len; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt policy = sta->ssid->security_policy; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt def_klen = sta->ssid->wep.default_len; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = policy != SECURITY_PLAINTEXT; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (policy == SECURITY_IEEE_802_1X && def_klen == 0) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt privacy = 0; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (privacy) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_PRIVACY; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode && 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time == 0) 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return capab; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len) 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > HOSTAPD_MAX_SSID_LEN) 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = HOSTAPD_MAX_SSID_LEN; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < len; i++) { 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid[i] >= 32 && ssid[i] < 127) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = ssid[i]; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[i] = '.'; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[len] = '\0'; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta, 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_transaction, const u8 *challenge, 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int iswep) 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication (shared key, transaction %d)", 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_transaction == 1) { 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta->challenge) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate a pseudo-random challenge */ 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 key[8]; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int r; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->challenge == NULL) 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_random(); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, &now.sec, 4); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key + 4, &r, 4); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(key, sizeof(key), 0, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge, WLAN_AUTH_CHALLENGE_LEN); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_transaction != 3) 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Transaction 3 */ 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iswep || !sta->challenge || !challenge || 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) { 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "shared key authentication - invalid " 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "challenge-response"); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_CHALLENGE_FAIL; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication OK (shared key)"); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE80211_REQUIRE_AUTH_ACK 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Station will be marked authenticated if it ACKs the 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication reply. */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->challenge); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->challenge = NULL; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_auth_reply(struct hostapd_data *hapd, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *dst, const u8 *bssid, 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, u16 auth_transaction, u16 resp, 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *reply; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(rlen); 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = (struct ieee80211_mgmt *) buf; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_AUTH); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->da, dst, ETH_ALEN); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->bssid, bssid, ETH_ALEN); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.auth_alg = host_to_le16(auth_alg); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.auth_transaction = host_to_le16(auth_transaction); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.auth.status_code = host_to_le16(resp); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies && ies_len) 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->u.auth.variable, ies, ies_len); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)", 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(dst), auth_alg, auth_transaction, 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp, (unsigned long) ies_len); 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("send_auth_reply: send"); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid, 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_transaction, u16 status, 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction, 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status, ies, ies_len); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != WLAN_STATUS_SUCCESS) 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, dst); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211, 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)"); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth(struct hostapd_data *hapd, 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, auth_transaction, status_code; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp = WLAN_STATUS_SUCCESS; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = NULL; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 fc; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *challenge = NULL; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 session_timeout, acct_interim_interval; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vlan_id = 0; 3101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 psk[PMK_LEN]; 3111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int has_psk = 0; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t resp_ies_len = 0; 31461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *identity = NULL; 31561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *radius_cui = NULL; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_auth - too short payload (len=%lu)\n", 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code = le_to_host16(mgmt->u.auth.status_code); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc = le_to_host16(mgmt->frame_control); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2 + WLAN_AUTH_CHALLENGE_LEN && 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE && 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN) 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge = &mgmt->u.auth.variable[2]; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d " 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "auth_transaction=%d status_code=%d wep=%d%s", 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), auth_alg, auth_transaction, 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code, !!(fc & WLAN_FC_ISWEP), 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt challenge ? " challenge" : ""); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) && 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_OPEN) || 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) && 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_FT) || 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) && 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg == WLAN_AUTH_SHARED_KEY))) { 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unsupported authentication algorithm (%d)\n", 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(auth_transaction == 1 || 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Unknown authentication transaction number (%d)\n", 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) { 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Station " MACSTR " not allowed to authenticate.\n", 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len, 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &session_timeout, 3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &acct_interim_interval, &vlan_id, 37761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt psk, &has_psk, &identity, &radius_cui); 3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_REJECT) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Station " MACSTR " not allowed to authenticate.\n", 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_PENDING) { 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " waiting for an external authentication", 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Authentication code will re-send the authentication frame 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * after it has received (and cached) information from the 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * external source. */ 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_sta_add(hapd, mgmt->sa); 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vlan_id > 0) { 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_vlan_id_ifname(hapd->conf->vlan, 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_id) == NULL) { 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Invalid VLAN ID " 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d received from RADIUS server", 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_id); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->vlan_id = vlan_id; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS, 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (has_psk && hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) { 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(sta->psk); 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->psk = os_malloc(PMK_LEN); 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta->psk) 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(sta->psk, psk, PMK_LEN); 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(sta->psk); 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->psk = NULL; 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 42661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->identity = identity; 42761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt identity = NULL; 42861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->radius_cui = radius_cui; 42961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt radius_cui = NULL; 43061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_PREAUTH; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_pre_auth(sta->eapol_sm, 0); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval) 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_interim_interval = acct_interim_interval; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_session_timeout(hapd, sta, session_timeout); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_no_session_timeout(hapd, sta); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (auth_alg) { 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_OPEN: 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "authentication OK (open system)"); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE80211_REQUIRE_AUTH_ACK 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Station will be marked authenticated if it ACKs the 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication reply. */ 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_OPEN; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_SHARED_KEY: 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = auth_shared_key(hapd, sta, auth_transaction, challenge, 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc & WLAN_FC_ISWEP); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_SHARED_KEY; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_authenticate_indication(hapd, sta); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->challenge && auth_transaction == 1) { 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies[0] = WLAN_EID_CHALLENGE; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp_ies + 2, sta->challenge, 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_AUTH_CHALLENGE_LEN); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_FT: 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg = WLAN_AUTH_FT; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->addr); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) { 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA " 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine"); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid, 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction, mgmt->u.auth.variable, 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - IEEE80211_HDRLEN - 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.auth), 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth_ft_finish, hapd); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* handle_auth_ft_finish() callback will complete auth. */ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 49261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(identity); 49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(radius_cui); 49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg, 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction + 1, resp, resp_ies, resp_ies_len); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta) 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, j = 32, aid; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* get a unique AID */ 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->aid > 0) { 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " old AID %d", sta->aid); 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < AID_WORDS; i++) { 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->sta_aid[i] == (u32) -1) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < 32; j++) { 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(hapd->sta_aid[i] & BIT(j))) 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j < 32) 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j == 32) 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aid = i * 32 + j + 1; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aid > 2007) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->aid = aid; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->sta_aid[i] |= BIT(j); 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, " new AID %d", sta->aid); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta, 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid_ie, size_t ssid_ie_len) 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_ie == NULL) 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_ie_len != hapd->conf->ssid.ssid_len || 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) { 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ssid_txt[33]; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Station tried to associate with unknown SSID " 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", ssid_txt); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta, 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wmm_ie, size_t wmm_ie_len) 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_WMM; 5581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->qosinfo = 0; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wmm_ie && hapd->conf->wmm_enabled) { 5601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct wmm_information_element *wmm; 5611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) { 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_WPA, 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "invalid WMM element in association " 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "request"); 5681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 5691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 5701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 5711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags |= WLAN_STA_WMM; 5721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wmm = (struct wmm_information_element *) wmm_ie; 5731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->qosinfo = wmm->qos_info; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta, 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems *elems) 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!elems->supp_rates) { 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "No supported rates element in AssocReq"); 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elems->supp_rates_len + elems->ext_supp_rates_len > 59061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(sta->supported_rates)) { 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 59361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Invalid supported rates element length %d+%d", 59461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->supp_rates_len, 59561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->ext_supp_rates_len); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->supported_rates_len = merge_byte_arrays( 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sta->supported_rates, sizeof(sta->supported_rates), 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->supp_rates, elems->supp_rates_len, 60261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->ext_supp_rates, elems->ext_supp_rates_len); 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len, int reassoc) 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) { 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station sent an invalid " 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association request"); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len); 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = copy_supp_rates(hapd, sta, &elems); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities, 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ht_capabilities_len); 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & WLAN_STA_HT)) { 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station does not support " 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "mandatory HT PHY - reject association"); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_ASSOC_DENIED_NO_HT; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211AC 64761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities, 64861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems.vht_capabilities_len); 64961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 65061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return resp; 65161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && 65261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !(sta->flags & WLAN_STA_VHT)) { 65361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 65461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station does not support " 65561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "mandatory VHT PHY - reject association"); 65661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 65761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 65861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211AC */ 65961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) { 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = elems.rsn_ie; 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = elems.rsn_ie_len; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if ((hapd->conf->wpa & WPA_PROTO_WPA) && 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.wpa_ie) { 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = elems.wpa_ie; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = elems.wpa_ie_len; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = NULL; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = 0; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 6731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && elems.wps_ie) { 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association " 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request - assume WPS is used"); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_WPS; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sta->wps_ie); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_IE_VENDOR_TYPE); 6811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta->wps_ie && wps_is_20(sta->wps_ie)) { 6821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0"); 6831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags |= WLAN_STA_WPS2; 6841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = NULL; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len = 0; 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) { 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in " 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Re)Association Request - reject"); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_INVALID_IE; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->conf->wps_state && wpa_ie == NULL) { 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in " 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(Re)Association Request - possible WPS use"); 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_MAYBE_WPS; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && wpa_ie == NULL) { 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "No WPA/RSN IE in association request"); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_INVALID_IE; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && wpa_ie) { 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie -= 2; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie_len += 2; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->addr); 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->wpa_sm == NULL) { 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to initialize WPA " 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "state machine"); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie, wpa_ie_len, 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.mdie, elems.mdie_len); 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == WPA_INVALID_GROUP) 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_PAIRWISE) 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_AKMP) 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_AKMP_NOT_VALID; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_ALLOC_FAIL) 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_UNSPECIFIED_FAILURE; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res == WPA_INVALID_MDIE) 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_INVALID_MDIE; 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (res != WPA_IE_OK) 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_INVALID_IE; 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->sa_query_count > 0) 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_check_sa_query_timeout(hapd, sta); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out && 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) { 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * STA has already been associated with MFP and SA 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Query timeout has not been reached. Reject the 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association attempt temporarily and start SA Query, 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one is not pending. 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->sa_query_count == 0) 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_start_sa_query(hapd, sta); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_auth_uses_mfp(sta->wpa_sm)) 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_MFP; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_MFP; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg == WLAN_AUTH_FT) { 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!reassoc) { 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried " 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to use association (not " 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "re-association) with FT auth_alg", 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr)); 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_UNSPECIFIED_FAILURE; 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies, 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ies_len); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 78361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) && 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) { 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODULE_IEEE80211, 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Station tried to use TKIP with HT " 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association"); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_no_wpa(sta->wpa_sm); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.p2p) { 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sta->p2p_ie); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_IE_VENDOR_TYPE); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(sta->p2p_ie); 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->p2p_ie = NULL; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len); 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return WLAN_STATUS_SUCCESS; 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_deauth(struct hostapd_data *hapd, const u8 *addr, 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 reason_code) 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int send_len; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt reply; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&reply, 0, sizeof(reply)); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply.frame_control = 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.da, addr, ETH_ALEN); 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN); 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN); 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply.u.deauth.reason_code = host_to_le16(reason_code); 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0) 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to send deauth: %s", 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 status_code, int reassoc, const u8 *ies, 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ies_len) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int send_len; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[sizeof(struct ieee80211_mgmt) + 1024]; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *reply; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *p; 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(buf, 0, sizeof(buf)); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply = (struct ieee80211_mgmt *) buf; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->frame_control = 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt IEEE80211_FC(WLAN_FC_TYPE_MGMT, 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (reassoc ? WLAN_FC_STYPE_REASSOC_RESP : 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_ASSOC_RESP)); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->da, sta->addr, ETH_ALEN); 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN); 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = IEEE80211_HDRLEN; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len += sizeof(reply->u.assoc_resp); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.assoc_resp.capab_info = 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(hostapd_own_capab_info(hapd, sta, 0)); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.assoc_resp.status_code = host_to_le16(status_code); 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt | BIT(14) | BIT(15)); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supported rates */ 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extended supported rates */ 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ext_supp_rates(hapd, p); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_SUCCESS) { 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11r: Mobility Domain Information, Fast BSS 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Transition Information, RSN, [RIC Response] */ 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p, 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf + sizeof(buf) - p, 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg, ies, ies_len); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_assoc_comeback_time(hapd, sta, p); 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ht_capabilities(hapd, p); 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ht_operation(hapd, p); 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 88761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_IEEE80211AC 88861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p = hostapd_eid_vht_capabilities(hapd, p); 88961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt p = hostapd_eid_vht_operation(hapd, p); 89061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_IEEE80211AC */ 89161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_ext_capab(hapd, p); 89304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt p = hostapd_eid_bss_max_idle_period(hapd, p); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_WMM) 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_wmm(hapd, p); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 8991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if ((sta->flags & WLAN_STA_WPS) || 9001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) { 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps = wps_build_assoc_resp_ie(); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps) { 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps)); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p += wpabuf_len(wps); 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps); 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie) { 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *p2p_resp_ie; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum p2p_status_code status; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status_code) { 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_STATUS_SUCCESS: 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_SUCCESS; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA: 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_LIMIT_REACHED; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = P2P_SC_FAIL_INVALID_PARAMS; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status); 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_resp_ie) { 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(p, wpabuf_head(p2p_resp_ie), 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(p2p_resp_ie)); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p += wpabuf_len(p2p_resp_ie); 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(p2p_resp_ie); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->p2p & P2P_MANAGE) 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = hostapd_eid_p2p_manage(hapd, p); 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len += p - reply->u.assoc_resp.variable; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to send assoc resp: %s", 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt strerror(errno)); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_assoc(struct hostapd_data *hapd, 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len, 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 capab_info, listen_interval; 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 resp = WLAN_STATUS_SUCCESS; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int left, i; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.assoc_req))) { 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)" 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n", reassoc, (unsigned long) len); 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval = le_to_host16( 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.reassoc_req.listen_interval); 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " capab_info=0x%02x listen_interval=%d current_ap=" 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), capab_info, listen_interval, 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->u.reassoc_req.current_ap)); 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = mgmt->u.reassoc_req.variable; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab_info = le_to_host16(mgmt->u.assoc_req.capab_info); 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval = le_to_host16( 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.assoc_req.listen_interval); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " capab_info=0x%02x listen_interval=%d", 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), capab_info, listen_interval); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = mgmt->u.assoc_req.variable; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && sta->auth_alg == WLAN_AUTH_FT && 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sta->flags & WLAN_STA_AUTH) == 0) { 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate " 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "prior to authentication since it is using " 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over-the-DS FT", MAC2STR(mgmt->sa)); 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) { 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "Station tried to " 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associate before authentication " 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(aid=%d flags=0x%x)", 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta ? sta->aid : -1, 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta ? sta->flags : 0); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_deauth(hapd, mgmt->sa, 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA); 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_REASON_MICHAEL_MIC_FAILURE; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (listen_interval > hapd->conf->max_listen_interval) { 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Too large Listen Interval (%d)", 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt listen_interval); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* followed by SSID and Supported rates; and HT capabilities if 802.11n 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is used */ 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = check_assoc_ies(hapd, sta, pos, left, reassoc); 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp != WLAN_STATUS_SUCCESS) 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_aid(hapd, sta) < 0) { 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "No room for more AIDs"); 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->capability = capab_info; 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->listen_interval = listen_interval; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_NONERP; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < sta->supported_rates_len; i++) { 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->supported_rates[i] & 0x7f) > 22) { 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_NONERP; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->nonerp_set = 1; 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_non_erp++; 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_non_erp == 1) 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) && 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sta->no_short_slot_time_set) { 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_short_slot_time_set = 1; 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time++; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_MODE_IEEE80211G && 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_slot_time == 1) 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_SHORT_PREAMBLE; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !sta->no_short_preamble_set) { 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_short_preamble_set = 1; 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->num_sta_no_short_preamble++; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt && hapd->iface->num_sta_no_short_preamble == 1) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacons(hapd->iface); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt update_ht_state(hapd, sta); 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "association OK (aid %d)", sta->aid); 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Station will be marked associated, after it acknowledges AssocResp 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_ASSOC_REQ_OK; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) { 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out " 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SA Query procedure", reassoc ? "re" : ""); 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: Send a protected Disassociate frame to the STA using 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the old key and Reason Code "Previous Authentication no 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * longer valid". Make sure this is only sent protected since 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * unprotected frame would be received by the STA that is now 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * trying to associate. 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap, 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->last_assoc_req); 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->last_assoc_req = os_malloc(len); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sta->last_assoc_req, mgmt, len); 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure that the previously registered inactivity timer will not 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * remove the STA immediately. */ 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next = STA_NULLFUNC; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_assoc_resp(hapd, sta, resp, reassoc, pos, left); 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_disassoc(struct hostapd_data *hapd, 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) { 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_disassoc - too short payload (len=%lu)\n", 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt le_to_host16(mgmt->u.disassoc.reason_code)); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) { 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("Station " MACSTR " trying to disassociate, but it " 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "is not associated.\n", MAC2STR(mgmt->sa)); 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_set_authorized(hapd, sta, 0); 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC); 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "disassociated"); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Stop Accounting and IEEE 802.1X sessions, but leave the STA 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authenticated. */ 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_stop(hapd, sta); 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_free_station(sta); 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_remove(hapd, sta->addr); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->timeout_next == STA_NULLFUNC || 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next == STA_DISASSOC) { 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->timeout_next = STA_DEAUTH; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta); 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_disassociate_indication( 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code)); 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_deauth(struct hostapd_data *hapd, 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) { 11751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short " 11761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "payload (len=%lu)", (unsigned long) len); 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " reason_code=%d", 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL) { 11861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " 11871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "to deauthenticate, but it is not authenticated", 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_set_authorized(hapd, sta, 0); 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STA_ASSOC_REQ_OK); 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, "deauthenticated"); 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_deauthenticate_indication( 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, sta, le_to_host16(mgmt->u.deauth.reason_code)); 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_free_sta(hapd, sta); 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_beacon(struct hostapd_data *hapd, 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len, 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_frame_info *fi) 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) { 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_beacon - too short payload (len=%lu)\n", 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (void) ieee802_11_parse_elems(mgmt->u.beacon.variable, 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - (IEEE80211_HDRLEN + 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.beacon)), &elems, 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0); 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_process_beacon(hapd->iface, mgmt, &elems, fi); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_sa_query_action(struct hostapd_data *hapd, 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = mgmt->u.action.u.sa_query_resp.trans_id + 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_SA_QUERY_TR_ID_LEN; 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (((u8 *) mgmt) + len < end) { 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action " 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame (len=%lu)", (unsigned long) len); 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ieee802_11_sa_query_action(hapd, mgmt->sa, 12441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.sa_query_resp.action, 12451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt mgmt->u.action.u.sa_query_resp.trans_id); 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int robust_action_frame(u8 category) 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return category != WLAN_ACTION_PUBLIC && 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt category != WLAN_ACTION_HT; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_action(struct hostapd_data *hapd, 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R) 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 12621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 12631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_IEEE80211W || CONFIG_IEEE80211R */ 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + 1) { 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handle_action - too short payload (len=%lu)", 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_MFP) && 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP) && 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt robust_action_frame(mgmt->u.action.category))) { 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Dropped unprotected Robust Action frame from " 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "an MFP STA"); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (mgmt->u.action.category) { 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_FT: 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action " 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame from unassociated STA " MACSTR, 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len - IEEE80211_HDRLEN)) 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_WMM: 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_wmm_action(hapd, mgmt, len); 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_SA_QUERY: 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_sa_query_action(hapd, mgmt, len); 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_PUBLIC: 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->public_action_cb) { 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->public_action_cb(hapd->public_action_cb_ctx, 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) mgmt, len, 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->freq); 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_ACTION_VENDOR_SPECIFIC: 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->vendor_action_cb) { 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx, 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) mgmt, len, 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->freq) == 0) 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "handle_action - unknown action category %d or invalid " 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame", 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->u.action.category); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) && 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(mgmt->sa[0] & 0x01)) { 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11-REVma/D9.0 - 7.3.1.11 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Return the Action frame to the source without change 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * except that MSB of the Category set to 1. 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action " 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "frame back to sender"); 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = os_malloc(len); 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp, mgmt, len); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, resp->sa, ETH_ALEN); 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.action.category |= 0x80; 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 135461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) { 135561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send " 135661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "Action frame"); 135761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(resp); 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_11_mgmt - process incoming IEEE 802.11 management frames 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data structure (the BSS to which the management frame was 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sent to) 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: management frame data (starting from IEEE 802.11 header) 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: length of frame data in octets 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @fi: meta data about received frame (signal level, etc.) 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Process all incoming IEEE 802.11 management frames. This will be called for 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * each frame received from the kernel driver through wlan#ap interface. In 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, it can be called to re-inserted pending frames (e.g., when using 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * external RADIUS server as an MAC ACL). 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len, 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_frame_info *fi) 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *mgmt; 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int broadcast; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 fc, stype; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 24) 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt = (struct ieee80211_mgmt *) buf; 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fc = le_to_host16(mgmt->frame_control); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt stype = WLAN_FC_GET_STYPE(fc); 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (stype == WLAN_FC_STYPE_BEACON) { 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_beacon(hapd, mgmt, len, fi); 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff && 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff && 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!broadcast && 14001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_P2P 14011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Invitation responses can be sent with the peer MAC as BSSID */ 14021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt !((hapd->conf->p2p & P2P_GROUP_OWNER) && 14031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt stype == WLAN_FC_STYPE_ACTION) && 14041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_P2P */ 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) { 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("MGMT: BSSID=" MACSTR " not our address\n", 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->bssid)); 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (stype == WLAN_FC_STYPE_PROBE_REQ) { 141304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt handle_probe_req(hapd, mgmt, len, fi->ssi_signal); 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) { 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MGMT: DA=" MACSTR " not our address", 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->da)); 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (stype) { 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_AUTH: 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::auth"); 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth(hapd, mgmt, len); 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ASSOC_REQ: 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::assoc_req"); 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc(hapd, mgmt, len, 0); 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_REASSOC_REQ: 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::reassoc_req"); 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc(hapd, mgmt, len, 1); 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DISASSOC: 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::disassoc"); 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_disassoc(hapd, mgmt, len); 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DEAUTH: 14431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth"); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_deauth(hapd, mgmt, len); 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ACTION: 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::action"); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_action(hapd, mgmt, len); 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211, 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unknown mgmt frame subtype %d", stype); 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_auth_cb(struct hostapd_data *hapd, 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int ok) 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 auth_alg, auth_transaction, status_code; 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ok) { 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_NOTICE, 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "did not acknowledge authentication response"); 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_auth_cb - too short payload (len=%lu)\n", 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_alg = le_to_host16(mgmt->u.auth.auth_alg); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction); 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status_code = le_to_host16(mgmt->u.auth.status_code); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_auth_cb: STA " MACSTR " not found\n", 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->da)); 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status_code == WLAN_STATUS_SUCCESS && 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) || 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) { 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, "authenticated"); 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_AUTH; 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_assoc_cb(struct hostapd_data *hapd, 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, int reassoc, int ok) 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 status; 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int new_assoc = 1; 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_ht_capabilities ht_cap; 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) : 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(mgmt->u.assoc_resp))) { 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_assoc_cb(reassoc=%d) - too short payload " 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)\n", reassoc, (unsigned long) len); 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sta) { 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("handle_assoc_cb: STA " MACSTR " not found\n", 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->da)); 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1523aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!ok) { 1524aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211, 1525aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt HOSTAPD_LEVEL_DEBUG, 1526aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt "did not acknowledge association response"); 1527aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt sta->flags &= ~WLAN_STA_ASSOC_REQ_OK; 1528aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt return; 1529aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt } 1530aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 1531aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (reassoc) 1532aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt status = le_to_host16(mgmt->u.reassoc_resp.status_code); 1533aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt else 1534aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt status = le_to_host16(mgmt->u.assoc_resp.status_code); 1535aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != WLAN_STATUS_SUCCESS) 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Stop previous accounting session, if one is started, and allocate 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new session id for the new session. */ 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_stop(hapd, sta); 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_INFO, 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "associated (aid %d)", 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->aid); 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_ASSOC) 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt new_assoc = 0; 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_ASSOC; 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->auth_alg == WLAN_AUTH_FT) { 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Open, static WEP, or FT protocol; no separate authorization 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * step. 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_reassociate_indication(hapd, sta); 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mlme_associate_indication(hapd, sta); 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->sa_query_timed_out = 0; 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Remove the STA entry in order to make sure the STA PS state gets 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cleared and configuration gets updated in case of reassociation back 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to the same AP. 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_remove(hapd, sta->addr); 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_HT) 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap); 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability, 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->supported_rates, sta->supported_rates_len, 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->listen_interval, 15841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags & WLAN_STA_HT ? &ht_cap : NULL, 15851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags, sta->qosinfo)) { 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_NOTICE, 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Could not add STA to kernel driver"); 15891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_disconnect(hapd, sta, sta->addr, 15911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WLAN_REASON_DISASSOC_AP_BUSY); 15921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 15931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto fail; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_WDS) 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1); 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->eapol_sm == NULL) { 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This STA does not use RADIUS server for EAP authentication, 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so bind it to the selected VLAN interface now, since the 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface selection is not going to change anymore. 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (sta->vlan_id) { 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */ 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ap_sta_bind_vlan(hapd, sta, 0) < 0) 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_sta_flags(hapd, sta); 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg == WLAN_AUTH_FT) 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT); 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC); 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb(hapd, sta, !new_assoc); 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_notify_port_enabled(sta->eapol_sm, 1); 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fail: 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Copy of the association request is not needed anymore */ 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->last_assoc_req) { 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(sta->last_assoc_req); 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->last_assoc_req = NULL; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void handle_deauth_cb(struct hostapd_data *hapd, 16331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct ieee80211_mgmt *mgmt, 16341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int ok) 16351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 16361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 16371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (mgmt->da[0] & 0x01) 16381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 16391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 16401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!sta) { 16411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR 16421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " not found", MAC2STR(mgmt->da)); 16431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 16441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 16451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ok) 16461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth", 16471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sta->addr)); 16481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 16491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge " 16501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "deauth", MAC2STR(sta->addr)); 16511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_deauth_cb(hapd, sta); 16531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 16541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void handle_disassoc_cb(struct hostapd_data *hapd, 16571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const struct ieee80211_mgmt *mgmt, 16581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len, int ok) 16591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 16601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 16611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (mgmt->da[0] & 0x01) 16621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 16631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, mgmt->da); 16641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!sta) { 16651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR 16661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt " not found", MAC2STR(mgmt->da)); 16671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 16681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 16691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ok) 16701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc", 16711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt MAC2STR(sta->addr)); 16721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt else 16731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge " 16741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "disassoc", MAC2STR(sta->addr)); 16751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ap_sta_disassoc_cb(hapd, sta); 16771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 16781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_11_mgmt_cb - Process management frame TX status callback 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: hostapd BSS data structure (the BSS from which the management frame 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * was sent from) 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: management frame data (starting from IEEE 802.11 header) 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: length of frame data in octets 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @stype: management frame subtype from frame control field 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ok: Whether the frame was ACK'ed 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 stype, int ok) 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt; 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt = (const struct ieee80211_mgmt *) buf; 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (stype) { 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_AUTH: 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::auth cb"); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_auth_cb(hapd, mgmt, len, ok); 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ASSOC_RESP: 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb"); 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc_cb(hapd, mgmt, len, 0, ok); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_REASSOC_RESP: 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb"); 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt handle_assoc_cb(hapd, mgmt, len, 1, ok); 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_PROBE_RESP: 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb"); 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_DEAUTH: 17121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::deauth cb"); 17131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt handle_deauth_cb(hapd, mgmt, len, ok); 17141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 17151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_STYPE_DISASSOC: 17161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::disassoc cb"); 17171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt handle_disassoc_cb(hapd, mgmt, len, ok); 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_FC_STYPE_ACTION: 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "mgmt::action cb"); 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("unknown mgmt cb frame subtype %d\n", stype); 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen) 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len, int ack) 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *iface = hapd->iface; 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, addr); 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1760c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->flags & WLAN_STA_PENDING_POLL) { 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending " 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "activity poll", MAC2STR(sta->addr), 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ack ? "ACKed" : "did not ACK"); 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ack) 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags &= ~WLAN_STA_PENDING_POLL; 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_tx_status(hapd, sta, buf, len, ack); 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst, 17751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const u8 *data, size_t len, int ack) 17761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 17771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 17781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 17791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, dst); 17811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 17821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t j; 17831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 17841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd = iface->bss[j]; 17851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, dst); 17861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta) 17871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 17881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 17891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1790c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 1791c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA " 1792c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt MACSTR " that is not currently associated", 1793c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt MAC2STR(dst)); 17941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 1795c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt } 17961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 17971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack); 17981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 17991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr) 18021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 18031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct sta_info *sta; 18041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 18051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, addr); 18071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL && iface->num_bss > 1) { 18081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t j; 18091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 18101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd = iface->bss[j]; 18111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta = ap_get_sta(hapd, addr); 18121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta) 18131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 18141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 18161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (sta == NULL) 18171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!(sta->flags & WLAN_STA_PENDING_POLL)) 18191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return; 18201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending " 18221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "activity poll", MAC2STR(sta->addr)); 18231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt sta->flags &= ~WLAN_STA_PENDING_POLL; 18241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 18251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int wds) 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta; 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, src); 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_ASSOC)) { 1834aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt if (!hapd->conf->wds_sta) 1835aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt return; 1836aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wds && !(sta->flags & WLAN_STA_WDS)) { 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for " 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "STA " MACSTR " (aid %u)", 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(sta->addr), sta->aid); 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->flags |= WLAN_STA_WDS; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 1); 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA " 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(src)); 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (src[0] & 0x01) { 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Broadcast bit set in SA?! Ignore the frame silently. */ 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) { 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Association Response to the STA has " 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "already been sent, but no TX status yet known - " 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignore Class 3 frame issue with " MACSTR, 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(src)); 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta && (sta->flags & WLAN_STA_AUTH)) 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_disassoc( 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, src, 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth( 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, src, 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1874