LCOV - code coverage report
Current view: top level - src/ap - ieee802_11.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 912 1171 77.9 %
Date: 2014-05-28 Functions: 38 41 92.7 %

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

Generated by: LCOV version 1.10