LCOV - code coverage report
Current view: top level - ap - ieee802_11.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 882 1148 76.8 %
Date: 2014-10-09 Functions: 37 41 90.2 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / IEEE 802.11 Management
       3             :  * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #ifndef CONFIG_NATIVE_WINDOWS
      12             : 
      13             : #include "utils/common.h"
      14             : #include "utils/eloop.h"
      15             : #include "crypto/crypto.h"
      16             : #include "crypto/sha256.h"
      17             : #include "crypto/random.h"
      18             : #include "common/ieee802_11_defs.h"
      19             : #include "common/ieee802_11_common.h"
      20             : #include "common/wpa_ctrl.h"
      21             : #include "common/sae.h"
      22             : #include "radius/radius.h"
      23             : #include "radius/radius_client.h"
      24             : #include "p2p/p2p.h"
      25             : #include "wps/wps.h"
      26             : #include "hostapd.h"
      27             : #include "beacon.h"
      28             : #include "ieee802_11_auth.h"
      29             : #include "sta_info.h"
      30             : #include "ieee802_1x.h"
      31             : #include "wpa_auth.h"
      32             : #include "wmm.h"
      33             : #include "ap_list.h"
      34             : #include "accounting.h"
      35             : #include "ap_config.h"
      36             : #include "ap_mlme.h"
      37             : #include "p2p_hostapd.h"
      38             : #include "ap_drv_ops.h"
      39             : #include "wnm_ap.h"
      40             : #include "ieee802_11.h"
      41             : #include "dfs.h"
      42             : 
      43             : 
      44        3531 : u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
      45             : {
      46        3531 :         u8 *pos = eid;
      47             :         int i, num, count;
      48             : 
      49        3531 :         if (hapd->iface->current_rates == NULL)
      50           3 :                 return eid;
      51             : 
      52        3528 :         *pos++ = WLAN_EID_SUPP_RATES;
      53        3528 :         num = hapd->iface->num_rates;
      54        3528 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
      55          18 :                 num++;
      56        3528 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
      57           8 :                 num++;
      58        3528 :         if (num > 8) {
      59             :                 /* rest of the rates are encoded in Extended supported
      60             :                  * rates element */
      61        3449 :                 num = 8;
      62             :         }
      63             : 
      64        3528 :         *pos++ = num;
      65       35210 :         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
      66       28154 :              i++) {
      67       28154 :                 count++;
      68       28154 :                 *pos = hapd->iface->current_rates[i].rate / 5;
      69       28154 :                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
      70       14014 :                         *pos |= 0x80;
      71       28154 :                 pos++;
      72             :         }
      73             : 
      74        3528 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
      75           4 :                 count++;
      76           4 :                 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
      77             :         }
      78             : 
      79        3528 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
      80           3 :                 count++;
      81           3 :                 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
      82             :         }
      83             : 
      84        3528 :         return pos;
      85             : }
      86             : 
      87             : 
      88        3531 : u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
      89             : {
      90        3531 :         u8 *pos = eid;
      91             :         int i, num, count;
      92             : 
      93        3531 :         if (hapd->iface->current_rates == NULL)
      94           3 :                 return eid;
      95             : 
      96        3528 :         num = hapd->iface->num_rates;
      97        3528 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
      98          18 :                 num++;
      99        3528 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
     100           8 :                 num++;
     101        3528 :         if (num <= 8)
     102          79 :                 return eid;
     103        3449 :         num -= 8;
     104             : 
     105        3449 :         *pos++ = WLAN_EID_EXT_SUPP_RATES;
     106        3449 :         *pos++ = num;
     107       48266 :         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
     108       41368 :              i++) {
     109       41368 :                 count++;
     110       41368 :                 if (count <= 8)
     111       27592 :                         continue; /* already in SuppRates IE */
     112       13776 :                 *pos = hapd->iface->current_rates[i].rate / 5;
     113       13776 :                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
     114          12 :                         *pos |= 0x80;
     115       13776 :                 pos++;
     116             :         }
     117             : 
     118        3449 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
     119          14 :                 count++;
     120          14 :                 if (count > 8)
     121          14 :                         *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
     122             :         }
     123             : 
     124        3449 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
     125           5 :                 count++;
     126           5 :                 if (count > 8)
     127           5 :                         *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
     128             :         }
     129             : 
     130        3449 :         return pos;
     131             : }
     132             : 
     133             : 
     134        3531 : u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
     135             :                            int probe)
     136             : {
     137        3531 :         int capab = WLAN_CAPABILITY_ESS;
     138             :         int privacy;
     139             :         int dfs;
     140             : 
     141             :         /* Check if any of configured channels require DFS */
     142        3531 :         dfs = hostapd_is_dfs_required(hapd->iface);
     143        3531 :         if (dfs < 0) {
     144           0 :                 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
     145             :                            dfs);
     146           0 :                 dfs = 0;
     147             :         }
     148             : 
     149        7039 :         if (hapd->iface->num_sta_no_short_preamble == 0 &&
     150        3508 :             hapd->iconf->preamble == SHORT_PREAMBLE)
     151           3 :                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
     152             : 
     153        3531 :         privacy = hapd->conf->ssid.wep.keys_set;
     154             : 
     155        4926 :         if (hapd->conf->ieee802_1x &&
     156        2784 :             (hapd->conf->default_wep_key_len ||
     157        1389 :              hapd->conf->individual_wep_key_len))
     158           6 :                 privacy = 1;
     159             : 
     160        3531 :         if (hapd->conf->wpa)
     161        2607 :                 privacy = 1;
     162             : 
     163             : #ifdef CONFIG_HS20
     164        3531 :         if (hapd->conf->osen)
     165          10 :                 privacy = 1;
     166             : #endif /* CONFIG_HS20 */
     167             : 
     168        3531 :         if (sta) {
     169             :                 int policy, def_klen;
     170        1506 :                 if (probe && sta->ssid_probe) {
     171         196 :                         policy = sta->ssid_probe->security_policy;
     172         196 :                         def_klen = sta->ssid_probe->wep.default_len;
     173             :                 } else {
     174        1310 :                         policy = sta->ssid->security_policy;
     175        1310 :                         def_klen = sta->ssid->wep.default_len;
     176             :                 }
     177        1506 :                 privacy = policy != SECURITY_PLAINTEXT;
     178        1506 :                 if (policy == SECURITY_IEEE_802_1X && def_klen == 0)
     179           2 :                         privacy = 0;
     180             :         }
     181             : 
     182        3531 :         if (privacy)
     183        2628 :                 capab |= WLAN_CAPABILITY_PRIVACY;
     184             : 
     185        7062 :         if (hapd->iface->current_mode &&
     186        6982 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
     187        3451 :             hapd->iface->num_sta_no_short_slot_time == 0)
     188        3451 :                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
     189             : 
     190             :         /*
     191             :          * Currently, Spectrum Management capability bit is set when directly
     192             :          * requested in configuration by spectrum_mgmt_required or when AP is
     193             :          * running on DFS channel.
     194             :          * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
     195             :          */
     196        7062 :         if (hapd->iface->current_mode &&
     197        3597 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
     198         129 :             (hapd->iconf->spectrum_mgmt_required || dfs))
     199          16 :                 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
     200             : 
     201        3531 :         return capab;
     202             : }
     203             : 
     204             : 
     205           4 : static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
     206             :                            u16 auth_transaction, const u8 *challenge,
     207             :                            int iswep)
     208             : {
     209           4 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     210             :                        HOSTAPD_LEVEL_DEBUG,
     211             :                        "authentication (shared key, transaction %d)",
     212             :                        auth_transaction);
     213             : 
     214           4 :         if (auth_transaction == 1) {
     215           2 :                 if (!sta->challenge) {
     216             :                         /* Generate a pseudo-random challenge */
     217             :                         u8 key[8];
     218             :                         struct os_time now;
     219             :                         int r;
     220           2 :                         sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
     221           2 :                         if (sta->challenge == NULL)
     222           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     223             : 
     224           2 :                         os_get_time(&now);
     225           2 :                         r = os_random();
     226           2 :                         os_memcpy(key, &now.sec, 4);
     227           2 :                         os_memcpy(key + 4, &r, 4);
     228           2 :                         rc4_skip(key, sizeof(key), 0,
     229             :                                  sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
     230             :                 }
     231           2 :                 return 0;
     232             :         }
     233             : 
     234           2 :         if (auth_transaction != 3)
     235           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     236             : 
     237             :         /* Transaction 3 */
     238           4 :         if (!iswep || !sta->challenge || !challenge ||
     239           2 :             os_memcmp_const(sta->challenge, challenge,
     240             :                             WLAN_AUTH_CHALLENGE_LEN)) {
     241           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     242             :                                HOSTAPD_LEVEL_INFO,
     243             :                                "shared key authentication - invalid "
     244             :                                "challenge-response");
     245           0 :                 return WLAN_STATUS_CHALLENGE_FAIL;
     246             :         }
     247             : 
     248           2 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     249             :                        HOSTAPD_LEVEL_DEBUG,
     250             :                        "authentication OK (shared key)");
     251           2 :         sta->flags |= WLAN_STA_AUTH;
     252           2 :         wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
     253           2 :         os_free(sta->challenge);
     254           2 :         sta->challenge = NULL;
     255             : 
     256           2 :         return 0;
     257             : }
     258             : 
     259             : 
     260        1249 : static void send_auth_reply(struct hostapd_data *hapd,
     261             :                             const u8 *dst, const u8 *bssid,
     262             :                             u16 auth_alg, u16 auth_transaction, u16 resp,
     263             :                             const u8 *ies, size_t ies_len)
     264             : {
     265             :         struct ieee80211_mgmt *reply;
     266             :         u8 *buf;
     267             :         size_t rlen;
     268             : 
     269        1249 :         rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
     270        1249 :         buf = os_zalloc(rlen);
     271        1249 :         if (buf == NULL)
     272        1249 :                 return;
     273             : 
     274        1249 :         reply = (struct ieee80211_mgmt *) buf;
     275        1249 :         reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
     276             :                                             WLAN_FC_STYPE_AUTH);
     277        1249 :         os_memcpy(reply->da, dst, ETH_ALEN);
     278        1249 :         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
     279        1249 :         os_memcpy(reply->bssid, bssid, ETH_ALEN);
     280             : 
     281        1249 :         reply->u.auth.auth_alg = host_to_le16(auth_alg);
     282        1249 :         reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
     283        1249 :         reply->u.auth.status_code = host_to_le16(resp);
     284             : 
     285        1249 :         if (ies && ies_len)
     286         160 :                 os_memcpy(reply->u.auth.variable, ies, ies_len);
     287             : 
     288        8743 :         wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
     289             :                    " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
     290        7494 :                    MAC2STR(dst), auth_alg, auth_transaction,
     291             :                    resp, (unsigned long) ies_len);
     292        1249 :         if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
     293           0 :                 wpa_printf(MSG_INFO, "send_auth_reply: send");
     294             : 
     295        1249 :         os_free(buf);
     296             : }
     297             : 
     298             : 
     299             : #ifdef CONFIG_IEEE80211R
     300         113 : static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
     301             :                                   u16 auth_transaction, u16 status,
     302             :                                   const u8 *ies, size_t ies_len)
     303             : {
     304         113 :         struct hostapd_data *hapd = ctx;
     305             :         struct sta_info *sta;
     306             : 
     307         113 :         send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction,
     308             :                         status, ies, ies_len);
     309             : 
     310         113 :         if (status != WLAN_STATUS_SUCCESS)
     311           0 :                 return;
     312             : 
     313         113 :         sta = ap_get_sta(hapd, dst);
     314         113 :         if (sta == NULL)
     315           0 :                 return;
     316             : 
     317         113 :         hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
     318             :                        HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
     319         113 :         sta->flags |= WLAN_STA_AUTH;
     320         113 :         mlme_authenticate_indication(hapd, sta);
     321             : }
     322             : #endif /* CONFIG_IEEE80211R */
     323             : 
     324             : 
     325             : #ifdef CONFIG_SAE
     326             : 
     327          20 : static struct wpabuf * auth_process_sae_commit(struct hostapd_data *hapd,
     328             :                                                struct sta_info *sta)
     329             : {
     330             :         struct wpabuf *buf;
     331             : 
     332          20 :         if (hapd->conf->ssid.wpa_passphrase == NULL) {
     333           0 :                 wpa_printf(MSG_DEBUG, "SAE: No password available");
     334           0 :                 return NULL;
     335             :         }
     336             : 
     337          60 :         if (sae_prepare_commit(hapd->own_addr, sta->addr,
     338          20 :                                (u8 *) hapd->conf->ssid.wpa_passphrase,
     339          20 :                                os_strlen(hapd->conf->ssid.wpa_passphrase),
     340             :                                sta->sae) < 0) {
     341           0 :                 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
     342           0 :                 return NULL;
     343             :         }
     344             : 
     345          20 :         if (sae_process_commit(sta->sae) < 0) {
     346           0 :                 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
     347           0 :                 return NULL;
     348             :         }
     349             : 
     350          20 :         buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
     351          20 :         if (buf == NULL)
     352           0 :                 return NULL;
     353          20 :         sae_write_commit(sta->sae, buf, NULL);
     354             : 
     355          20 :         return buf;
     356             : }
     357             : 
     358             : 
     359          20 : static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
     360             :                                               struct sta_info *sta)
     361             : {
     362             :         struct wpabuf *buf;
     363             : 
     364          20 :         buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
     365          20 :         if (buf == NULL)
     366           0 :                 return NULL;
     367             : 
     368          20 :         sae_write_confirm(sta->sae, buf);
     369             : 
     370          20 :         return buf;
     371             : }
     372             : 
     373             : 
     374          20 : static int use_sae_anti_clogging(struct hostapd_data *hapd)
     375             : {
     376             :         struct sta_info *sta;
     377          20 :         unsigned int open = 0;
     378             : 
     379          20 :         if (hapd->conf->sae_anti_clogging_threshold == 0)
     380           4 :                 return 1;
     381             : 
     382          32 :         for (sta = hapd->sta_list; sta; sta = sta->next) {
     383          17 :                 if (!sta->sae)
     384           0 :                         continue;
     385          33 :                 if (sta->sae->state != SAE_COMMITTED &&
     386          16 :                     sta->sae->state != SAE_CONFIRMED)
     387          16 :                         continue;
     388           1 :                 open++;
     389           1 :                 if (open >= hapd->conf->sae_anti_clogging_threshold)
     390           1 :                         return 1;
     391             :         }
     392             : 
     393          15 :         return 0;
     394             : }
     395             : 
     396             : 
     397           5 : static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
     398             :                            const u8 *token, size_t token_len)
     399             : {
     400             :         u8 mac[SHA256_MAC_LEN];
     401             : 
     402           5 :         if (token_len != SHA256_MAC_LEN)
     403           0 :                 return -1;
     404           5 :         if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
     405           5 :                         addr, ETH_ALEN, mac) < 0 ||
     406           5 :             os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0)
     407           0 :                 return -1;
     408             : 
     409           5 :         return 0;
     410             : }
     411             : 
     412             : 
     413           5 : static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
     414             :                                             const u8 *addr)
     415             : {
     416             :         struct wpabuf *buf;
     417             :         u8 *token;
     418             :         struct os_reltime now;
     419             : 
     420           5 :         os_get_reltime(&now);
     421           7 :         if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
     422           2 :             os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60)) {
     423           3 :                 if (random_get_bytes(hapd->sae_token_key,
     424             :                                      sizeof(hapd->sae_token_key)) < 0)
     425           0 :                         return NULL;
     426           3 :                 wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
     427           3 :                             hapd->sae_token_key, sizeof(hapd->sae_token_key));
     428           3 :                 hapd->last_sae_token_key_update = now;
     429             :         }
     430             : 
     431           5 :         buf = wpabuf_alloc(SHA256_MAC_LEN);
     432           5 :         if (buf == NULL)
     433           0 :                 return NULL;
     434             : 
     435           5 :         token = wpabuf_put(buf, SHA256_MAC_LEN);
     436           5 :         hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
     437             :                     addr, ETH_ALEN, token);
     438             : 
     439           5 :         return buf;
     440             : }
     441             : 
     442             : 
     443          48 : static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
     444             :                             const struct ieee80211_mgmt *mgmt, size_t len,
     445             :                             u8 auth_transaction)
     446             : {
     447          48 :         u16 resp = WLAN_STATUS_SUCCESS;
     448          48 :         struct wpabuf *data = NULL;
     449             : 
     450          48 :         if (!sta->sae) {
     451          20 :                 if (auth_transaction != 1)
     452           0 :                         return;
     453          20 :                 sta->sae = os_zalloc(sizeof(*sta->sae));
     454          20 :                 if (sta->sae == NULL)
     455           0 :                         return;
     456          20 :                 sta->sae->state = SAE_NOTHING;
     457             :         }
     458             : 
     459          48 :         if (auth_transaction == 1) {
     460          28 :                 const u8 *token = NULL;
     461          28 :                 size_t token_len = 0;
     462          28 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     463             :                                HOSTAPD_LEVEL_DEBUG,
     464             :                                "start SAE authentication (RX commit)");
     465          56 :                 resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
     466          28 :                                         ((const u8 *) mgmt) + len -
     467             :                                         mgmt->u.auth.variable, &token,
     468          28 :                                         &token_len, hapd->conf->sae_groups);
     469          28 :                 if (token && check_sae_token(hapd, sta->addr, token, token_len)
     470             :                     < 0) {
     471           0 :                         wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
     472             :                                    "incorrect token from " MACSTR,
     473           0 :                                    MAC2STR(sta->addr));
     474           0 :                         return;
     475             :                 }
     476             : 
     477          28 :                 if (resp == WLAN_STATUS_SUCCESS) {
     478          25 :                         if (!token && use_sae_anti_clogging(hapd)) {
     479          30 :                                 wpa_printf(MSG_DEBUG, "SAE: Request anti-"
     480             :                                            "clogging token from " MACSTR,
     481          30 :                                            MAC2STR(sta->addr));
     482           5 :                                 data = auth_build_token_req(hapd, sta->addr);
     483           5 :                                 resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
     484             :                         } else {
     485          20 :                                 data = auth_process_sae_commit(hapd, sta);
     486          20 :                                 if (data == NULL)
     487           0 :                                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     488             :                                 else
     489          20 :                                         sta->sae->state = SAE_COMMITTED;
     490             :                         }
     491             :                 }
     492          20 :         } else if (auth_transaction == 2) {
     493          20 :                 if (sta->sae->state != SAE_COMMITTED) {
     494           0 :                         hostapd_logger(hapd, sta->addr,
     495             :                                        HOSTAPD_MODULE_IEEE80211,
     496             :                                        HOSTAPD_LEVEL_DEBUG,
     497             :                                        "SAE confirm before commit");
     498           0 :                         resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
     499           0 :                         goto failed;
     500             :                 }
     501          20 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     502             :                                HOSTAPD_LEVEL_DEBUG,
     503             :                                "SAE authentication (RX confirm)");
     504          20 :                 if (sae_check_confirm(sta->sae, mgmt->u.auth.variable,
     505          20 :                                        ((u8 *) mgmt) + len -
     506             :                                        mgmt->u.auth.variable) < 0) {
     507           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     508             :                 } else {
     509          20 :                         resp = WLAN_STATUS_SUCCESS;
     510          20 :                         sta->flags |= WLAN_STA_AUTH;
     511          20 :                         wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
     512          20 :                         sta->auth_alg = WLAN_AUTH_SAE;
     513          20 :                         mlme_authenticate_indication(hapd, sta);
     514             : 
     515          20 :                         data = auth_build_sae_confirm(hapd, sta);
     516          20 :                         if (data == NULL)
     517           0 :                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     518             :                         else {
     519          20 :                                 sta->sae->state = SAE_ACCEPTED;
     520          20 :                                 sae_clear_temp_data(sta->sae);
     521             :                         }
     522             :                 }
     523             :         } else {
     524           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     525             :                                HOSTAPD_LEVEL_DEBUG,
     526             :                                "unexpected SAE authentication transaction %u",
     527             :                                auth_transaction);
     528           0 :                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
     529             :         }
     530             : 
     531             : failed:
     532          48 :         sta->auth_alg = WLAN_AUTH_SAE;
     533             : 
     534          48 :         send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
     535             :                         auth_transaction, resp,
     536             :                         data ? wpabuf_head(data) : (u8 *) "",
     537             :                         data ? wpabuf_len(data) : 0);
     538          48 :         wpabuf_free(data);
     539             : }
     540             : #endif /* CONFIG_SAE */
     541             : 
     542             : 
     543        1254 : static void handle_auth(struct hostapd_data *hapd,
     544             :                         const struct ieee80211_mgmt *mgmt, size_t len)
     545             : {
     546             :         u16 auth_alg, auth_transaction, status_code;
     547        1254 :         u16 resp = WLAN_STATUS_SUCCESS;
     548        1254 :         struct sta_info *sta = NULL;
     549             :         int res;
     550             :         u16 fc;
     551        1254 :         const u8 *challenge = NULL;
     552             :         u32 session_timeout, acct_interim_interval;
     553        1254 :         int vlan_id = 0;
     554        1254 :         struct hostapd_sta_wpa_psk_short *psk = NULL;
     555             :         u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
     556        1254 :         size_t resp_ies_len = 0;
     557        1254 :         char *identity = NULL;
     558        1254 :         char *radius_cui = NULL;
     559             : 
     560        1254 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
     561           0 :                 wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
     562             :                            (unsigned long) len);
     563           0 :                 return;
     564             :         }
     565             : 
     566             : #ifdef CONFIG_TESTING_OPTIONS
     567        1261 :         if (hapd->iconf->ignore_auth_probability > 0.0 &&
     568           7 :             drand48() < hapd->iconf->ignore_auth_probability) {
     569          24 :                 wpa_printf(MSG_INFO,
     570             :                            "TESTING: ignoring auth frame from " MACSTR,
     571          24 :                            MAC2STR(mgmt->sa));
     572           4 :                 return;
     573             :         }
     574             : #endif /* CONFIG_TESTING_OPTIONS */
     575             : 
     576        1250 :         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
     577        1250 :         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
     578        1250 :         status_code = le_to_host16(mgmt->u.auth.status_code);
     579        1250 :         fc = le_to_host16(mgmt->frame_control);
     580             : 
     581        1250 :         if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
     582         128 :             2 + WLAN_AUTH_CHALLENGE_LEN &&
     583         130 :             mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
     584           2 :             mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
     585           2 :                 challenge = &mgmt->u.auth.variable[2];
     586             : 
     587       10000 :         wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
     588             :                    "auth_transaction=%d status_code=%d wep=%d%s",
     589        7500 :                    MAC2STR(mgmt->sa), auth_alg, auth_transaction,
     590        1250 :                    status_code, !!(fc & WLAN_FC_ISWEP),
     591             :                    challenge ? " challenge" : "");
     592             : 
     593        1250 :         if (hapd->tkip_countermeasures) {
     594           2 :                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
     595           2 :                 goto fail;
     596             :         }
     597             : 
     598        1257 :         if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
     599         170 :                auth_alg == WLAN_AUTH_OPEN) ||
     600             : #ifdef CONFIG_IEEE80211R
     601         331 :               (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
     602          57 :                auth_alg == WLAN_AUTH_FT) ||
     603             : #endif /* CONFIG_IEEE80211R */
     604             : #ifdef CONFIG_SAE
     605         105 :               (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
     606             :                auth_alg == WLAN_AUTH_SAE) ||
     607             : #endif /* CONFIG_SAE */
     608          14 :               ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
     609             :                auth_alg == WLAN_AUTH_SHARED_KEY))) {
     610           5 :                 wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
     611             :                            auth_alg);
     612           5 :                 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
     613           5 :                 goto fail;
     614             :         }
     615             : 
     616        1243 :         if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
     617           2 :               (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
     618           0 :                 wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
     619             :                            auth_transaction);
     620           0 :                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
     621           0 :                 goto fail;
     622             :         }
     623             : 
     624        1243 :         if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
     625           0 :                 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
     626           0 :                            MAC2STR(mgmt->sa));
     627           0 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     628           0 :                 goto fail;
     629             :         }
     630             : 
     631        1243 :         res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
     632             :                                       &session_timeout,
     633             :                                       &acct_interim_interval, &vlan_id,
     634             :                                       &psk, &identity, &radius_cui);
     635             : 
     636        1243 :         if (res == HOSTAPD_ACL_REJECT) {
     637          54 :                 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
     638          54 :                            MAC2STR(mgmt->sa));
     639           9 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     640           9 :                 goto fail;
     641             :         }
     642        1234 :         if (res == HOSTAPD_ACL_PENDING) {
     643           6 :                 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
     644             :                            " waiting for an external authentication",
     645           6 :                            MAC2STR(mgmt->sa));
     646             :                 /* Authentication code will re-send the authentication frame
     647             :                  * after it has received (and cached) information from the
     648             :                  * external source. */
     649           1 :                 return;
     650             :         }
     651             : 
     652        1233 :         sta = ap_sta_add(hapd, mgmt->sa);
     653        1233 :         if (!sta) {
     654           3 :                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
     655           3 :                 goto fail;
     656             :         }
     657             : 
     658        1230 :         if (vlan_id > 0) {
     659           8 :                 if (!hostapd_vlan_id_valid(hapd->conf->vlan, vlan_id)) {
     660           0 :                         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
     661             :                                        HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
     662             :                                        "%d received from RADIUS server",
     663             :                                        vlan_id);
     664           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     665           0 :                         goto fail;
     666             :                 }
     667           8 :                 sta->vlan_id = vlan_id;
     668           8 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
     669             :                                HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
     670             :         }
     671             : 
     672        1230 :         hostapd_free_psk_list(sta->psk);
     673        1230 :         if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
     674           0 :                 sta->psk = psk;
     675           0 :                 psk = NULL;
     676             :         } else {
     677        1230 :                 sta->psk = NULL;
     678             :         }
     679             : 
     680        1230 :         sta->identity = identity;
     681        1230 :         identity = NULL;
     682        1230 :         sta->radius_cui = radius_cui;
     683        1230 :         radius_cui = NULL;
     684             : 
     685        1230 :         sta->flags &= ~WLAN_STA_PREAUTH;
     686        1230 :         ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
     687             : 
     688        1230 :         if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
     689           0 :                 sta->acct_interim_interval = acct_interim_interval;
     690        1230 :         if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
     691           0 :                 ap_sta_session_timeout(hapd, sta, session_timeout);
     692             :         else
     693        1230 :                 ap_sta_no_session_timeout(hapd, sta);
     694             : 
     695        1230 :         switch (auth_alg) {
     696             :         case WLAN_AUTH_OPEN:
     697        1065 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     698             :                                HOSTAPD_LEVEL_DEBUG,
     699             :                                "authentication OK (open system)");
     700        1065 :                 sta->flags |= WLAN_STA_AUTH;
     701        1065 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
     702        1065 :                 sta->auth_alg = WLAN_AUTH_OPEN;
     703        1065 :                 mlme_authenticate_indication(hapd, sta);
     704        1065 :                 break;
     705             :         case WLAN_AUTH_SHARED_KEY:
     706           4 :                 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
     707             :                                        fc & WLAN_FC_ISWEP);
     708           4 :                 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
     709           4 :                 mlme_authenticate_indication(hapd, sta);
     710           4 :                 if (sta->challenge && auth_transaction == 1) {
     711           2 :                         resp_ies[0] = WLAN_EID_CHALLENGE;
     712           2 :                         resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
     713           2 :                         os_memcpy(resp_ies + 2, sta->challenge,
     714             :                                   WLAN_AUTH_CHALLENGE_LEN);
     715           2 :                         resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
     716             :                 }
     717           4 :                 break;
     718             : #ifdef CONFIG_IEEE80211R
     719             :         case WLAN_AUTH_FT:
     720         113 :                 sta->auth_alg = WLAN_AUTH_FT;
     721         113 :                 if (sta->wpa_sm == NULL)
     722           8 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
     723           8 :                                                         sta->addr, NULL);
     724         113 :                 if (sta->wpa_sm == NULL) {
     725           0 :                         wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
     726             :                                    "state machine");
     727           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     728           0 :                         goto fail;
     729             :                 }
     730         226 :                 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
     731         113 :                                     auth_transaction, mgmt->u.auth.variable,
     732             :                                     len - IEEE80211_HDRLEN -
     733             :                                     sizeof(mgmt->u.auth),
     734             :                                     handle_auth_ft_finish, hapd);
     735             :                 /* handle_auth_ft_finish() callback will complete auth. */
     736         113 :                 return;
     737             : #endif /* CONFIG_IEEE80211R */
     738             : #ifdef CONFIG_SAE
     739             :         case WLAN_AUTH_SAE:
     740          48 :                 handle_auth_sae(hapd, sta, mgmt, len, auth_transaction);
     741          48 :                 return;
     742             : #endif /* CONFIG_SAE */
     743             :         }
     744             : 
     745             :  fail:
     746        1088 :         os_free(identity);
     747        1088 :         os_free(radius_cui);
     748        1088 :         hostapd_free_psk_list(psk);
     749             : 
     750        1088 :         send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
     751             :                         auth_transaction + 1, resp, resp_ies, resp_ies_len);
     752             : }
     753             : 
     754             : 
     755        1299 : static int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
     756             : {
     757        1299 :         int i, j = 32, aid;
     758             : 
     759             :         /* get a unique AID */
     760        1299 :         if (sta->aid > 0) {
     761         262 :                 wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
     762         262 :                 return 0;
     763             :         }
     764             : 
     765        1037 :         for (i = 0; i < AID_WORDS; i++) {
     766        1037 :                 if (hapd->sta_aid[i] == (u32) -1)
     767           0 :                         continue;
     768        1222 :                 for (j = 0; j < 32; j++) {
     769        1222 :                         if (!(hapd->sta_aid[i] & BIT(j)))
     770        1037 :                                 break;
     771             :                 }
     772        1037 :                 if (j < 32)
     773        1037 :                         break;
     774             :         }
     775        1037 :         if (j == 32)
     776           0 :                 return -1;
     777        1037 :         aid = i * 32 + j + 1;
     778        1037 :         if (aid > 2007)
     779           0 :                 return -1;
     780             : 
     781        1037 :         sta->aid = aid;
     782        1037 :         hapd->sta_aid[i] |= BIT(j);
     783        1037 :         wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
     784        1037 :         return 0;
     785             : }
     786             : 
     787             : 
     788        1309 : static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
     789             :                       const u8 *ssid_ie, size_t ssid_ie_len)
     790             : {
     791        1309 :         if (ssid_ie == NULL)
     792           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     793             : 
     794        2618 :         if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
     795        1309 :             os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
     796           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     797             :                                HOSTAPD_LEVEL_INFO,
     798             :                                "Station tried to associate with unknown SSID "
     799             :                                "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
     800           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     801             :         }
     802             : 
     803        1309 :         return WLAN_STATUS_SUCCESS;
     804             : }
     805             : 
     806             : 
     807        1309 : static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
     808             :                      const u8 *wmm_ie, size_t wmm_ie_len)
     809             : {
     810        1309 :         sta->flags &= ~WLAN_STA_WMM;
     811        1309 :         sta->qosinfo = 0;
     812        1309 :         if (wmm_ie && hapd->conf->wmm_enabled) {
     813             :                 struct wmm_information_element *wmm;
     814             : 
     815        1305 :                 if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
     816           0 :                         hostapd_logger(hapd, sta->addr,
     817             :                                        HOSTAPD_MODULE_WPA,
     818             :                                        HOSTAPD_LEVEL_DEBUG,
     819             :                                        "invalid WMM element in association "
     820             :                                        "request");
     821           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
     822             :                 }
     823             : 
     824        1305 :                 sta->flags |= WLAN_STA_WMM;
     825        1305 :                 wmm = (struct wmm_information_element *) wmm_ie;
     826        1305 :                 sta->qosinfo = wmm->qos_info;
     827             :         }
     828        1309 :         return WLAN_STATUS_SUCCESS;
     829             : }
     830             : 
     831             : 
     832        1309 : static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
     833             :                            struct ieee802_11_elems *elems)
     834             : {
     835        1309 :         if (!elems->supp_rates) {
     836           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     837             :                                HOSTAPD_LEVEL_DEBUG,
     838             :                                "No supported rates element in AssocReq");
     839           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     840             :         }
     841             : 
     842        1309 :         if (elems->supp_rates_len + elems->ext_supp_rates_len >
     843             :             sizeof(sta->supported_rates)) {
     844           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     845             :                                HOSTAPD_LEVEL_DEBUG,
     846             :                                "Invalid supported rates element length %d+%d",
     847           0 :                                elems->supp_rates_len,
     848           0 :                                elems->ext_supp_rates_len);
     849           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     850             :         }
     851             : 
     852        3927 :         sta->supported_rates_len = merge_byte_arrays(
     853        1309 :                 sta->supported_rates, sizeof(sta->supported_rates),
     854        1309 :                 elems->supp_rates, elems->supp_rates_len,
     855        1309 :                 elems->ext_supp_rates, elems->ext_supp_rates_len);
     856             : 
     857        1309 :         return WLAN_STATUS_SUCCESS;
     858             : }
     859             : 
     860             : 
     861        1309 : static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
     862             :                            const u8 *ext_capab_ie, size_t ext_capab_ie_len)
     863             : {
     864             : #ifdef CONFIG_INTERWORKING
     865             :         /* check for QoS Map support */
     866        1309 :         if (ext_capab_ie_len >= 5) {
     867        1083 :                 if (ext_capab_ie[4] & 0x01)
     868        1083 :                         sta->qos_map_enabled = 1;
     869             :         }
     870             : #endif /* CONFIG_INTERWORKING */
     871             : 
     872        1309 :         return WLAN_STATUS_SUCCESS;
     873             : }
     874             : 
     875             : 
     876        1309 : static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
     877             :                            const u8 *ies, size_t ies_len, int reassoc)
     878             : {
     879             :         struct ieee802_11_elems elems;
     880             :         u16 resp;
     881             :         const u8 *wpa_ie;
     882             :         size_t wpa_ie_len;
     883        1309 :         const u8 *p2p_dev_addr = NULL;
     884             : 
     885        1309 :         if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
     886           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     887             :                                HOSTAPD_LEVEL_INFO, "Station sent an invalid "
     888             :                                "association request");
     889           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     890             :         }
     891             : 
     892        1309 :         resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
     893        1309 :         if (resp != WLAN_STATUS_SUCCESS)
     894           0 :                 return resp;
     895        1309 :         resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
     896        1309 :         if (resp != WLAN_STATUS_SUCCESS)
     897           0 :                 return resp;
     898        1309 :         resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
     899        1309 :         if (resp != WLAN_STATUS_SUCCESS)
     900           0 :                 return resp;
     901        1309 :         resp = copy_supp_rates(hapd, sta, &elems);
     902        1309 :         if (resp != WLAN_STATUS_SUCCESS)
     903           0 :                 return resp;
     904             : #ifdef CONFIG_IEEE80211N
     905        1309 :         resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities,
     906        1309 :                                  elems.ht_capabilities_len);
     907        1309 :         if (resp != WLAN_STATUS_SUCCESS)
     908           0 :                 return resp;
     909        1317 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
     910           8 :             !(sta->flags & WLAN_STA_HT)) {
     911           5 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     912             :                                HOSTAPD_LEVEL_INFO, "Station does not support "
     913             :                                "mandatory HT PHY - reject association");
     914           5 :                 return WLAN_STATUS_ASSOC_DENIED_NO_HT;
     915             :         }
     916             : #endif /* CONFIG_IEEE80211N */
     917             : 
     918             : #ifdef CONFIG_IEEE80211AC
     919        1304 :         resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities,
     920        1304 :                                   elems.vht_capabilities_len);
     921        1304 :         if (resp != WLAN_STATUS_SUCCESS)
     922           0 :                 return resp;
     923             : 
     924        1304 :         resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
     925        1304 :         if (resp != WLAN_STATUS_SUCCESS)
     926           0 :                 return resp;
     927             : 
     928        1307 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
     929           3 :             !(sta->flags & WLAN_STA_VHT)) {
     930           1 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     931             :                                HOSTAPD_LEVEL_INFO, "Station does not support "
     932             :                                "mandatory VHT PHY - reject association");
     933           1 :                 return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
     934             :         }
     935             : #endif /* CONFIG_IEEE80211AC */
     936             : 
     937             : #ifdef CONFIG_P2P
     938             :         if (elems.p2p) {
     939             :                 wpabuf_free(sta->p2p_ie);
     940             :                 sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
     941             :                                                           P2P_IE_VENDOR_TYPE);
     942             :                 if (sta->p2p_ie)
     943             :                         p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
     944             :         } else {
     945             :                 wpabuf_free(sta->p2p_ie);
     946             :                 sta->p2p_ie = NULL;
     947             :         }
     948             : #endif /* CONFIG_P2P */
     949             : 
     950        1303 :         if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
     951        1009 :                 wpa_ie = elems.rsn_ie;
     952        1009 :                 wpa_ie_len = elems.rsn_ie_len;
     953         310 :         } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
     954          16 :                    elems.wpa_ie) {
     955          13 :                 wpa_ie = elems.wpa_ie;
     956          13 :                 wpa_ie_len = elems.wpa_ie_len;
     957             :         } else {
     958         281 :                 wpa_ie = NULL;
     959         281 :                 wpa_ie_len = 0;
     960             :         }
     961             : 
     962             : #ifdef CONFIG_WPS
     963        1303 :         sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
     964        1303 :         if (hapd->conf->wps_state && elems.wps_ie) {
     965          86 :                 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
     966             :                            "Request - assume WPS is used");
     967          86 :                 sta->flags |= WLAN_STA_WPS;
     968          86 :                 wpabuf_free(sta->wps_ie);
     969          86 :                 sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
     970             :                                                           WPS_IE_VENDOR_TYPE);
     971          86 :                 if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
     972          84 :                         wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
     973          84 :                         sta->flags |= WLAN_STA_WPS2;
     974             :                 }
     975          86 :                 wpa_ie = NULL;
     976          86 :                 wpa_ie_len = 0;
     977         172 :                 if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
     978           0 :                         wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
     979             :                                    "(Re)Association Request - reject");
     980           0 :                         return WLAN_STATUS_INVALID_IE;
     981             :                 }
     982        1217 :         } else if (hapd->conf->wps_state && wpa_ie == NULL) {
     983           1 :                 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
     984             :                            "(Re)Association Request - possible WPS use");
     985           1 :                 sta->flags |= WLAN_STA_MAYBE_WPS;
     986             :         } else
     987             : #endif /* CONFIG_WPS */
     988        1216 :         if (hapd->conf->wpa && wpa_ie == NULL) {
     989           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     990             :                                HOSTAPD_LEVEL_INFO,
     991             :                                "No WPA/RSN IE in association request");
     992           0 :                 return WLAN_STATUS_INVALID_IE;
     993             :         }
     994             : 
     995        2323 :         if (hapd->conf->wpa && wpa_ie) {
     996             :                 int res;
     997        1022 :                 wpa_ie -= 2;
     998        1022 :                 wpa_ie_len += 2;
     999        1022 :                 if (sta->wpa_sm == NULL)
    1000         749 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    1001         749 :                                                         sta->addr,
    1002             :                                                         p2p_dev_addr);
    1003        1022 :                 if (sta->wpa_sm == NULL) {
    1004           0 :                         wpa_printf(MSG_WARNING, "Failed to initialize WPA "
    1005             :                                    "state machine");
    1006           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1007             :                 }
    1008        1022 :                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
    1009             :                                           wpa_ie, wpa_ie_len,
    1010        1022 :                                           elems.mdie, elems.mdie_len);
    1011        1022 :                 if (res == WPA_INVALID_GROUP)
    1012           0 :                         resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
    1013        1022 :                 else if (res == WPA_INVALID_PAIRWISE)
    1014           0 :                         resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
    1015        1022 :                 else if (res == WPA_INVALID_AKMP)
    1016           0 :                         resp = WLAN_STATUS_AKMP_NOT_VALID;
    1017        1022 :                 else if (res == WPA_ALLOC_FAIL)
    1018           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1019             : #ifdef CONFIG_IEEE80211W
    1020        1022 :                 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
    1021           0 :                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
    1022        1022 :                 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
    1023           0 :                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
    1024             : #endif /* CONFIG_IEEE80211W */
    1025        1022 :                 else if (res == WPA_INVALID_MDIE)
    1026           0 :                         resp = WLAN_STATUS_INVALID_MDIE;
    1027        1022 :                 else if (res != WPA_IE_OK)
    1028           0 :                         resp = WLAN_STATUS_INVALID_IE;
    1029        1022 :                 if (resp != WLAN_STATUS_SUCCESS)
    1030           0 :                         return resp;
    1031             : #ifdef CONFIG_IEEE80211W
    1032        1026 :                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    1033           4 :                     sta->sa_query_count > 0)
    1034           0 :                         ap_check_sa_query_timeout(hapd, sta);
    1035        1022 :                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    1036           3 :                     (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
    1037             :                         /*
    1038             :                          * STA has already been associated with MFP and SA
    1039             :                          * Query timeout has not been reached. Reject the
    1040             :                          * association attempt temporarily and start SA Query,
    1041             :                          * if one is not pending.
    1042             :                          */
    1043             : 
    1044           2 :                         if (sta->sa_query_count == 0)
    1045           2 :                                 ap_sta_start_sa_query(hapd, sta);
    1046             : 
    1047           2 :                         return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
    1048             :                 }
    1049             : 
    1050        1020 :                 if (wpa_auth_uses_mfp(sta->wpa_sm))
    1051          31 :                         sta->flags |= WLAN_STA_MFP;
    1052             :                 else
    1053         989 :                         sta->flags &= ~WLAN_STA_MFP;
    1054             : #endif /* CONFIG_IEEE80211W */
    1055             : 
    1056             : #ifdef CONFIG_IEEE80211R
    1057        1020 :                 if (sta->auth_alg == WLAN_AUTH_FT) {
    1058         221 :                         if (!reassoc) {
    1059           0 :                                 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
    1060             :                                            "to use association (not "
    1061             :                                            "re-association) with FT auth_alg",
    1062           0 :                                            MAC2STR(sta->addr));
    1063           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1064             :                         }
    1065             : 
    1066         221 :                         resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
    1067             :                                                        ies_len);
    1068         221 :                         if (resp != WLAN_STATUS_SUCCESS)
    1069           0 :                                 return resp;
    1070             :                 }
    1071             : #endif /* CONFIG_IEEE80211R */
    1072             : 
    1073             : #ifdef CONFIG_SAE
    1074        1044 :                 if (wpa_auth_uses_sae(sta->wpa_sm) &&
    1075          28 :                     sta->auth_alg != WLAN_AUTH_SAE &&
    1076           8 :                     !(sta->auth_alg == WLAN_AUTH_FT &&
    1077           4 :                       wpa_auth_uses_ft_sae(sta->wpa_sm))) {
    1078           0 :                         wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
    1079             :                                    "SAE AKM after non-SAE auth_alg %u",
    1080           0 :                                    MAC2STR(sta->addr), sta->auth_alg);
    1081           0 :                         return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
    1082             :                 }
    1083             : #endif /* CONFIG_SAE */
    1084             : 
    1085             : #ifdef CONFIG_IEEE80211N
    1086        2024 :                 if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
    1087        1004 :                     wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
    1088           0 :                         hostapd_logger(hapd, sta->addr,
    1089             :                                        HOSTAPD_MODULE_IEEE80211,
    1090             :                                        HOSTAPD_LEVEL_INFO,
    1091             :                                        "Station tried to use TKIP with HT "
    1092             :                                        "association");
    1093           0 :                         return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
    1094             :                 }
    1095             : #endif /* CONFIG_IEEE80211N */
    1096             : #ifdef CONFIG_HS20
    1097         281 :         } else if (hapd->conf->osen) {
    1098           4 :                 if (elems.osen == NULL) {
    1099           2 :                         hostapd_logger(
    1100           2 :                                 hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1101             :                                 HOSTAPD_LEVEL_INFO,
    1102             :                                 "No HS 2.0 OSEN element in association request");
    1103           2 :                         return WLAN_STATUS_INVALID_IE;
    1104             :                 }
    1105             : 
    1106           2 :                 wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
    1107           2 :                 if (sta->wpa_sm == NULL)
    1108           2 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    1109           2 :                                                         sta->addr, NULL);
    1110           2 :                 if (sta->wpa_sm == NULL) {
    1111           0 :                         wpa_printf(MSG_WARNING, "Failed to initialize WPA "
    1112             :                                    "state machine");
    1113           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1114             :                 }
    1115           4 :                 if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
    1116           4 :                                       elems.osen - 2, elems.osen_len + 2) < 0)
    1117           0 :                         return WLAN_STATUS_INVALID_IE;
    1118             : #endif /* CONFIG_HS20 */
    1119             :         } else
    1120         277 :                 wpa_auth_sta_no_wpa(sta->wpa_sm);
    1121             : 
    1122             : #ifdef CONFIG_P2P
    1123             :         p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
    1124             : #endif /* CONFIG_P2P */
    1125             : 
    1126             : #ifdef CONFIG_HS20
    1127        1299 :         wpabuf_free(sta->hs20_ie);
    1128        1299 :         if (elems.hs20 && elems.hs20_len > 4) {
    1129          81 :                 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
    1130          81 :                                                  elems.hs20_len - 4);
    1131             :         } else
    1132        1218 :                 sta->hs20_ie = NULL;
    1133             : #endif /* CONFIG_HS20 */
    1134             : 
    1135        1299 :         return WLAN_STATUS_SUCCESS;
    1136             : }
    1137             : 
    1138             : 
    1139           0 : static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
    1140             :                         u16 reason_code)
    1141             : {
    1142             :         int send_len;
    1143             :         struct ieee80211_mgmt reply;
    1144             : 
    1145           0 :         os_memset(&reply, 0, sizeof(reply));
    1146           0 :         reply.frame_control =
    1147             :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
    1148           0 :         os_memcpy(reply.da, addr, ETH_ALEN);
    1149           0 :         os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
    1150           0 :         os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
    1151             : 
    1152           0 :         send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
    1153           0 :         reply.u.deauth.reason_code = host_to_le16(reason_code);
    1154             : 
    1155           0 :         if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
    1156           0 :                 wpa_printf(MSG_INFO, "Failed to send deauth: %s",
    1157           0 :                            strerror(errno));
    1158           0 : }
    1159             : 
    1160             : 
    1161        1310 : static void send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
    1162             :                             u16 status_code, int reassoc, const u8 *ies,
    1163             :                             size_t ies_len)
    1164             : {
    1165             :         int send_len;
    1166             :         u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
    1167             :         struct ieee80211_mgmt *reply;
    1168             :         u8 *p;
    1169             : 
    1170        1310 :         os_memset(buf, 0, sizeof(buf));
    1171        1310 :         reply = (struct ieee80211_mgmt *) buf;
    1172        1310 :         reply->frame_control =
    1173        1310 :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    1174             :                              (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
    1175             :                               WLAN_FC_STYPE_ASSOC_RESP));
    1176        1310 :         os_memcpy(reply->da, sta->addr, ETH_ALEN);
    1177        1310 :         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
    1178        1310 :         os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
    1179             : 
    1180        1310 :         send_len = IEEE80211_HDRLEN;
    1181        1310 :         send_len += sizeof(reply->u.assoc_resp);
    1182        1310 :         reply->u.assoc_resp.capab_info =
    1183        1310 :                 host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
    1184        1310 :         reply->u.assoc_resp.status_code = host_to_le16(status_code);
    1185        1310 :         reply->u.assoc_resp.aid = host_to_le16(sta->aid | BIT(14) | BIT(15));
    1186             :         /* Supported rates */
    1187        1310 :         p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
    1188             :         /* Extended supported rates */
    1189        1310 :         p = hostapd_eid_ext_supp_rates(hapd, p);
    1190             : 
    1191             : #ifdef CONFIG_IEEE80211R
    1192        1310 :         if (status_code == WLAN_STATUS_SUCCESS) {
    1193             :                 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
    1194             :                  * Transition Information, RSN, [RIC Response] */
    1195        2598 :                 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
    1196        1299 :                                                 buf + sizeof(buf) - p,
    1197        1299 :                                                 sta->auth_alg, ies, ies_len);
    1198             :         }
    1199             : #endif /* CONFIG_IEEE80211R */
    1200             : 
    1201             : #ifdef CONFIG_IEEE80211W
    1202        1310 :         if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
    1203           2 :                 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
    1204             : #endif /* CONFIG_IEEE80211W */
    1205             : 
    1206             : #ifdef CONFIG_IEEE80211N
    1207        1310 :         p = hostapd_eid_ht_capabilities(hapd, p);
    1208        1310 :         p = hostapd_eid_ht_operation(hapd, p);
    1209             : #endif /* CONFIG_IEEE80211N */
    1210             : 
    1211             : #ifdef CONFIG_IEEE80211AC
    1212        1310 :         p = hostapd_eid_vht_capabilities(hapd, p);
    1213        1310 :         p = hostapd_eid_vht_operation(hapd, p);
    1214             : #endif /* CONFIG_IEEE80211AC */
    1215             : 
    1216        1310 :         p = hostapd_eid_ext_capab(hapd, p);
    1217        1310 :         p = hostapd_eid_bss_max_idle_period(hapd, p);
    1218        1310 :         if (sta->qos_map_enabled)
    1219        1193 :                 p = hostapd_eid_qos_map_set(hapd, p);
    1220             : 
    1221        1310 :         if (sta->flags & WLAN_STA_WMM)
    1222        1305 :                 p = hostapd_eid_wmm(hapd, p);
    1223             : 
    1224             : #ifdef CONFIG_WPS
    1225        2534 :         if ((sta->flags & WLAN_STA_WPS) ||
    1226        1225 :             ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) {
    1227          86 :                 struct wpabuf *wps = wps_build_assoc_resp_ie();
    1228          86 :                 if (wps) {
    1229          86 :                         os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
    1230          86 :                         p += wpabuf_len(wps);
    1231          86 :                         wpabuf_free(wps);
    1232             :                 }
    1233             :         }
    1234             : #endif /* CONFIG_WPS */
    1235             : 
    1236             : #ifdef CONFIG_P2P
    1237             :         if (sta->p2p_ie) {
    1238             :                 struct wpabuf *p2p_resp_ie;
    1239             :                 enum p2p_status_code status;
    1240             :                 switch (status_code) {
    1241             :                 case WLAN_STATUS_SUCCESS:
    1242             :                         status = P2P_SC_SUCCESS;
    1243             :                         break;
    1244             :                 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
    1245             :                         status = P2P_SC_FAIL_LIMIT_REACHED;
    1246             :                         break;
    1247             :                 default:
    1248             :                         status = P2P_SC_FAIL_INVALID_PARAMS;
    1249             :                         break;
    1250             :                 }
    1251             :                 p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
    1252             :                 if (p2p_resp_ie) {
    1253             :                         os_memcpy(p, wpabuf_head(p2p_resp_ie),
    1254             :                                   wpabuf_len(p2p_resp_ie));
    1255             :                         p += wpabuf_len(p2p_resp_ie);
    1256             :                         wpabuf_free(p2p_resp_ie);
    1257             :                 }
    1258             :         }
    1259             : #endif /* CONFIG_P2P */
    1260             : 
    1261             : #ifdef CONFIG_P2P_MANAGER
    1262        1310 :         if (hapd->conf->p2p & P2P_MANAGE)
    1263           5 :                 p = hostapd_eid_p2p_manage(hapd, p);
    1264             : #endif /* CONFIG_P2P_MANAGER */
    1265             : 
    1266        1310 :         send_len += p - reply->u.assoc_resp.variable;
    1267             : 
    1268        1310 :         if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0)
    1269           0 :                 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
    1270           0 :                            strerror(errno));
    1271        1310 : }
    1272             : 
    1273             : 
    1274        1311 : static void handle_assoc(struct hostapd_data *hapd,
    1275             :                          const struct ieee80211_mgmt *mgmt, size_t len,
    1276             :                          int reassoc)
    1277             : {
    1278             :         u16 capab_info, listen_interval;
    1279        1311 :         u16 resp = WLAN_STATUS_SUCCESS;
    1280             :         const u8 *pos;
    1281             :         int left, i;
    1282             :         struct sta_info *sta;
    1283             : 
    1284        1311 :         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
    1285             :                                       sizeof(mgmt->u.assoc_req))) {
    1286           0 :                 wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
    1287             :                            reassoc, (unsigned long) len);
    1288           0 :                 return;
    1289             :         }
    1290             : 
    1291             : #ifdef CONFIG_TESTING_OPTIONS
    1292        1311 :         if (reassoc) {
    1293         258 :                 if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
    1294           0 :                     drand48() < hapd->iconf->ignore_reassoc_probability) {
    1295           0 :                         wpa_printf(MSG_INFO,
    1296             :                                    "TESTING: ignoring reassoc request from "
    1297           0 :                                    MACSTR, MAC2STR(mgmt->sa));
    1298           0 :                         return;
    1299             :                 }
    1300             :         } else {
    1301        1057 :                 if (hapd->iconf->ignore_assoc_probability > 0.0 &&
    1302           4 :                     drand48() < hapd->iconf->ignore_assoc_probability) {
    1303           6 :                         wpa_printf(MSG_INFO,
    1304             :                                    "TESTING: ignoring assoc request from "
    1305           6 :                                    MACSTR, MAC2STR(mgmt->sa));
    1306           1 :                         return;
    1307             :                 }
    1308             :         }
    1309             : #endif /* CONFIG_TESTING_OPTIONS */
    1310             : 
    1311        1310 :         if (reassoc) {
    1312         258 :                 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
    1313         258 :                 listen_interval = le_to_host16(
    1314             :                         mgmt->u.reassoc_req.listen_interval);
    1315        3096 :                 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
    1316             :                            " capab_info=0x%02x listen_interval=%d current_ap="
    1317             :                            MACSTR,
    1318        1548 :                            MAC2STR(mgmt->sa), capab_info, listen_interval,
    1319        1548 :                            MAC2STR(mgmt->u.reassoc_req.current_ap));
    1320         258 :                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
    1321         258 :                 pos = mgmt->u.reassoc_req.variable;
    1322             :         } else {
    1323        1052 :                 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
    1324        1052 :                 listen_interval = le_to_host16(
    1325             :                         mgmt->u.assoc_req.listen_interval);
    1326        7364 :                 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
    1327             :                            " capab_info=0x%02x listen_interval=%d",
    1328        6312 :                            MAC2STR(mgmt->sa), capab_info, listen_interval);
    1329        1052 :                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
    1330        1052 :                 pos = mgmt->u.assoc_req.variable;
    1331             :         }
    1332             : 
    1333        1310 :         sta = ap_get_sta(hapd, mgmt->sa);
    1334             : #ifdef CONFIG_IEEE80211R
    1335        1531 :         if (sta && sta->auth_alg == WLAN_AUTH_FT &&
    1336         221 :             (sta->flags & WLAN_STA_AUTH) == 0) {
    1337         324 :                 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
    1338             :                            "prior to authentication since it is using "
    1339         324 :                            "over-the-DS FT", MAC2STR(mgmt->sa));
    1340             :         } else
    1341             : #endif /* CONFIG_IEEE80211R */
    1342        1256 :         if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
    1343           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1344             :                                HOSTAPD_LEVEL_INFO, "Station tried to "
    1345             :                                "associate before authentication "
    1346             :                                "(aid=%d flags=0x%x)",
    1347           0 :                                sta ? sta->aid : -1,
    1348             :                                sta ? sta->flags : 0);
    1349           0 :                 send_deauth(hapd, mgmt->sa,
    1350             :                             WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
    1351           0 :                 return;
    1352             :         }
    1353             : 
    1354        1310 :         if (hapd->tkip_countermeasures) {
    1355           0 :                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
    1356           0 :                 goto fail;
    1357             :         }
    1358             : 
    1359        1310 :         if (listen_interval > hapd->conf->max_listen_interval) {
    1360           1 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1361             :                                HOSTAPD_LEVEL_DEBUG,
    1362             :                                "Too large Listen Interval (%d)",
    1363             :                                listen_interval);
    1364           1 :                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
    1365           1 :                 goto fail;
    1366             :         }
    1367             : 
    1368             :         /* followed by SSID and Supported rates; and HT capabilities if 802.11n
    1369             :          * is used */
    1370        1309 :         resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
    1371        1309 :         if (resp != WLAN_STATUS_SUCCESS)
    1372          10 :                 goto fail;
    1373             : 
    1374        1299 :         if (hostapd_get_aid(hapd, sta) < 0) {
    1375           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1376             :                                HOSTAPD_LEVEL_INFO, "No room for more AIDs");
    1377           0 :                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    1378           0 :                 goto fail;
    1379             :         }
    1380             : 
    1381        1299 :         sta->capability = capab_info;
    1382        1299 :         sta->listen_interval = listen_interval;
    1383             : 
    1384        1299 :         if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    1385        1278 :                 sta->flags |= WLAN_STA_NONERP;
    1386        9011 :         for (i = 0; i < sta->supported_rates_len; i++) {
    1387        9007 :                 if ((sta->supported_rates[i] & 0x7f) > 22) {
    1388        1295 :                         sta->flags &= ~WLAN_STA_NONERP;
    1389        1295 :                         break;
    1390             :                 }
    1391             :         }
    1392        1299 :         if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
    1393           0 :                 sta->nonerp_set = 1;
    1394           0 :                 hapd->iface->num_sta_non_erp++;
    1395           0 :                 if (hapd->iface->num_sta_non_erp == 1)
    1396           0 :                         ieee802_11_set_beacons(hapd->iface);
    1397             :         }
    1398             : 
    1399        1316 :         if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
    1400          17 :             !sta->no_short_slot_time_set) {
    1401          17 :                 sta->no_short_slot_time_set = 1;
    1402          17 :                 hapd->iface->num_sta_no_short_slot_time++;
    1403          17 :                 if (hapd->iface->current_mode->mode ==
    1404           0 :                     HOSTAPD_MODE_IEEE80211G &&
    1405           0 :                     hapd->iface->num_sta_no_short_slot_time == 1)
    1406           0 :                         ieee802_11_set_beacons(hapd->iface);
    1407             :         }
    1408             : 
    1409        1299 :         if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
    1410        1282 :                 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
    1411             :         else
    1412          17 :                 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
    1413             : 
    1414        1316 :         if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
    1415          17 :             !sta->no_short_preamble_set) {
    1416          17 :                 sta->no_short_preamble_set = 1;
    1417          17 :                 hapd->iface->num_sta_no_short_preamble++;
    1418          17 :                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
    1419           0 :                     && hapd->iface->num_sta_no_short_preamble == 1)
    1420           0 :                         ieee802_11_set_beacons(hapd->iface);
    1421             :         }
    1422             : 
    1423             : #ifdef CONFIG_IEEE80211N
    1424        1299 :         update_ht_state(hapd, sta);
    1425             : #endif /* CONFIG_IEEE80211N */
    1426             : 
    1427        1299 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1428             :                        HOSTAPD_LEVEL_DEBUG,
    1429        1299 :                        "association OK (aid %d)", sta->aid);
    1430             :         /* Station will be marked associated, after it acknowledges AssocResp
    1431             :          */
    1432        1299 :         sta->flags |= WLAN_STA_ASSOC_REQ_OK;
    1433             : 
    1434             : #ifdef CONFIG_IEEE80211W
    1435        1299 :         if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
    1436           2 :                 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
    1437             :                            "SA Query procedure", reassoc ? "re" : "");
    1438             :                 /* TODO: Send a protected Disassociate frame to the STA using
    1439             :                  * the old key and Reason Code "Previous Authentication no
    1440             :                  * longer valid". Make sure this is only sent protected since
    1441             :                  * unprotected frame would be received by the STA that is now
    1442             :                  * trying to associate.
    1443             :                  */
    1444             :         }
    1445             : #endif /* CONFIG_IEEE80211W */
    1446             : 
    1447             :         /* Make sure that the previously registered inactivity timer will not
    1448             :          * remove the STA immediately. */
    1449        1299 :         sta->timeout_next = STA_NULLFUNC;
    1450             : 
    1451             :  fail:
    1452        1310 :         send_assoc_resp(hapd, sta, resp, reassoc, pos, left);
    1453             : }
    1454             : 
    1455             : 
    1456           1 : static void handle_disassoc(struct hostapd_data *hapd,
    1457             :                             const struct ieee80211_mgmt *mgmt, size_t len)
    1458             : {
    1459             :         struct sta_info *sta;
    1460             : 
    1461           1 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
    1462           0 :                 wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
    1463             :                            (unsigned long) len);
    1464           0 :                 return;
    1465             :         }
    1466             : 
    1467           7 :         wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
    1468           6 :                    MAC2STR(mgmt->sa),
    1469           1 :                    le_to_host16(mgmt->u.disassoc.reason_code));
    1470             : 
    1471           1 :         sta = ap_get_sta(hapd, mgmt->sa);
    1472           1 :         if (sta == NULL) {
    1473           0 :                 wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated",
    1474           0 :                            MAC2STR(mgmt->sa));
    1475           0 :                 return;
    1476             :         }
    1477             : 
    1478           1 :         ap_sta_set_authorized(hapd, sta, 0);
    1479           1 :         sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
    1480           1 :         wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
    1481           1 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1482             :                        HOSTAPD_LEVEL_INFO, "disassociated");
    1483           1 :         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    1484           1 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    1485             :         /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
    1486             :          * authenticated. */
    1487           1 :         accounting_sta_stop(hapd, sta);
    1488           1 :         ieee802_1x_free_station(sta);
    1489           1 :         hostapd_drv_sta_remove(hapd, sta->addr);
    1490             : 
    1491           1 :         if (sta->timeout_next == STA_NULLFUNC ||
    1492           0 :             sta->timeout_next == STA_DISASSOC) {
    1493           1 :                 sta->timeout_next = STA_DEAUTH;
    1494           1 :                 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    1495           1 :                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
    1496             :                                        hapd, sta);
    1497             :         }
    1498             : 
    1499           1 :         mlme_disassociate_indication(
    1500           1 :                 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
    1501             : }
    1502             : 
    1503             : 
    1504         944 : static void handle_deauth(struct hostapd_data *hapd,
    1505             :                           const struct ieee80211_mgmt *mgmt, size_t len)
    1506             : {
    1507             :         struct sta_info *sta;
    1508             : 
    1509         944 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
    1510           0 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
    1511             :                         "payload (len=%lu)", (unsigned long) len);
    1512           0 :                 return;
    1513             :         }
    1514             : 
    1515        6608 :         wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
    1516             :                 " reason_code=%d",
    1517        6608 :                 MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
    1518             : 
    1519         944 :         sta = ap_get_sta(hapd, mgmt->sa);
    1520         944 :         if (sta == NULL) {
    1521           0 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
    1522             :                         "to deauthenticate, but it is not authenticated",
    1523           0 :                         MAC2STR(mgmt->sa));
    1524           0 :                 return;
    1525             :         }
    1526             : 
    1527         944 :         ap_sta_set_authorized(hapd, sta, 0);
    1528         944 :         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
    1529             :                         WLAN_STA_ASSOC_REQ_OK);
    1530         944 :         wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
    1531         944 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1532             :                        HOSTAPD_LEVEL_DEBUG, "deauthenticated");
    1533         944 :         mlme_deauthenticate_indication(
    1534         944 :                 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
    1535         944 :         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    1536         944 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    1537         944 :         ap_free_sta(hapd, sta);
    1538             : }
    1539             : 
    1540             : 
    1541        2667 : static void handle_beacon(struct hostapd_data *hapd,
    1542             :                           const struct ieee80211_mgmt *mgmt, size_t len,
    1543             :                           struct hostapd_frame_info *fi)
    1544             : {
    1545             :         struct ieee802_11_elems elems;
    1546             : 
    1547        2667 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
    1548           0 :                 wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
    1549             :                            (unsigned long) len);
    1550        2667 :                 return;
    1551             :         }
    1552             : 
    1553        2667 :         (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
    1554             :                                       len - (IEEE80211_HDRLEN +
    1555             :                                              sizeof(mgmt->u.beacon)), &elems,
    1556             :                                       0);
    1557             : 
    1558        2667 :         ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
    1559             : }
    1560             : 
    1561             : 
    1562             : #ifdef CONFIG_IEEE80211W
    1563             : 
    1564           2 : static int hostapd_sa_query_action(struct hostapd_data *hapd,
    1565             :                                    const struct ieee80211_mgmt *mgmt,
    1566             :                                    size_t len)
    1567             : {
    1568             :         const u8 *end;
    1569             : 
    1570           2 :         end = mgmt->u.action.u.sa_query_resp.trans_id +
    1571             :                 WLAN_SA_QUERY_TR_ID_LEN;
    1572           2 :         if (((u8 *) mgmt) + len < end) {
    1573           0 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
    1574             :                            "frame (len=%lu)", (unsigned long) len);
    1575           0 :                 return 0;
    1576             :         }
    1577             : 
    1578           2 :         ieee802_11_sa_query_action(hapd, mgmt->sa,
    1579           2 :                                    mgmt->u.action.u.sa_query_resp.action,
    1580           2 :                                    mgmt->u.action.u.sa_query_resp.trans_id);
    1581           2 :         return 1;
    1582             : }
    1583             : 
    1584             : 
    1585           0 : static int robust_action_frame(u8 category)
    1586             : {
    1587           0 :         return category != WLAN_ACTION_PUBLIC &&
    1588             :                 category != WLAN_ACTION_HT;
    1589             : }
    1590             : #endif /* CONFIG_IEEE80211W */
    1591             : 
    1592             : 
    1593         359 : static int handle_action(struct hostapd_data *hapd,
    1594             :                          const struct ieee80211_mgmt *mgmt, size_t len)
    1595             : {
    1596             :         struct sta_info *sta;
    1597         359 :         sta = ap_get_sta(hapd, mgmt->sa);
    1598             : 
    1599         359 :         if (len < IEEE80211_HDRLEN + 1) {
    1600           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1601             :                                HOSTAPD_LEVEL_DEBUG,
    1602             :                                "handle_action - too short payload (len=%lu)",
    1603             :                                (unsigned long) len);
    1604           0 :                 return 0;
    1605             :         }
    1606             : 
    1607         359 :         if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
    1608         135 :             (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
    1609           0 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
    1610             :                            "frame (category=%u) from unassociated STA " MACSTR,
    1611           0 :                            MAC2STR(mgmt->sa), mgmt->u.action.category);
    1612           0 :                 return 0;
    1613             :         }
    1614             : 
    1615             : #ifdef CONFIG_IEEE80211W
    1616         370 :         if (sta && (sta->flags & WLAN_STA_MFP) &&
    1617          11 :             !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
    1618           0 :             robust_action_frame(mgmt->u.action.category)) {
    1619           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1620             :                                HOSTAPD_LEVEL_DEBUG,
    1621             :                                "Dropped unprotected Robust Action frame from "
    1622             :                                "an MFP STA");
    1623           0 :                 return 0;
    1624             :         }
    1625             : #endif /* CONFIG_IEEE80211W */
    1626             : 
    1627         359 :         switch (mgmt->u.action.category) {
    1628             : #ifdef CONFIG_IEEE80211R
    1629             :         case WLAN_ACTION_FT:
    1630         226 :                 if (!sta ||
    1631         113 :                     wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
    1632             :                                      len - IEEE80211_HDRLEN))
    1633             :                         break;
    1634         113 :                 return 1;
    1635             : #endif /* CONFIG_IEEE80211R */
    1636             :         case WLAN_ACTION_WMM:
    1637           0 :                 hostapd_wmm_action(hapd, mgmt, len);
    1638           0 :                 return 1;
    1639             : #ifdef CONFIG_IEEE80211W
    1640             :         case WLAN_ACTION_SA_QUERY:
    1641           2 :                 return hostapd_sa_query_action(hapd, mgmt, len);
    1642             : #endif /* CONFIG_IEEE80211W */
    1643             : #ifdef CONFIG_WNM
    1644             :         case WLAN_ACTION_WNM:
    1645          18 :                 ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
    1646          18 :                 return 1;
    1647             : #endif /* CONFIG_WNM */
    1648             :         case WLAN_ACTION_PUBLIC:
    1649             :         case WLAN_ACTION_PROTECTED_DUAL:
    1650             : #ifdef CONFIG_IEEE80211N
    1651         225 :                 if (mgmt->u.action.u.public_action.action ==
    1652             :                     WLAN_PA_20_40_BSS_COEX) {
    1653          24 :                         wpa_printf(MSG_DEBUG,
    1654             :                                    "HT20/40 coex mgmt frame received from STA "
    1655          24 :                                    MACSTR, MAC2STR(mgmt->sa));
    1656           4 :                         hostapd_2040_coex_action(hapd, mgmt, len);
    1657             :                 }
    1658             : #endif /* CONFIG_IEEE80211N */
    1659         225 :                 if (hapd->public_action_cb) {
    1660           0 :                         hapd->public_action_cb(hapd->public_action_cb_ctx,
    1661             :                                                (u8 *) mgmt, len,
    1662           0 :                                                hapd->iface->freq);
    1663             :                 }
    1664         225 :                 if (hapd->public_action_cb2) {
    1665         450 :                         hapd->public_action_cb2(hapd->public_action_cb2_ctx,
    1666             :                                                 (u8 *) mgmt, len,
    1667         225 :                                                 hapd->iface->freq);
    1668             :                 }
    1669         225 :                 if (hapd->public_action_cb || hapd->public_action_cb2)
    1670         225 :                         return 1;
    1671           0 :                 break;
    1672             :         case WLAN_ACTION_VENDOR_SPECIFIC:
    1673           0 :                 if (hapd->vendor_action_cb) {
    1674           0 :                         if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
    1675             :                                                    (u8 *) mgmt, len,
    1676           0 :                                                    hapd->iface->freq) == 0)
    1677           0 :                                 return 1;
    1678             :                 }
    1679           0 :                 break;
    1680             :         }
    1681             : 
    1682           1 :         hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1683             :                        HOSTAPD_LEVEL_DEBUG,
    1684             :                        "handle_action - unknown action category %d or invalid "
    1685             :                        "frame",
    1686           1 :                        mgmt->u.action.category);
    1687           2 :         if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
    1688           1 :             !(mgmt->sa[0] & 0x01)) {
    1689             :                 struct ieee80211_mgmt *resp;
    1690             : 
    1691             :                 /*
    1692             :                  * IEEE 802.11-REVma/D9.0 - 7.3.1.11
    1693             :                  * Return the Action frame to the source without change
    1694             :                  * except that MSB of the Category set to 1.
    1695             :                  */
    1696           1 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
    1697             :                            "frame back to sender");
    1698           1 :                 resp = os_malloc(len);
    1699           1 :                 if (resp == NULL)
    1700           0 :                         return 0;
    1701           1 :                 os_memcpy(resp, mgmt, len);
    1702           1 :                 os_memcpy(resp->da, resp->sa, ETH_ALEN);
    1703           1 :                 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
    1704           1 :                 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
    1705           1 :                 resp->u.action.category |= 0x80;
    1706             : 
    1707           1 :                 if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
    1708           0 :                         wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
    1709             :                                    "Action frame");
    1710             :                 }
    1711           1 :                 os_free(resp);
    1712             :         }
    1713             : 
    1714           1 :         return 1;
    1715             : }
    1716             : 
    1717             : 
    1718             : /**
    1719             :  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
    1720             :  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
    1721             :  * sent to)
    1722             :  * @buf: management frame data (starting from IEEE 802.11 header)
    1723             :  * @len: length of frame data in octets
    1724             :  * @fi: meta data about received frame (signal level, etc.)
    1725             :  *
    1726             :  * Process all incoming IEEE 802.11 management frames. This will be called for
    1727             :  * each frame received from the kernel driver through wlan#ap interface. In
    1728             :  * addition, it can be called to re-inserted pending frames (e.g., when using
    1729             :  * external RADIUS server as an MAC ACL).
    1730             :  */
    1731        8011 : int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
    1732             :                     struct hostapd_frame_info *fi)
    1733             : {
    1734             :         struct ieee80211_mgmt *mgmt;
    1735             :         int broadcast;
    1736             :         u16 fc, stype;
    1737        8011 :         int ret = 0;
    1738             : 
    1739        8011 :         if (len < 24)
    1740           0 :                 return 0;
    1741             : 
    1742        8011 :         mgmt = (struct ieee80211_mgmt *) buf;
    1743        8011 :         fc = le_to_host16(mgmt->frame_control);
    1744        8011 :         stype = WLAN_FC_GET_STYPE(fc);
    1745             : 
    1746        8011 :         if (stype == WLAN_FC_STYPE_BEACON) {
    1747        2667 :                 handle_beacon(hapd, mgmt, len, fi);
    1748        2667 :                 return 1;
    1749             :         }
    1750             : 
    1751       13448 :         broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
    1752        4140 :                 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
    1753        8104 :                 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
    1754             : 
    1755        9308 :         if (!broadcast &&
    1756             : #ifdef CONFIG_P2P
    1757             :             /* Invitation responses can be sent with the peer MAC as BSSID */
    1758             :             !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
    1759             :               stype == WLAN_FC_STYPE_ACTION) &&
    1760             : #endif /* CONFIG_P2P */
    1761        3964 :             os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
    1762           0 :                 wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
    1763           0 :                            MAC2STR(mgmt->bssid));
    1764           0 :                 return 0;
    1765             :         }
    1766             : 
    1767             : 
    1768        5344 :         if (stype == WLAN_FC_STYPE_PROBE_REQ) {
    1769        1475 :                 handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
    1770        1475 :                 return 1;
    1771             :         }
    1772             : 
    1773        3869 :         if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
    1774           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1775             :                                HOSTAPD_LEVEL_DEBUG,
    1776             :                                "MGMT: DA=" MACSTR " not our address",
    1777           0 :                                MAC2STR(mgmt->da));
    1778           0 :                 return 0;
    1779             :         }
    1780             : 
    1781        3869 :         switch (stype) {
    1782             :         case WLAN_FC_STYPE_AUTH:
    1783        1254 :                 wpa_printf(MSG_DEBUG, "mgmt::auth");
    1784        1254 :                 handle_auth(hapd, mgmt, len);
    1785        1254 :                 ret = 1;
    1786        1254 :                 break;
    1787             :         case WLAN_FC_STYPE_ASSOC_REQ:
    1788        1053 :                 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
    1789        1053 :                 handle_assoc(hapd, mgmt, len, 0);
    1790        1053 :                 ret = 1;
    1791        1053 :                 break;
    1792             :         case WLAN_FC_STYPE_REASSOC_REQ:
    1793         258 :                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
    1794         258 :                 handle_assoc(hapd, mgmt, len, 1);
    1795         258 :                 ret = 1;
    1796         258 :                 break;
    1797             :         case WLAN_FC_STYPE_DISASSOC:
    1798           1 :                 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
    1799           1 :                 handle_disassoc(hapd, mgmt, len);
    1800           1 :                 ret = 1;
    1801           1 :                 break;
    1802             :         case WLAN_FC_STYPE_DEAUTH:
    1803         944 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
    1804         944 :                 handle_deauth(hapd, mgmt, len);
    1805         944 :                 ret = 1;
    1806         944 :                 break;
    1807             :         case WLAN_FC_STYPE_ACTION:
    1808         359 :                 wpa_printf(MSG_DEBUG, "mgmt::action");
    1809         359 :                 ret = handle_action(hapd, mgmt, len);
    1810         359 :                 break;
    1811             :         default:
    1812           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    1813             :                                HOSTAPD_LEVEL_DEBUG,
    1814             :                                "unknown mgmt frame subtype %d", stype);
    1815           0 :                 break;
    1816             :         }
    1817             : 
    1818        3869 :         return ret;
    1819             : }
    1820             : 
    1821             : 
    1822        1249 : static void handle_auth_cb(struct hostapd_data *hapd,
    1823             :                            const struct ieee80211_mgmt *mgmt,
    1824             :                            size_t len, int ok)
    1825             : {
    1826             :         u16 auth_alg, auth_transaction, status_code;
    1827             :         struct sta_info *sta;
    1828             : 
    1829        1249 :         if (!ok) {
    1830           0 :                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
    1831             :                                HOSTAPD_LEVEL_NOTICE,
    1832             :                                "did not acknowledge authentication response");
    1833           0 :                 return;
    1834             :         }
    1835             : 
    1836        1249 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
    1837           0 :                 wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
    1838             :                            (unsigned long) len);
    1839           0 :                 return;
    1840             :         }
    1841             : 
    1842        1249 :         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    1843        1249 :         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
    1844        1249 :         status_code = le_to_host16(mgmt->u.auth.status_code);
    1845             : 
    1846        1249 :         sta = ap_get_sta(hapd, mgmt->da);
    1847        1249 :         if (!sta) {
    1848          90 :                 wpa_printf(MSG_INFO, "handle_auth_cb: STA " MACSTR " not found",
    1849          90 :                            MAC2STR(mgmt->da));
    1850          15 :                 return;
    1851             :         }
    1852             : 
    1853        1234 :         if (status_code == WLAN_STATUS_SUCCESS &&
    1854        1065 :             ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
    1855           4 :              (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
    1856        1067 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1857             :                                HOSTAPD_LEVEL_INFO, "authenticated");
    1858        1067 :                 sta->flags |= WLAN_STA_AUTH;
    1859             :         }
    1860             : }
    1861             : 
    1862             : 
    1863           1 : static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
    1864             :                                        struct sta_info *sta,
    1865             :                                        char *ifname_wds)
    1866             : {
    1867             :         int i;
    1868           1 :         struct hostapd_ssid *ssid = sta->ssid;
    1869             : 
    1870           1 :         if (hapd->conf->ieee802_1x || hapd->conf->wpa)
    1871           2 :                 return;
    1872             : 
    1873           0 :         for (i = 0; i < 4; i++) {
    1874           0 :                 if (ssid->wep.key[i] &&
    1875           0 :                     hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
    1876           0 :                                         i == ssid->wep.idx, NULL, 0,
    1877           0 :                                         ssid->wep.key[i], ssid->wep.len[i])) {
    1878           0 :                         wpa_printf(MSG_WARNING,
    1879             :                                    "Could not set WEP keys for WDS interface; %s",
    1880             :                                    ifname_wds);
    1881           0 :                         break;
    1882             :                 }
    1883             :         }
    1884             : }
    1885             : 
    1886             : 
    1887        1310 : static void handle_assoc_cb(struct hostapd_data *hapd,
    1888             :                             const struct ieee80211_mgmt *mgmt,
    1889             :                             size_t len, int reassoc, int ok)
    1890             : {
    1891             :         u16 status;
    1892             :         struct sta_info *sta;
    1893        1310 :         int new_assoc = 1;
    1894             :         struct ieee80211_ht_capabilities ht_cap;
    1895             :         struct ieee80211_vht_capabilities vht_cap;
    1896             : 
    1897        1310 :         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
    1898             :                                       sizeof(mgmt->u.assoc_resp))) {
    1899           0 :                 wpa_printf(MSG_INFO, "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
    1900             :                            reassoc, (unsigned long) len);
    1901           0 :                 return;
    1902             :         }
    1903             : 
    1904        1310 :         sta = ap_get_sta(hapd, mgmt->da);
    1905        1310 :         if (!sta) {
    1906           0 :                 wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
    1907           0 :                            MAC2STR(mgmt->da));
    1908           0 :                 return;
    1909             :         }
    1910             : 
    1911        1310 :         if (!ok) {
    1912           0 :                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
    1913             :                                HOSTAPD_LEVEL_DEBUG,
    1914             :                                "did not acknowledge association response");
    1915           0 :                 sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
    1916           0 :                 return;
    1917             :         }
    1918             : 
    1919        1310 :         if (reassoc)
    1920         258 :                 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
    1921             :         else
    1922        1052 :                 status = le_to_host16(mgmt->u.assoc_resp.status_code);
    1923             : 
    1924        1310 :         if (status != WLAN_STATUS_SUCCESS)
    1925          11 :                 return;
    1926             : 
    1927             :         /* Stop previous accounting session, if one is started, and allocate
    1928             :          * new session id for the new session. */
    1929        1299 :         accounting_sta_stop(hapd, sta);
    1930             : 
    1931        1299 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1932             :                        HOSTAPD_LEVEL_INFO,
    1933             :                        "associated (aid %d)",
    1934        1299 :                        sta->aid);
    1935             : 
    1936        1299 :         if (sta->flags & WLAN_STA_ASSOC)
    1937           4 :                 new_assoc = 0;
    1938        1299 :         sta->flags |= WLAN_STA_ASSOC;
    1939        1299 :         sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
    1940        2397 :         if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) ||
    1941        1098 :             sta->auth_alg == WLAN_AUTH_FT) {
    1942             :                 /*
    1943             :                  * Open, static WEP, or FT protocol; no separate authorization
    1944             :                  * step.
    1945             :                  */
    1946         422 :                 ap_sta_set_authorized(hapd, sta, 1);
    1947             :         }
    1948             : 
    1949        1299 :         if (reassoc)
    1950         257 :                 mlme_reassociate_indication(hapd, sta);
    1951             :         else
    1952        1042 :                 mlme_associate_indication(hapd, sta);
    1953             : 
    1954             : #ifdef CONFIG_IEEE80211W
    1955        1299 :         sta->sa_query_timed_out = 0;
    1956             : #endif /* CONFIG_IEEE80211W */
    1957             : 
    1958             :         /*
    1959             :          * Remove the STA entry in order to make sure the STA PS state gets
    1960             :          * cleared and configuration gets updated in case of reassociation back
    1961             :          * to the same AP.
    1962             :          */
    1963        1299 :         hostapd_drv_sta_remove(hapd, sta->addr);
    1964             : 
    1965             : #ifdef CONFIG_IEEE80211N
    1966        1299 :         if (sta->flags & WLAN_STA_HT)
    1967        1276 :                 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
    1968             : #endif /* CONFIG_IEEE80211N */
    1969             : #ifdef CONFIG_IEEE80211AC
    1970        1299 :         if (sta->flags & WLAN_STA_VHT)
    1971           6 :                 hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
    1972             : #endif /* CONFIG_IEEE80211AC */
    1973             : 
    1974        9093 :         if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
    1975        2598 :                             sta->supported_rates, sta->supported_rates_len,
    1976        1299 :                             sta->listen_interval,
    1977        1299 :                             sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
    1978        1299 :                             sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
    1979        2598 :                             sta->flags, sta->qosinfo, sta->vht_opmode)) {
    1980           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1981             :                                HOSTAPD_LEVEL_NOTICE,
    1982             :                                "Could not add STA to kernel driver");
    1983             : 
    1984           0 :                 ap_sta_disconnect(hapd, sta, sta->addr,
    1985             :                                   WLAN_REASON_DISASSOC_AP_BUSY);
    1986             : 
    1987           0 :                 return;
    1988             :         }
    1989             : 
    1990        1299 :         if (sta->flags & WLAN_STA_WDS) {
    1991             :                 int ret;
    1992             :                 char ifname_wds[IFNAMSIZ + 1];
    1993             : 
    1994           0 :                 ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
    1995           0 :                                           sta->aid, 1);
    1996           0 :                 if (!ret)
    1997           0 :                         hostapd_set_wds_encryption(hapd, sta, ifname_wds);
    1998             :         }
    1999             : 
    2000        1299 :         if (sta->eapol_sm == NULL) {
    2001             :                 /*
    2002             :                  * This STA does not use RADIUS server for EAP authentication,
    2003             :                  * so bind it to the selected VLAN interface now, since the
    2004             :                  * interface selection is not going to change anymore.
    2005             :                  */
    2006        1274 :                 if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
    2007           0 :                         return;
    2008          25 :         } else if (sta->vlan_id) {
    2009             :                 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
    2010           0 :                 if (ap_sta_bind_vlan(hapd, sta, 0) < 0)
    2011           0 :                         return;
    2012             :         }
    2013             : 
    2014        1299 :         hostapd_set_sta_flags(hapd, sta);
    2015             : 
    2016        1299 :         if (sta->auth_alg == WLAN_AUTH_FT)
    2017         221 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
    2018             :         else
    2019        1078 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
    2020        1299 :         hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
    2021             : 
    2022        1299 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
    2023             : }
    2024             : 
    2025             : 
    2026         207 : static void handle_deauth_cb(struct hostapd_data *hapd,
    2027             :                              const struct ieee80211_mgmt *mgmt,
    2028             :                              size_t len, int ok)
    2029             : {
    2030             :         struct sta_info *sta;
    2031         207 :         if (mgmt->da[0] & 0x01)
    2032          19 :                 return;
    2033         188 :         sta = ap_get_sta(hapd, mgmt->da);
    2034         188 :         if (!sta) {
    2035         642 :                 wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
    2036         642 :                            " not found", MAC2STR(mgmt->da));
    2037         107 :                 return;
    2038             :         }
    2039          81 :         if (ok)
    2040         468 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
    2041         468 :                            MAC2STR(sta->addr));
    2042             :         else
    2043          18 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
    2044          18 :                            "deauth", MAC2STR(sta->addr));
    2045             : 
    2046          81 :         ap_sta_deauth_cb(hapd, sta);
    2047             : }
    2048             : 
    2049             : 
    2050           4 : static void handle_disassoc_cb(struct hostapd_data *hapd,
    2051             :                                const struct ieee80211_mgmt *mgmt,
    2052             :                                size_t len, int ok)
    2053             : {
    2054             :         struct sta_info *sta;
    2055           4 :         if (mgmt->da[0] & 0x01)
    2056           1 :                 return;
    2057           3 :         sta = ap_get_sta(hapd, mgmt->da);
    2058           3 :         if (!sta) {
    2059           0 :                 wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
    2060           0 :                            " not found", MAC2STR(mgmt->da));
    2061           0 :                 return;
    2062             :         }
    2063           3 :         if (ok)
    2064           6 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
    2065           6 :                            MAC2STR(sta->addr));
    2066             :         else
    2067          12 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
    2068          12 :                            "disassoc", MAC2STR(sta->addr));
    2069             : 
    2070           3 :         ap_sta_disassoc_cb(hapd, sta);
    2071             : }
    2072             : 
    2073             : 
    2074             : /**
    2075             :  * ieee802_11_mgmt_cb - Process management frame TX status callback
    2076             :  * @hapd: hostapd BSS data structure (the BSS from which the management frame
    2077             :  * was sent from)
    2078             :  * @buf: management frame data (starting from IEEE 802.11 header)
    2079             :  * @len: length of frame data in octets
    2080             :  * @stype: management frame subtype from frame control field
    2081             :  * @ok: Whether the frame was ACK'ed
    2082             :  */
    2083        3448 : void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
    2084             :                         u16 stype, int ok)
    2085             : {
    2086             :         const struct ieee80211_mgmt *mgmt;
    2087        3448 :         mgmt = (const struct ieee80211_mgmt *) buf;
    2088             : 
    2089             : #ifdef CONFIG_TESTING_OPTIONS
    2090        3448 :         if (hapd->ext_mgmt_frame_handling) {
    2091         185 :                 wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d",
    2092             :                         stype, ok);
    2093        3633 :                 return;
    2094             :         }
    2095             : #endif /* CONFIG_TESTING_OPTIONS */
    2096             : 
    2097        3263 :         switch (stype) {
    2098             :         case WLAN_FC_STYPE_AUTH:
    2099        1249 :                 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
    2100        1249 :                 handle_auth_cb(hapd, mgmt, len, ok);
    2101        1249 :                 break;
    2102             :         case WLAN_FC_STYPE_ASSOC_RESP:
    2103        1052 :                 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
    2104        1052 :                 handle_assoc_cb(hapd, mgmt, len, 0, ok);
    2105        1052 :                 break;
    2106             :         case WLAN_FC_STYPE_REASSOC_RESP:
    2107         258 :                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
    2108         258 :                 handle_assoc_cb(hapd, mgmt, len, 1, ok);
    2109         258 :                 break;
    2110             :         case WLAN_FC_STYPE_PROBE_RESP:
    2111         116 :                 wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb");
    2112         116 :                 break;
    2113             :         case WLAN_FC_STYPE_DEAUTH:
    2114         207 :                 wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
    2115         207 :                 handle_deauth_cb(hapd, mgmt, len, ok);
    2116         207 :                 break;
    2117             :         case WLAN_FC_STYPE_DISASSOC:
    2118           4 :                 wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
    2119           4 :                 handle_disassoc_cb(hapd, mgmt, len, ok);
    2120           4 :                 break;
    2121             :         case WLAN_FC_STYPE_ACTION:
    2122         377 :                 wpa_printf(MSG_DEBUG, "mgmt::action cb");
    2123         377 :                 break;
    2124             :         default:
    2125           0 :                 wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
    2126           0 :                 break;
    2127             :         }
    2128             : }
    2129             : 
    2130             : 
    2131           7 : int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
    2132             : {
    2133             :         /* TODO */
    2134           7 :         return 0;
    2135             : }
    2136             : 
    2137             : 
    2138          30 : int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
    2139             :                            char *buf, size_t buflen)
    2140             : {
    2141             :         /* TODO */
    2142          30 :         return 0;
    2143             : }
    2144             : 
    2145             : 
    2146           0 : void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
    2147             :                        const u8 *buf, size_t len, int ack)
    2148             : {
    2149             :         struct sta_info *sta;
    2150           0 :         struct hostapd_iface *iface = hapd->iface;
    2151             : 
    2152           0 :         sta = ap_get_sta(hapd, addr);
    2153           0 :         if (sta == NULL && iface->num_bss > 1) {
    2154             :                 size_t j;
    2155           0 :                 for (j = 0; j < iface->num_bss; j++) {
    2156           0 :                         hapd = iface->bss[j];
    2157           0 :                         sta = ap_get_sta(hapd, addr);
    2158           0 :                         if (sta)
    2159           0 :                                 break;
    2160             :                 }
    2161             :         }
    2162           0 :         if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
    2163           0 :                 return;
    2164           0 :         if (sta->flags & WLAN_STA_PENDING_POLL) {
    2165           0 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
    2166           0 :                            "activity poll", MAC2STR(sta->addr),
    2167             :                            ack ? "ACKed" : "did not ACK");
    2168           0 :                 if (ack)
    2169           0 :                         sta->flags &= ~WLAN_STA_PENDING_POLL;
    2170             :         }
    2171             : 
    2172           0 :         ieee802_1x_tx_status(hapd, sta, buf, len, ack);
    2173             : }
    2174             : 
    2175             : 
    2176        4775 : void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
    2177             :                              const u8 *data, size_t len, int ack)
    2178             : {
    2179             :         struct sta_info *sta;
    2180        4775 :         struct hostapd_iface *iface = hapd->iface;
    2181             : 
    2182        4775 :         sta = ap_get_sta(hapd, dst);
    2183        4775 :         if (sta == NULL && iface->num_bss > 1) {
    2184             :                 size_t j;
    2185          13 :                 for (j = 0; j < iface->num_bss; j++) {
    2186          13 :                         hapd = iface->bss[j];
    2187          13 :                         sta = ap_get_sta(hapd, dst);
    2188          13 :                         if (sta)
    2189           5 :                                 break;
    2190             :                 }
    2191             :         }
    2192        4775 :         if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
    2193        1032 :                 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
    2194             :                            MACSTR " that is not currently associated",
    2195        1032 :                            MAC2STR(dst));
    2196        4947 :                 return;
    2197             :         }
    2198             : 
    2199        4603 :         ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
    2200             : }
    2201             : 
    2202             : 
    2203           0 : void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
    2204             : {
    2205             :         struct sta_info *sta;
    2206           0 :         struct hostapd_iface *iface = hapd->iface;
    2207             : 
    2208           0 :         sta = ap_get_sta(hapd, addr);
    2209           0 :         if (sta == NULL && iface->num_bss > 1) {
    2210             :                 size_t j;
    2211           0 :                 for (j = 0; j < iface->num_bss; j++) {
    2212           0 :                         hapd = iface->bss[j];
    2213           0 :                         sta = ap_get_sta(hapd, addr);
    2214           0 :                         if (sta)
    2215           0 :                                 break;
    2216             :                 }
    2217             :         }
    2218           0 :         if (sta == NULL)
    2219           0 :                 return;
    2220           0 :         if (!(sta->flags & WLAN_STA_PENDING_POLL))
    2221           0 :                 return;
    2222             : 
    2223           0 :         wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
    2224           0 :                    "activity poll", MAC2STR(sta->addr));
    2225           0 :         sta->flags &= ~WLAN_STA_PENDING_POLL;
    2226             : }
    2227             : 
    2228             : 
    2229           7 : void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
    2230             :                                 int wds)
    2231             : {
    2232             :         struct sta_info *sta;
    2233             : 
    2234           7 :         sta = ap_get_sta(hapd, src);
    2235           7 :         if (sta && (sta->flags & WLAN_STA_ASSOC)) {
    2236           7 :                 if (!hapd->conf->wds_sta)
    2237           5 :                         return;
    2238             : 
    2239           2 :                 if (wds && !(sta->flags & WLAN_STA_WDS)) {
    2240             :                         int ret;
    2241             :                         char ifname_wds[IFNAMSIZ + 1];
    2242             : 
    2243           7 :                         wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
    2244             :                                    "STA " MACSTR " (aid %u)",
    2245           7 :                                    MAC2STR(sta->addr), sta->aid);
    2246           1 :                         sta->flags |= WLAN_STA_WDS;
    2247           2 :                         ret = hostapd_set_wds_sta(hapd, ifname_wds,
    2248           2 :                                                   sta->addr, sta->aid, 1);
    2249           1 :                         if (!ret)
    2250           1 :                                 hostapd_set_wds_encryption(hapd, sta,
    2251             :                                                            ifname_wds);
    2252             :                 }
    2253           2 :                 return;
    2254             :         }
    2255             : 
    2256           0 :         wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
    2257           0 :                    MACSTR, MAC2STR(src));
    2258           0 :         if (src[0] & 0x01) {
    2259             :                 /* Broadcast bit set in SA?! Ignore the frame silently. */
    2260           0 :                 return;
    2261             :         }
    2262             : 
    2263           0 :         if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
    2264           0 :                 wpa_printf(MSG_DEBUG, "Association Response to the STA has "
    2265             :                            "already been sent, but no TX status yet known - "
    2266             :                            "ignore Class 3 frame issue with " MACSTR,
    2267           0 :                            MAC2STR(src));
    2268           0 :                 return;
    2269             :         }
    2270             : 
    2271           0 :         if (sta && (sta->flags & WLAN_STA_AUTH))
    2272           0 :                 hostapd_drv_sta_disassoc(
    2273             :                         hapd, src,
    2274             :                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
    2275             :         else
    2276           0 :                 hostapd_drv_sta_deauth(
    2277             :                         hapd, src,
    2278             :                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
    2279             : }
    2280             : 
    2281             : 
    2282             : #endif /* CONFIG_NATIVE_WINDOWS */

Generated by: LCOV version 1.10