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 1475438200 Lines: 1245 1618 76.9 %
Date: 2016-10-02 Functions: 50 52 96.2 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / IEEE 802.11 Management
       3             :  * Copyright (c) 2002-2014, 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 "fst/fst.h"
      27             : #include "hostapd.h"
      28             : #include "beacon.h"
      29             : #include "ieee802_11_auth.h"
      30             : #include "sta_info.h"
      31             : #include "ieee802_1x.h"
      32             : #include "wpa_auth.h"
      33             : #include "pmksa_cache_auth.h"
      34             : #include "wmm.h"
      35             : #include "ap_list.h"
      36             : #include "accounting.h"
      37             : #include "ap_config.h"
      38             : #include "ap_mlme.h"
      39             : #include "p2p_hostapd.h"
      40             : #include "ap_drv_ops.h"
      41             : #include "wnm_ap.h"
      42             : #include "hw_features.h"
      43             : #include "ieee802_11.h"
      44             : #include "dfs.h"
      45             : #include "mbo_ap.h"
      46             : #include "rrm.h"
      47             : #include "taxonomy.h"
      48             : 
      49             : 
      50       15251 : u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
      51             : {
      52       15251 :         u8 *pos = eid;
      53             :         int i, num, count;
      54             : 
      55       15251 :         if (hapd->iface->current_rates == NULL)
      56          17 :                 return eid;
      57             : 
      58       15234 :         *pos++ = WLAN_EID_SUPP_RATES;
      59       15234 :         num = hapd->iface->num_rates;
      60       15234 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
      61          17 :                 num++;
      62       15234 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
      63           8 :                 num++;
      64       15234 :         if (num > 8) {
      65             :                 /* rest of the rates are encoded in Extended supported
      66             :                  * rates element */
      67       11115 :                 num = 8;
      68             :         }
      69             : 
      70       15234 :         *pos++ = num;
      71      152200 :         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
      72      121732 :              i++) {
      73      121732 :                 count++;
      74      121732 :                 *pos = hapd->iface->current_rates[i].rate / 5;
      75      121732 :                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
      76       57294 :                         *pos |= 0x80;
      77      121732 :                 pos++;
      78             :         }
      79             : 
      80       15234 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
      81           5 :                 count++;
      82           5 :                 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
      83             :         }
      84             : 
      85       15234 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
      86           3 :                 count++;
      87           3 :                 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
      88             :         }
      89             : 
      90       15234 :         return pos;
      91             : }
      92             : 
      93             : 
      94       15251 : u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
      95             : {
      96       15251 :         u8 *pos = eid;
      97             :         int i, num, count;
      98             : 
      99       15251 :         if (hapd->iface->current_rates == NULL)
     100          17 :                 return eid;
     101             : 
     102       15234 :         num = hapd->iface->num_rates;
     103       15234 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
     104          17 :                 num++;
     105       15234 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
     106           8 :                 num++;
     107       15234 :         if (num <= 8)
     108        4119 :                 return eid;
     109       11115 :         num -= 8;
     110             : 
     111       11115 :         *pos++ = WLAN_EID_EXT_SUPP_RATES;
     112       11115 :         *pos++ = num;
     113      155590 :         for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
     114      133360 :              i++) {
     115      133360 :                 count++;
     116      133360 :                 if (count <= 8)
     117       88920 :                         continue; /* already in SuppRates IE */
     118       44440 :                 *pos = hapd->iface->current_rates[i].rate / 5;
     119       44440 :                 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
     120         278 :                         *pos |= 0x80;
     121       44440 :                 pos++;
     122             :         }
     123             : 
     124       11115 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
     125          12 :                 count++;
     126          12 :                 if (count > 8)
     127          12 :                         *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
     128             :         }
     129             : 
     130       11115 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
     131           5 :                 count++;
     132           5 :                 if (count > 8)
     133           5 :                         *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
     134             :         }
     135             : 
     136       11115 :         return pos;
     137             : }
     138             : 
     139             : 
     140       17583 : u16 hostapd_own_capab_info(struct hostapd_data *hapd)
     141             : {
     142       17583 :         int capab = WLAN_CAPABILITY_ESS;
     143             :         int privacy;
     144             :         int dfs;
     145             :         int i;
     146             : 
     147             :         /* Check if any of configured channels require DFS */
     148       17583 :         dfs = hostapd_is_dfs_required(hapd->iface);
     149       17583 :         if (dfs < 0) {
     150           0 :                 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
     151             :                            dfs);
     152           0 :                 dfs = 0;
     153             :         }
     154             : 
     155       34872 :         if (hapd->iface->num_sta_no_short_preamble == 0 &&
     156       17289 :             hapd->iconf->preamble == SHORT_PREAMBLE)
     157           4 :                 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
     158             : 
     159       17583 :         privacy = hapd->conf->ssid.wep.keys_set;
     160             : 
     161       22564 :         if (hapd->conf->ieee802_1x &&
     162        9938 :             (hapd->conf->default_wep_key_len ||
     163        4957 :              hapd->conf->individual_wep_key_len))
     164          24 :                 privacy = 1;
     165             : 
     166       17583 :         if (hapd->conf->wpa)
     167       12860 :                 privacy = 1;
     168             : 
     169             : #ifdef CONFIG_HS20
     170       17583 :         if (hapd->conf->osen)
     171          13 :                 privacy = 1;
     172             : #endif /* CONFIG_HS20 */
     173             : 
     174       17583 :         if (privacy)
     175       12998 :                 capab |= WLAN_CAPABILITY_PRIVACY;
     176             : 
     177       35142 :         if (hapd->iface->current_mode &&
     178       33790 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
     179       16231 :             hapd->iface->num_sta_no_short_slot_time == 0)
     180       16231 :                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
     181             : 
     182             :         /*
     183             :          * Currently, Spectrum Management capability bit is set when directly
     184             :          * requested in configuration by spectrum_mgmt_required or when AP is
     185             :          * running on DFS channel.
     186             :          * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
     187             :          */
     188       35142 :         if (hapd->iface->current_mode &&
     189       18847 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
     190        2572 :             (hapd->iconf->spectrum_mgmt_required || dfs))
     191          29 :                 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
     192             : 
     193      105423 :         for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
     194       87855 :                 if (hapd->conf->radio_measurements[i]) {
     195          15 :                         capab |= IEEE80211_CAP_RRM;
     196          15 :                         break;
     197             :                 }
     198             :         }
     199             : 
     200       17583 :         return capab;
     201             : }
     202             : 
     203             : 
     204             : #ifndef CONFIG_NO_RC4
     205          26 : 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          26 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     210             :                        HOSTAPD_LEVEL_DEBUG,
     211             :                        "authentication (shared key, transaction %d)",
     212             :                        auth_transaction);
     213             : 
     214          26 :         if (auth_transaction == 1) {
     215          13 :                 if (!sta->challenge) {
     216             :                         /* Generate a pseudo-random challenge */
     217             :                         u8 key[8];
     218             : 
     219          13 :                         sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
     220          13 :                         if (sta->challenge == NULL)
     221           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     222             : 
     223          13 :                         if (os_get_random(key, sizeof(key)) < 0) {
     224           0 :                                 os_free(sta->challenge);
     225           0 :                                 sta->challenge = NULL;
     226           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     227             :                         }
     228             : 
     229          13 :                         rc4_skip(key, sizeof(key), 0,
     230             :                                  sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
     231             :                 }
     232          13 :                 return 0;
     233             :         }
     234             : 
     235          13 :         if (auth_transaction != 3)
     236           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     237             : 
     238             :         /* Transaction 3 */
     239          26 :         if (!iswep || !sta->challenge || !challenge ||
     240          13 :             os_memcmp_const(sta->challenge, challenge,
     241             :                             WLAN_AUTH_CHALLENGE_LEN)) {
     242           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     243             :                                HOSTAPD_LEVEL_INFO,
     244             :                                "shared key authentication - invalid "
     245             :                                "challenge-response");
     246           0 :                 return WLAN_STATUS_CHALLENGE_FAIL;
     247             :         }
     248             : 
     249          13 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     250             :                        HOSTAPD_LEVEL_DEBUG,
     251             :                        "authentication OK (shared key)");
     252          13 :         sta->flags |= WLAN_STA_AUTH;
     253          13 :         wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
     254          13 :         os_free(sta->challenge);
     255          13 :         sta->challenge = NULL;
     256             : 
     257          13 :         return 0;
     258             : }
     259             : #endif /* CONFIG_NO_RC4 */
     260             : 
     261             : 
     262        5293 : static int send_auth_reply(struct hostapd_data *hapd,
     263             :                            const u8 *dst, const u8 *bssid,
     264             :                            u16 auth_alg, u16 auth_transaction, u16 resp,
     265             :                            const u8 *ies, size_t ies_len)
     266             : {
     267             :         struct ieee80211_mgmt *reply;
     268             :         u8 *buf;
     269             :         size_t rlen;
     270        5293 :         int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
     271             : 
     272        5293 :         rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
     273        5293 :         buf = os_zalloc(rlen);
     274        5293 :         if (buf == NULL)
     275           0 :                 return -1;
     276             : 
     277        5293 :         reply = (struct ieee80211_mgmt *) buf;
     278        5293 :         reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
     279             :                                             WLAN_FC_STYPE_AUTH);
     280        5293 :         os_memcpy(reply->da, dst, ETH_ALEN);
     281        5293 :         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
     282        5293 :         os_memcpy(reply->bssid, bssid, ETH_ALEN);
     283             : 
     284        5293 :         reply->u.auth.auth_alg = host_to_le16(auth_alg);
     285        5293 :         reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
     286        5293 :         reply->u.auth.status_code = host_to_le16(resp);
     287             : 
     288        5293 :         if (ies && ies_len)
     289         616 :                 os_memcpy(reply->u.auth.variable, ies, ies_len);
     290             : 
     291       37051 :         wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
     292             :                    " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
     293       31758 :                    MAC2STR(dst), auth_alg, auth_transaction,
     294             :                    resp, (unsigned long) ies_len);
     295        5293 :         if (hostapd_drv_send_mlme(hapd, reply, rlen, 0) < 0)
     296           0 :                 wpa_printf(MSG_INFO, "send_auth_reply: send failed");
     297             :         else
     298        5293 :                 reply_res = WLAN_STATUS_SUCCESS;
     299             : 
     300        5293 :         os_free(buf);
     301             : 
     302        5293 :         return reply_res;
     303             : }
     304             : 
     305             : 
     306             : #ifdef CONFIG_IEEE80211R
     307         123 : static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
     308             :                                   u16 auth_transaction, u16 status,
     309             :                                   const u8 *ies, size_t ies_len)
     310             : {
     311         123 :         struct hostapd_data *hapd = ctx;
     312             :         struct sta_info *sta;
     313             :         int reply_res;
     314             : 
     315         123 :         reply_res = send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT,
     316             :                                     auth_transaction, status, ies, ies_len);
     317             : 
     318         123 :         sta = ap_get_sta(hapd, dst);
     319         123 :         if (sta == NULL)
     320           0 :                 return;
     321             : 
     322         123 :         if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
     323             :                                    status != WLAN_STATUS_SUCCESS)) {
     324           0 :                 hostapd_drv_sta_remove(hapd, sta->addr);
     325           0 :                 sta->added_unassoc = 0;
     326           0 :                 return;
     327             :         }
     328             : 
     329         123 :         if (status != WLAN_STATUS_SUCCESS)
     330           0 :                 return;
     331             : 
     332         123 :         hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
     333             :                        HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
     334         123 :         sta->flags |= WLAN_STA_AUTH;
     335         123 :         mlme_authenticate_indication(hapd, sta);
     336             : }
     337             : #endif /* CONFIG_IEEE80211R */
     338             : 
     339             : 
     340             : #ifdef CONFIG_SAE
     341             : 
     342             : #define dot11RSNASAESync 5              /* attempts */
     343             : 
     344             : 
     345         205 : static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
     346             :                                              struct sta_info *sta, int update)
     347             : {
     348             :         struct wpabuf *buf;
     349             : 
     350         205 :         if (hapd->conf->ssid.wpa_passphrase == NULL) {
     351           0 :                 wpa_printf(MSG_DEBUG, "SAE: No password available");
     352           0 :                 return NULL;
     353             :         }
     354             : 
     355         317 :         if (update &&
     356         336 :             sae_prepare_commit(hapd->own_addr, sta->addr,
     357         112 :                                (u8 *) hapd->conf->ssid.wpa_passphrase,
     358         112 :                                os_strlen(hapd->conf->ssid.wpa_passphrase),
     359             :                                sta->sae) < 0) {
     360           0 :                 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
     361           0 :                 return NULL;
     362             :         }
     363             : 
     364         205 :         buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
     365         205 :         if (buf == NULL)
     366           1 :                 return NULL;
     367         408 :         sae_write_commit(sta->sae, buf, sta->sae->tmp ?
     368         204 :                          sta->sae->tmp->anti_clogging_token : NULL);
     369             : 
     370         204 :         return buf;
     371             : }
     372             : 
     373             : 
     374         268 : static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
     375             :                                               struct sta_info *sta)
     376             : {
     377             :         struct wpabuf *buf;
     378             : 
     379         268 :         buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
     380         268 :         if (buf == NULL)
     381           0 :                 return NULL;
     382             : 
     383         268 :         sae_write_confirm(sta->sae, buf);
     384             : 
     385         268 :         return buf;
     386             : }
     387             : 
     388             : 
     389         205 : static int auth_sae_send_commit(struct hostapd_data *hapd,
     390             :                                 struct sta_info *sta,
     391             :                                 const u8 *bssid, int update)
     392             : {
     393             :         struct wpabuf *data;
     394             :         int reply_res;
     395             : 
     396         205 :         data = auth_build_sae_commit(hapd, sta, update);
     397         205 :         if (data == NULL)
     398           1 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     399             : 
     400         408 :         reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 1,
     401         204 :                                     WLAN_STATUS_SUCCESS, wpabuf_head(data),
     402             :                                     wpabuf_len(data));
     403             : 
     404         204 :         wpabuf_free(data);
     405             : 
     406         204 :         return reply_res;
     407             : }
     408             : 
     409             : 
     410         268 : static int auth_sae_send_confirm(struct hostapd_data *hapd,
     411             :                                  struct sta_info *sta,
     412             :                                  const u8 *bssid)
     413             : {
     414             :         struct wpabuf *data;
     415             :         int reply_res;
     416             : 
     417         268 :         data = auth_build_sae_confirm(hapd, sta);
     418         268 :         if (data == NULL)
     419           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     420             : 
     421         536 :         reply_res = send_auth_reply(hapd, sta->addr, bssid, WLAN_AUTH_SAE, 2,
     422         268 :                                     WLAN_STATUS_SUCCESS, wpabuf_head(data),
     423             :                                     wpabuf_len(data));
     424             : 
     425         268 :         wpabuf_free(data);
     426             : 
     427         268 :         return reply_res;
     428             : }
     429             : 
     430             : 
     431         190 : static int use_sae_anti_clogging(struct hostapd_data *hapd)
     432             : {
     433             :         struct sta_info *sta;
     434         190 :         unsigned int open = 0;
     435             : 
     436         190 :         if (hapd->conf->sae_anti_clogging_threshold == 0)
     437           4 :                 return 1;
     438             : 
     439         397 :         for (sta = hapd->sta_list; sta; sta = sta->next) {
     440         212 :                 if (!sta->sae)
     441           6 :                         continue;
     442         329 :                 if (sta->sae->state != SAE_COMMITTED &&
     443         123 :                     sta->sae->state != SAE_CONFIRMED)
     444          91 :                         continue;
     445         115 :                 open++;
     446         115 :                 if (open >= hapd->conf->sae_anti_clogging_threshold)
     447           1 :                         return 1;
     448             :         }
     449             : 
     450         185 :         return 0;
     451             : }
     452             : 
     453             : 
     454           5 : static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
     455             :                            const u8 *token, size_t token_len)
     456             : {
     457             :         u8 mac[SHA256_MAC_LEN];
     458             : 
     459           5 :         if (token_len != SHA256_MAC_LEN)
     460           0 :                 return -1;
     461           5 :         if (hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
     462           5 :                         addr, ETH_ALEN, mac) < 0 ||
     463           5 :             os_memcmp_const(token, mac, SHA256_MAC_LEN) != 0)
     464           0 :                 return -1;
     465             : 
     466           5 :         return 0;
     467             : }
     468             : 
     469             : 
     470           5 : static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
     471             :                                             int group, const u8 *addr)
     472             : {
     473             :         struct wpabuf *buf;
     474             :         u8 *token;
     475             :         struct os_reltime now;
     476             : 
     477           5 :         os_get_reltime(&now);
     478           7 :         if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
     479           2 :             os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60)) {
     480           3 :                 if (random_get_bytes(hapd->sae_token_key,
     481             :                                      sizeof(hapd->sae_token_key)) < 0)
     482           0 :                         return NULL;
     483           3 :                 wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
     484           3 :                             hapd->sae_token_key, sizeof(hapd->sae_token_key));
     485           3 :                 hapd->last_sae_token_key_update = now;
     486             :         }
     487             : 
     488           5 :         buf = wpabuf_alloc(sizeof(le16) + SHA256_MAC_LEN);
     489           5 :         if (buf == NULL)
     490           0 :                 return NULL;
     491             : 
     492           5 :         wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
     493             : 
     494           5 :         token = wpabuf_put(buf, SHA256_MAC_LEN);
     495           5 :         hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
     496             :                     addr, ETH_ALEN, token);
     497             : 
     498           5 :         return buf;
     499             : }
     500             : 
     501             : 
     502         142 : static int sae_check_big_sync(struct sta_info *sta)
     503             : {
     504         142 :         if (sta->sae->sync > dot11RSNASAESync) {
     505          13 :                 sta->sae->state = SAE_NOTHING;
     506          13 :                 sta->sae->sync = 0;
     507          13 :                 return -1;
     508             :         }
     509         129 :         return 0;
     510             : }
     511             : 
     512             : 
     513         110 : static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
     514             : {
     515         110 :         struct hostapd_data *hapd = eloop_ctx;
     516         110 :         struct sta_info *sta = eloop_data;
     517             :         int ret;
     518             : 
     519         110 :         if (sae_check_big_sync(sta))
     520         122 :                 return;
     521          98 :         sta->sae->sync++;
     522         686 :         wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
     523             :                    " (sync=%d state=%d)",
     524         686 :                    MAC2STR(sta->addr), sta->sae->sync, sta->sae->state);
     525             : 
     526          98 :         switch (sta->sae->state) {
     527             :         case SAE_COMMITTED:
     528           7 :                 ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
     529           7 :                 eloop_register_timeout(0,
     530           7 :                                        hapd->dot11RSNASAERetransPeriod * 1000,
     531             :                                        auth_sae_retransmit_timer, hapd, sta);
     532           7 :                 break;
     533             :         case SAE_CONFIRMED:
     534          87 :                 ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
     535          87 :                 eloop_register_timeout(0,
     536          87 :                                        hapd->dot11RSNASAERetransPeriod * 1000,
     537             :                                        auth_sae_retransmit_timer, hapd, sta);
     538          87 :                 break;
     539             :         default:
     540           4 :                 ret = -1;
     541           4 :                 break;
     542             :         }
     543             : 
     544          98 :         if (ret != WLAN_STATUS_SUCCESS)
     545           4 :                 wpa_printf(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
     546             : }
     547             : 
     548             : 
     549        4819 : void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
     550             : {
     551        4819 :         eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
     552        4819 : }
     553             : 
     554             : 
     555         271 : static void sae_set_retransmit_timer(struct hostapd_data *hapd,
     556             :                                      struct sta_info *sta)
     557             : {
     558         271 :         if (!(hapd->conf->mesh & MESH_ENABLED))
     559         362 :                 return;
     560             : 
     561         180 :         eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
     562         180 :         eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
     563             :                                auth_sae_retransmit_timer, hapd, sta);
     564             : }
     565             : 
     566             : 
     567         138 : void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
     568             : {
     569         138 :         sta->flags |= WLAN_STA_AUTH;
     570         138 :         sta->auth_alg = WLAN_AUTH_SAE;
     571         138 :         mlme_authenticate_indication(hapd, sta);
     572         138 :         wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
     573         138 :         sta->sae->state = SAE_ACCEPTED;
     574         138 :         wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
     575         138 :                                sta->sae->pmk, sta->sae->pmkid);
     576         138 : }
     577             : 
     578             : 
     579         398 : static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
     580             :                        const u8 *bssid, u8 auth_transaction)
     581             : {
     582             :         int ret;
     583             : 
     584         398 :         if (auth_transaction != 1 && auth_transaction != 2)
     585           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     586             : 
     587         398 :         switch (sta->sae->state) {
     588             :         case SAE_NOTHING:
     589          93 :                 if (auth_transaction == 1) {
     590          86 :                         ret = auth_sae_send_commit(hapd, sta, bssid, 1);
     591          86 :                         if (ret)
     592           0 :                                 return ret;
     593          86 :                         sta->sae->state = SAE_COMMITTED;
     594             : 
     595          86 :                         if (sae_process_commit(sta->sae) < 0)
     596           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     597             : 
     598             :                         /*
     599             :                          * In mesh case, both Commit and Confirm can be sent
     600             :                          * immediately. In infrastructure BSS, only a single
     601             :                          * Authentication frame (Commit) is expected from the AP
     602             :                          * here and the second one (Confirm) will be sent once
     603             :                          * the STA has sent its second Authentication frame
     604             :                          * (Confirm).
     605             :                          */
     606          86 :                         if (hapd->conf->mesh & MESH_ENABLED) {
     607             :                                 /*
     608             :                                  * Send both Commit and Confirm immediately
     609             :                                  * based on SAE finite state machine
     610             :                                  * Nothing -> Confirm transition.
     611             :                                  */
     612          15 :                                 ret = auth_sae_send_confirm(hapd, sta, bssid);
     613          15 :                                 if (ret)
     614           0 :                                         return ret;
     615          15 :                                 sta->sae->state = SAE_CONFIRMED;
     616             :                         } else {
     617             :                                 /*
     618             :                                  * For infrastructure BSS, send only the Commit
     619             :                                  * message now to get alternating sequence of
     620             :                                  * Authentication frames between the AP and STA.
     621             :                                  * Confirm will be sent in
     622             :                                  * Committed -> Confirmed/Accepted transition
     623             :                                  * when receiving Confirm from STA.
     624             :                                  */
     625             :                         }
     626          86 :                         sta->sae->sync = 0;
     627          86 :                         sae_set_retransmit_timer(hapd, sta);
     628             :                 } else {
     629           7 :                         hostapd_logger(hapd, sta->addr,
     630             :                                        HOSTAPD_MODULE_IEEE80211,
     631             :                                        HOSTAPD_LEVEL_DEBUG,
     632             :                                        "SAE confirm before commit");
     633             :                 }
     634          93 :                 break;
     635             :         case SAE_COMMITTED:
     636         145 :                 sae_clear_retransmit_timer(hapd, sta);
     637         145 :                 if (auth_transaction == 1) {
     638          74 :                         if (sae_process_commit(sta->sae) < 0)
     639           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     640             : 
     641          74 :                         ret = auth_sae_send_confirm(hapd, sta, bssid);
     642          74 :                         if (ret)
     643           0 :                                 return ret;
     644          74 :                         sta->sae->state = SAE_CONFIRMED;
     645          74 :                         sta->sae->sync = 0;
     646          74 :                         sae_set_retransmit_timer(hapd, sta);
     647          71 :                 } else if (hapd->conf->mesh & MESH_ENABLED) {
     648             :                         /*
     649             :                          * In mesh case, follow SAE finite state machine and
     650             :                          * send Commit now, if sync count allows.
     651             :                          */
     652           5 :                         if (sae_check_big_sync(sta))
     653           0 :                                 return WLAN_STATUS_SUCCESS;
     654           5 :                         sta->sae->sync++;
     655             : 
     656           5 :                         ret = auth_sae_send_commit(hapd, sta, bssid, 0);
     657           5 :                         if (ret)
     658           0 :                                 return ret;
     659             : 
     660           5 :                         sae_set_retransmit_timer(hapd, sta);
     661             :                 } else {
     662             :                         /*
     663             :                          * For instructure BSS, send the postponed Confirm from
     664             :                          * Nothing -> Confirmed transition that was reduced to
     665             :                          * Nothing -> Committed above.
     666             :                          */
     667          66 :                         ret = auth_sae_send_confirm(hapd, sta, bssid);
     668          66 :                         if (ret)
     669           0 :                                 return ret;
     670             : 
     671          66 :                         sta->sae->state = SAE_CONFIRMED;
     672             : 
     673             :                         /*
     674             :                          * Since this was triggered on Confirm RX, run another
     675             :                          * step to get to Accepted without waiting for
     676             :                          * additional events.
     677             :                          */
     678          66 :                         return sae_sm_step(hapd, sta, bssid, auth_transaction);
     679             :                 }
     680          79 :                 break;
     681             :         case SAE_CONFIRMED:
     682         157 :                 sae_clear_retransmit_timer(hapd, sta);
     683         157 :                 if (auth_transaction == 1) {
     684          27 :                         if (sae_check_big_sync(sta))
     685           1 :                                 return WLAN_STATUS_SUCCESS;
     686          26 :                         sta->sae->sync++;
     687             : 
     688          26 :                         ret = auth_sae_send_commit(hapd, sta, bssid, 1);
     689          26 :                         if (ret)
     690           0 :                                 return ret;
     691             : 
     692          26 :                         if (sae_process_commit(sta->sae) < 0)
     693           0 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     694             : 
     695          26 :                         ret = auth_sae_send_confirm(hapd, sta, bssid);
     696          26 :                         if (ret)
     697           0 :                                 return ret;
     698             : 
     699          26 :                         sae_set_retransmit_timer(hapd, sta);
     700             :                 } else {
     701         130 :                         sae_accept_sta(hapd, sta);
     702             :                 }
     703         156 :                 break;
     704             :         case SAE_ACCEPTED:
     705           3 :                 if (auth_transaction == 1) {
     706          18 :                         wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
     707             :                                    ") doing reauthentication",
     708          18 :                                    MAC2STR(sta->addr));
     709           3 :                         ap_free_sta(hapd, sta);
     710           3 :                         wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
     711             :                 } else {
     712           0 :                         if (sae_check_big_sync(sta))
     713           0 :                                 return WLAN_STATUS_SUCCESS;
     714           0 :                         sta->sae->sync++;
     715             : 
     716           0 :                         ret = auth_sae_send_confirm(hapd, sta, bssid);
     717           0 :                         sae_clear_temp_data(sta->sae);
     718           0 :                         if (ret)
     719           0 :                                 return ret;
     720             :                 }
     721           3 :                 break;
     722             :         default:
     723           0 :                 wpa_printf(MSG_ERROR, "SAE: invalid state %d",
     724           0 :                            sta->sae->state);
     725           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
     726             :         }
     727         331 :         return WLAN_STATUS_SUCCESS;
     728             : }
     729             : 
     730             : 
     731          17 : static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
     732             : {
     733          17 :         struct sae_data *sae = sta->sae;
     734          17 :         int i, *groups = hapd->conf->sae_groups;
     735             : 
     736          17 :         if (sae->state != SAE_COMMITTED)
     737           0 :                 return;
     738             : 
     739          17 :         wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
     740             : 
     741          18 :         for (i = 0; groups && groups[i] > 0; i++) {
     742          18 :                 if (sae->group == groups[i])
     743          17 :                         break;
     744             :         }
     745             : 
     746          17 :         if (!groups || groups[i] <= 0) {
     747           0 :                 wpa_printf(MSG_DEBUG,
     748             :                            "SAE: Previously selected group not found from the current configuration");
     749           0 :                 return;
     750             :         }
     751             : 
     752             :         for (;;) {
     753          17 :                 i++;
     754          17 :                 if (groups[i] <= 0) {
     755          11 :                         wpa_printf(MSG_DEBUG,
     756             :                                    "SAE: No alternative group enabled");
     757          11 :                         return;
     758             :                 }
     759             : 
     760           6 :                 if (sae_set_group(sae, groups[i]) < 0)
     761           0 :                         continue;
     762             : 
     763           6 :                 break;
     764           0 :         }
     765           6 :         wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
     766             : }
     767             : 
     768             : 
     769         588 : static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
     770             :                             const struct ieee80211_mgmt *mgmt, size_t len,
     771             :                             u16 auth_transaction, u16 status_code)
     772             : {
     773         588 :         int resp = WLAN_STATUS_SUCCESS;
     774         588 :         struct wpabuf *data = NULL;
     775             : 
     776         588 :         if (!sta->sae) {
     777          77 :                 if (auth_transaction != 1 ||
     778             :                     status_code != WLAN_STATUS_SUCCESS) {
     779           0 :                         resp = -1;
     780           0 :                         goto remove_sta;
     781             :                 }
     782          77 :                 sta->sae = os_zalloc(sizeof(*sta->sae));
     783          77 :                 if (!sta->sae) {
     784           0 :                         resp = -1;
     785           0 :                         goto remove_sta;
     786             :                 }
     787          77 :                 sta->sae->state = SAE_NOTHING;
     788          77 :                 sta->sae->sync = 0;
     789             :         }
     790             : 
     791         588 :         if (sta->mesh_sae_pmksa_caching) {
     792           0 :                 wpa_printf(MSG_DEBUG,
     793             :                            "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
     794           0 :                 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
     795           0 :                 sta->mesh_sae_pmksa_caching = 0;
     796             :         }
     797             : 
     798         588 :         if (auth_transaction == 1) {
     799         234 :                 const u8 *token = NULL, *pos, *end;
     800         234 :                 size_t token_len = 0;
     801         234 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     802             :                                HOSTAPD_LEVEL_DEBUG,
     803             :                                "start SAE authentication (RX commit, status=%u)",
     804             :                                status_code);
     805             : 
     806         234 :                 if ((hapd->conf->mesh & MESH_ENABLED) &&
     807           0 :                     status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
     808           0 :                     sta->sae->tmp) {
     809           0 :                         pos = mgmt->u.auth.variable;
     810           0 :                         end = ((const u8 *) mgmt) + len;
     811           0 :                         if (pos + sizeof(le16) > end) {
     812           0 :                                 wpa_printf(MSG_ERROR,
     813             :                                            "SAE: Too short anti-clogging token request");
     814           0 :                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     815          27 :                                 goto reply;
     816             :                         }
     817           0 :                         resp = sae_group_allowed(sta->sae,
     818           0 :                                                  hapd->conf->sae_groups,
     819           0 :                                                  WPA_GET_LE16(pos));
     820           0 :                         if (resp != WLAN_STATUS_SUCCESS) {
     821           0 :                                 wpa_printf(MSG_ERROR,
     822             :                                            "SAE: Invalid group in anti-clogging token request");
     823           0 :                                 goto reply;
     824             :                         }
     825           0 :                         pos += sizeof(le16);
     826             : 
     827           0 :                         wpabuf_free(sta->sae->tmp->anti_clogging_token);
     828           0 :                         sta->sae->tmp->anti_clogging_token =
     829           0 :                                 wpabuf_alloc_copy(pos, end - pos);
     830           0 :                         if (sta->sae->tmp->anti_clogging_token == NULL) {
     831           0 :                                 wpa_printf(MSG_ERROR,
     832             :                                            "SAE: Failed to alloc for anti-clogging token");
     833           0 :                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     834          17 :                                 goto remove_sta;
     835             :                         }
     836             : 
     837             :                         /*
     838             :                          * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
     839             :                          * is 76, a new Commit Message shall be constructed
     840             :                          * with the Anti-Clogging Token from the received
     841             :                          * Authentication frame, and the commit-scalar and
     842             :                          * COMMIT-ELEMENT previously sent.
     843             :                          */
     844           0 :                         resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0);
     845           0 :                         if (resp != WLAN_STATUS_SUCCESS) {
     846           0 :                                 wpa_printf(MSG_ERROR,
     847             :                                            "SAE: Failed to send commit message");
     848           0 :                                 goto remove_sta;
     849             :                         }
     850           0 :                         sta->sae->state = SAE_COMMITTED;
     851           0 :                         sta->sae->sync = 0;
     852           0 :                         sae_set_retransmit_timer(hapd, sta);
     853         588 :                         return;
     854             :                 }
     855             : 
     856         234 :                 if ((hapd->conf->mesh & MESH_ENABLED) &&
     857             :                     status_code ==
     858          17 :                     WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
     859          17 :                     sta->sae->tmp) {
     860          17 :                         wpa_printf(MSG_DEBUG,
     861             :                                    "SAE: Peer did not accept our SAE group");
     862          17 :                         sae_pick_next_group(hapd, sta);
     863          17 :                         goto remove_sta;
     864             :                 }
     865             : 
     866         217 :                 if (status_code != WLAN_STATUS_SUCCESS)
     867           0 :                         goto remove_sta;
     868             : 
     869         434 :                 resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
     870         217 :                                         ((const u8 *) mgmt) + len -
     871             :                                         mgmt->u.auth.variable, &token,
     872         217 :                                         &token_len, hapd->conf->sae_groups);
     873         217 :                 if (resp == SAE_SILENTLY_DISCARD) {
     874           0 :                         wpa_printf(MSG_DEBUG,
     875             :                                    "SAE: Drop commit message from " MACSTR " due to reflection attack",
     876           0 :                                    MAC2STR(sta->addr));
     877           0 :                         goto remove_sta;
     878             :                 }
     879         217 :                 if (token && check_sae_token(hapd, sta->addr, token, token_len)
     880             :                     < 0) {
     881           0 :                         wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
     882             :                                    "incorrect token from " MACSTR,
     883           0 :                                    MAC2STR(sta->addr));
     884           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     885           0 :                         goto remove_sta;
     886             :                 }
     887             : 
     888         217 :                 if (resp != WLAN_STATUS_SUCCESS)
     889          22 :                         goto reply;
     890             : 
     891         195 :                 if (!token && use_sae_anti_clogging(hapd)) {
     892          30 :                         wpa_printf(MSG_DEBUG,
     893             :                                    "SAE: Request anti-clogging token from "
     894          30 :                                    MACSTR, MAC2STR(sta->addr));
     895           5 :                         data = auth_build_token_req(hapd, sta->sae->group,
     896           5 :                                                     sta->addr);
     897           5 :                         resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
     898           5 :                         if (hapd->conf->mesh & MESH_ENABLED)
     899           0 :                                 sta->sae->state = SAE_NOTHING;
     900           5 :                         goto reply;
     901             :                 }
     902             : 
     903         190 :                 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
     904         354 :         } else if (auth_transaction == 2) {
     905         354 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     906             :                                HOSTAPD_LEVEL_DEBUG,
     907             :                                "SAE authentication (RX confirm, status=%u)",
     908             :                                status_code);
     909         354 :                 if (status_code != WLAN_STATUS_SUCCESS)
     910         106 :                         goto remove_sta;
     911         326 :                 if (sta->sae->state >= SAE_CONFIRMED ||
     912          78 :                     !(hapd->conf->mesh & MESH_ENABLED)) {
     913         236 :                         if (sae_check_confirm(sta->sae, mgmt->u.auth.variable,
     914         236 :                                               ((u8 *) mgmt) + len -
     915             :                                               mgmt->u.auth.variable) < 0) {
     916         106 :                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
     917         106 :                                 goto reply;
     918             :                         }
     919             :                 }
     920         142 :                 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction);
     921             :         } else {
     922           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
     923             :                                HOSTAPD_LEVEL_DEBUG,
     924             :                                "unexpected SAE authentication transaction %u (status=%u)",
     925             :                                auth_transaction, status_code);
     926           0 :                 if (status_code != WLAN_STATUS_SUCCESS)
     927           0 :                         goto remove_sta;
     928           0 :                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
     929             :         }
     930             : 
     931             : reply:
     932         465 :         if (resp != WLAN_STATUS_SUCCESS) {
     933         133 :                 send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
     934             :                                 auth_transaction, resp,
     935             :                                 data ? wpabuf_head(data) : (u8 *) "",
     936             :                                 data ? wpabuf_len(data) : 0);
     937             :         }
     938             : 
     939             : remove_sta:
     940         588 :         if (sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
     941             :                                    status_code != WLAN_STATUS_SUCCESS)) {
     942          10 :                 hostapd_drv_sta_remove(hapd, sta->addr);
     943          10 :                 sta->added_unassoc = 0;
     944             :         }
     945         588 :         wpabuf_free(data);
     946             : }
     947             : 
     948             : 
     949             : /**
     950             :  * auth_sae_init_committed - Send COMMIT and start SAE in committed state
     951             :  * @hapd: BSS data for the device initiating the authentication
     952             :  * @sta: the peer to which commit authentication frame is sent
     953             :  *
     954             :  * This function implements Init event handling (IEEE Std 802.11-2012,
     955             :  * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
     956             :  * sta->sae structure should be initialized appropriately via a call to
     957             :  * sae_prepare_commit().
     958             :  */
     959          81 : int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
     960             : {
     961             :         int ret;
     962             : 
     963          81 :         if (!sta->sae || !sta->sae->tmp)
     964           0 :                 return -1;
     965             : 
     966          81 :         if (sta->sae->state != SAE_NOTHING)
     967           0 :                 return -1;
     968             : 
     969          81 :         ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0);
     970          81 :         if (ret)
     971           1 :                 return -1;
     972             : 
     973          80 :         sta->sae->state = SAE_COMMITTED;
     974          80 :         sta->sae->sync = 0;
     975          80 :         sae_set_retransmit_timer(hapd, sta);
     976             : 
     977          80 :         return 0;
     978             : }
     979             : 
     980             : #endif /* CONFIG_SAE */
     981             : 
     982             : 
     983        5299 : static void handle_auth(struct hostapd_data *hapd,
     984             :                         const struct ieee80211_mgmt *mgmt, size_t len)
     985             : {
     986             :         u16 auth_alg, auth_transaction, status_code;
     987        5299 :         u16 resp = WLAN_STATUS_SUCCESS;
     988        5299 :         struct sta_info *sta = NULL;
     989             :         int res, reply_res;
     990             :         u16 fc;
     991        5299 :         const u8 *challenge = NULL;
     992             :         u32 session_timeout, acct_interim_interval;
     993             :         struct vlan_description vlan_id;
     994        5299 :         struct hostapd_sta_wpa_psk_short *psk = NULL;
     995             :         u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
     996        5299 :         size_t resp_ies_len = 0;
     997        5299 :         char *identity = NULL;
     998        5299 :         char *radius_cui = NULL;
     999             :         u16 seq_ctrl;
    1000             : 
    1001        5299 :         os_memset(&vlan_id, 0, sizeof(vlan_id));
    1002             : 
    1003        5299 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
    1004           0 :                 wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
    1005             :                            (unsigned long) len);
    1006           0 :                 return;
    1007             :         }
    1008             : 
    1009             : #ifdef CONFIG_TESTING_OPTIONS
    1010        5310 :         if (hapd->iconf->ignore_auth_probability > 0.0 &&
    1011          11 :             drand48() < hapd->iconf->ignore_auth_probability) {
    1012          48 :                 wpa_printf(MSG_INFO,
    1013             :                            "TESTING: ignoring auth frame from " MACSTR,
    1014          48 :                            MAC2STR(mgmt->sa));
    1015           8 :                 return;
    1016             :         }
    1017             : #endif /* CONFIG_TESTING_OPTIONS */
    1018             : 
    1019        5291 :         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    1020        5291 :         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
    1021        5291 :         status_code = le_to_host16(mgmt->u.auth.status_code);
    1022        5291 :         fc = le_to_host16(mgmt->frame_control);
    1023        5291 :         seq_ctrl = le_to_host16(mgmt->seq_ctrl);
    1024             : 
    1025        5291 :         if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
    1026         186 :             2 + WLAN_AUTH_CHALLENGE_LEN &&
    1027         200 :             mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
    1028          14 :             mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
    1029          13 :                 challenge = &mgmt->u.auth.variable[2];
    1030             : 
    1031       42328 :         wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
    1032             :                    "auth_transaction=%d status_code=%d wep=%d%s "
    1033             :                    "seq_ctrl=0x%x%s",
    1034       31746 :                    MAC2STR(mgmt->sa), auth_alg, auth_transaction,
    1035        5291 :                    status_code, !!(fc & WLAN_FC_ISWEP),
    1036             :                    challenge ? " challenge" : "",
    1037        5291 :                    seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
    1038             : 
    1039             : #ifdef CONFIG_NO_RC4
    1040             :         if (auth_alg == WLAN_AUTH_SHARED_KEY) {
    1041             :                 wpa_printf(MSG_INFO,
    1042             :                            "Unsupported authentication algorithm (%d)",
    1043             :                            auth_alg);
    1044             :                 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
    1045             :                 goto fail;
    1046             :         }
    1047             : #endif /* CONFIG_NO_RC4 */
    1048             : 
    1049        5291 :         if (hapd->tkip_countermeasures) {
    1050           2 :                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
    1051           2 :                 goto fail;
    1052             :         }
    1053             : 
    1054        5323 :         if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
    1055         750 :                auth_alg == WLAN_AUTH_OPEN) ||
    1056             : #ifdef CONFIG_IEEE80211R
    1057        1466 :               (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
    1058         624 :                auth_alg == WLAN_AUTH_FT) ||
    1059             : #endif /* CONFIG_IEEE80211R */
    1060             : #ifdef CONFIG_SAE
    1061        1214 :               (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
    1062             :                auth_alg == WLAN_AUTH_SAE) ||
    1063             : #endif /* CONFIG_SAE */
    1064          64 :               ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
    1065             :                auth_alg == WLAN_AUTH_SHARED_KEY))) {
    1066           8 :                 wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
    1067             :                            auth_alg);
    1068           8 :                 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
    1069           8 :                 goto fail;
    1070             :         }
    1071             : 
    1072        5281 :         if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
    1073          13 :               (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
    1074           0 :                 wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
    1075             :                            auth_transaction);
    1076           0 :                 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
    1077           0 :                 goto fail;
    1078             :         }
    1079             : 
    1080        5281 :         if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
    1081           0 :                 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
    1082           0 :                            MAC2STR(mgmt->sa));
    1083           0 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1084           0 :                 goto fail;
    1085             :         }
    1086             : 
    1087        5281 :         if (hapd->conf->no_auth_if_seen_on) {
    1088             :                 struct hostapd_data *other;
    1089             : 
    1090           4 :                 other = sta_track_seen_on(hapd->iface, mgmt->sa,
    1091           4 :                                           hapd->conf->no_auth_if_seen_on);
    1092           4 :                 if (other) {
    1093             :                         u8 *pos;
    1094             :                         u32 info;
    1095             :                         u8 op_class, channel, phytype;
    1096             : 
    1097          24 :                         wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
    1098             :                                    MACSTR " since STA has been seen on %s",
    1099          21 :                                    hapd->conf->iface, MAC2STR(mgmt->sa),
    1100           3 :                                    hapd->conf->no_auth_if_seen_on);
    1101             : 
    1102           3 :                         resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
    1103           3 :                         pos = &resp_ies[0];
    1104           3 :                         *pos++ = WLAN_EID_NEIGHBOR_REPORT;
    1105           3 :                         *pos++ = 13;
    1106           3 :                         os_memcpy(pos, other->own_addr, ETH_ALEN);
    1107           3 :                         pos += ETH_ALEN;
    1108           3 :                         info = 0; /* TODO: BSSID Information */
    1109           3 :                         WPA_PUT_LE32(pos, info);
    1110           3 :                         pos += 4;
    1111           3 :                         if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
    1112           0 :                                 phytype = 8; /* dmg */
    1113           3 :                         else if (other->iconf->ieee80211ac)
    1114           0 :                                 phytype = 9; /* vht */
    1115           3 :                         else if (other->iconf->ieee80211n)
    1116           3 :                                 phytype = 7; /* ht */
    1117           0 :                         else if (other->iconf->hw_mode ==
    1118             :                                  HOSTAPD_MODE_IEEE80211A)
    1119           0 :                                 phytype = 4; /* ofdm */
    1120           0 :                         else if (other->iconf->hw_mode ==
    1121             :                                  HOSTAPD_MODE_IEEE80211G)
    1122           0 :                                 phytype = 6; /* erp */
    1123             :                         else
    1124           0 :                                 phytype = 5; /* hrdsss */
    1125           9 :                         if (ieee80211_freq_to_channel_ext(
    1126           3 :                                     hostapd_hw_get_freq(other,
    1127           3 :                                                         other->iconf->channel),
    1128           3 :                                     other->iconf->secondary_channel,
    1129           3 :                                     other->iconf->ieee80211ac,
    1130             :                                     &op_class, &channel) == NUM_HOSTAPD_MODES) {
    1131           0 :                                 op_class = 0;
    1132           0 :                                 channel = other->iconf->channel;
    1133             :                         }
    1134           3 :                         *pos++ = op_class;
    1135           3 :                         *pos++ = channel;
    1136           3 :                         *pos++ = phytype;
    1137           3 :                         resp_ies_len = pos - &resp_ies[0];
    1138           3 :                         goto fail;
    1139             :                 }
    1140             :         }
    1141             : 
    1142        5278 :         res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
    1143             :                                       &session_timeout,
    1144             :                                       &acct_interim_interval, &vlan_id,
    1145             :                                       &psk, &identity, &radius_cui);
    1146             : 
    1147        5278 :         if (res == HOSTAPD_ACL_REJECT) {
    1148         126 :                 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
    1149         126 :                            MAC2STR(mgmt->sa));
    1150          21 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1151          21 :                 goto fail;
    1152             :         }
    1153        5257 :         if (res == HOSTAPD_ACL_PENDING) {
    1154          60 :                 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
    1155             :                            " waiting for an external authentication",
    1156          60 :                            MAC2STR(mgmt->sa));
    1157             :                 /* Authentication code will re-send the authentication frame
    1158             :                  * after it has received (and cached) information from the
    1159             :                  * external source. */
    1160          10 :                 return;
    1161             :         }
    1162             : 
    1163        5247 :         sta = ap_get_sta(hapd, mgmt->sa);
    1164        5247 :         if (sta) {
    1165         914 :                 if ((fc & WLAN_FC_RETRY) &&
    1166           0 :                     sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
    1167           0 :                     sta->last_seq_ctrl == seq_ctrl &&
    1168           0 :                     sta->last_subtype == WLAN_FC_STYPE_AUTH) {
    1169           0 :                         hostapd_logger(hapd, sta->addr,
    1170             :                                        HOSTAPD_MODULE_IEEE80211,
    1171             :                                        HOSTAPD_LEVEL_DEBUG,
    1172             :                                        "Drop repeated authentication frame seq_ctrl=0x%x",
    1173             :                                        seq_ctrl);
    1174           0 :                         return;
    1175             :                 }
    1176             : #ifdef CONFIG_MESH
    1177         850 :                 if ((hapd->conf->mesh & MESH_ENABLED) &&
    1178         420 :                     sta->plink_state == PLINK_BLOCKED) {
    1179           0 :                         wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
    1180             :                                    " is blocked - drop Authentication frame",
    1181           0 :                                    MAC2STR(mgmt->sa));
    1182           0 :                         return;
    1183             :                 }
    1184             : #endif /* CONFIG_MESH */
    1185             :         } else {
    1186             : #ifdef CONFIG_MESH
    1187         568 :                 if (hapd->conf->mesh & MESH_ENABLED) {
    1188             :                         /* if the mesh peer is not available, we don't do auth.
    1189             :                          */
    1190          12 :                         wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
    1191             :                                    " not yet known - drop Authentication frame",
    1192          12 :                                    MAC2STR(mgmt->sa));
    1193             :                         /*
    1194             :                          * Save a copy of the frame so that it can be processed
    1195             :                          * if a new peer entry is added shortly after this.
    1196             :                          */
    1197           2 :                         wpabuf_free(hapd->mesh_pending_auth);
    1198           2 :                         hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
    1199           2 :                         os_get_reltime(&hapd->mesh_pending_auth_time);
    1200           2 :                         return;
    1201             :                 }
    1202             : #endif /* CONFIG_MESH */
    1203             : 
    1204        4331 :                 sta = ap_sta_add(hapd, mgmt->sa);
    1205        4331 :                 if (!sta) {
    1206           4 :                         resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    1207           4 :                         goto fail;
    1208             :                 }
    1209             :         }
    1210        5241 :         sta->last_seq_ctrl = seq_ctrl;
    1211        5241 :         sta->last_subtype = WLAN_FC_STYPE_AUTH;
    1212             : 
    1213        5253 :         if (vlan_id.notempty &&
    1214          12 :             !hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
    1215           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
    1216             :                                HOSTAPD_LEVEL_INFO,
    1217             :                                "Invalid VLAN %d%s received from RADIUS server",
    1218             :                                vlan_id.untagged,
    1219           0 :                                vlan_id.tagged[0] ? "+" : "");
    1220           0 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1221           0 :                 goto fail;
    1222             :         }
    1223        5241 :         if (ap_sta_set_vlan(hapd, sta, &vlan_id) < 0) {
    1224           0 :                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1225           0 :                 goto fail;
    1226             :         }
    1227        5241 :         if (sta->vlan_id)
    1228          22 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
    1229             :                                HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
    1230             : 
    1231        5241 :         hostapd_free_psk_list(sta->psk);
    1232        5241 :         if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
    1233           2 :                 sta->psk = psk;
    1234           2 :                 psk = NULL;
    1235             :         } else {
    1236        5239 :                 sta->psk = NULL;
    1237             :         }
    1238             : 
    1239        5241 :         sta->identity = identity;
    1240        5241 :         identity = NULL;
    1241        5241 :         sta->radius_cui = radius_cui;
    1242        5241 :         radius_cui = NULL;
    1243             : 
    1244        5241 :         sta->flags &= ~WLAN_STA_PREAUTH;
    1245        5241 :         ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
    1246             : 
    1247        5241 :         if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
    1248           0 :                 sta->acct_interim_interval = acct_interim_interval;
    1249        5241 :         if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
    1250           0 :                 ap_sta_session_timeout(hapd, sta, session_timeout);
    1251             :         else
    1252        5241 :                 ap_sta_no_session_timeout(hapd, sta);
    1253             : 
    1254             :         /*
    1255             :          * If the driver supports full AP client state, add a station to the
    1256             :          * driver before sending authentication reply to make sure the driver
    1257             :          * has resources, and not to go through the entire authentication and
    1258             :          * association handshake, and fail it at the end.
    1259             :          *
    1260             :          * If this is not the first transaction, in a multi-step authentication
    1261             :          * algorithm, the station already exists in the driver
    1262             :          * (sta->added_unassoc = 1) so skip it.
    1263             :          *
    1264             :          * In mesh mode, the station was already added to the driver when the
    1265             :          * NEW_PEER_CANDIDATE event is received.
    1266             :          */
    1267       10482 :         if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
    1268       10062 :             !(hapd->conf->mesh & MESH_ENABLED) &&
    1269        4821 :             !(sta->added_unassoc)) {
    1270             :                 /*
    1271             :                  * If a station that is already associated to the AP, is trying
    1272             :                  * to authenticate again, remove the STA entry, in order to make
    1273             :                  * sure the STA PS state gets cleared and configuration gets
    1274             :                  * updated. To handle this, station's added_unassoc flag is
    1275             :                  * cleared once the station has completed association.
    1276             :                  */
    1277        4708 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    1278        4708 :                 sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
    1279             :                                 WLAN_STA_AUTHORIZED);
    1280             : 
    1281        4708 :                 if (hostapd_sta_add(hapd, sta->addr, 0, 0, NULL, 0, 0,
    1282             :                                     NULL, NULL, sta->flags, 0, 0, 0, 0)) {
    1283           0 :                         hostapd_logger(hapd, sta->addr,
    1284             :                                        HOSTAPD_MODULE_IEEE80211,
    1285             :                                        HOSTAPD_LEVEL_NOTICE,
    1286             :                                        "Could not add STA to kernel driver");
    1287           0 :                         resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    1288           0 :                         goto fail;
    1289             :                 }
    1290             : 
    1291        4708 :                 sta->added_unassoc = 1;
    1292             :         }
    1293             : 
    1294        5241 :         switch (auth_alg) {
    1295             :         case WLAN_AUTH_OPEN:
    1296        4501 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1297             :                                HOSTAPD_LEVEL_DEBUG,
    1298             :                                "authentication OK (open system)");
    1299        4501 :                 sta->flags |= WLAN_STA_AUTH;
    1300        4501 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
    1301        4501 :                 sta->auth_alg = WLAN_AUTH_OPEN;
    1302        4501 :                 mlme_authenticate_indication(hapd, sta);
    1303        4501 :                 break;
    1304             : #ifndef CONFIG_NO_RC4
    1305             :         case WLAN_AUTH_SHARED_KEY:
    1306          26 :                 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
    1307             :                                        fc & WLAN_FC_ISWEP);
    1308          26 :                 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
    1309          26 :                 mlme_authenticate_indication(hapd, sta);
    1310          26 :                 if (sta->challenge && auth_transaction == 1) {
    1311          13 :                         resp_ies[0] = WLAN_EID_CHALLENGE;
    1312          13 :                         resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
    1313          13 :                         os_memcpy(resp_ies + 2, sta->challenge,
    1314             :                                   WLAN_AUTH_CHALLENGE_LEN);
    1315          13 :                         resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
    1316             :                 }
    1317          26 :                 break;
    1318             : #endif /* CONFIG_NO_RC4 */
    1319             : #ifdef CONFIG_IEEE80211R
    1320             :         case WLAN_AUTH_FT:
    1321         126 :                 sta->auth_alg = WLAN_AUTH_FT;
    1322         126 :                 if (sta->wpa_sm == NULL)
    1323          12 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    1324          12 :                                                         sta->addr, NULL);
    1325         126 :                 if (sta->wpa_sm == NULL) {
    1326           0 :                         wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
    1327             :                                    "state machine");
    1328           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1329           0 :                         goto fail;
    1330             :                 }
    1331         252 :                 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
    1332         126 :                                     auth_transaction, mgmt->u.auth.variable,
    1333             :                                     len - IEEE80211_HDRLEN -
    1334             :                                     sizeof(mgmt->u.auth),
    1335             :                                     handle_auth_ft_finish, hapd);
    1336             :                 /* handle_auth_ft_finish() callback will complete auth. */
    1337         126 :                 return;
    1338             : #endif /* CONFIG_IEEE80211R */
    1339             : #ifdef CONFIG_SAE
    1340             :         case WLAN_AUTH_SAE:
    1341             : #ifdef CONFIG_MESH
    1342         717 :                 if (status_code == WLAN_STATUS_SUCCESS &&
    1343         297 :                     hapd->conf->mesh & MESH_ENABLED) {
    1344         297 :                         if (sta->wpa_sm == NULL)
    1345          78 :                                 sta->wpa_sm =
    1346          78 :                                         wpa_auth_sta_init(hapd->wpa_auth,
    1347          78 :                                                           sta->addr, NULL);
    1348         297 :                         if (sta->wpa_sm == NULL) {
    1349           0 :                                 wpa_printf(MSG_DEBUG,
    1350             :                                            "SAE: Failed to initialize WPA state machine");
    1351           0 :                                 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1352           0 :                                 goto fail;
    1353             :                         }
    1354             :                 }
    1355             : #endif /* CONFIG_MESH */
    1356         588 :                 handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
    1357             :                                 status_code);
    1358         588 :                 return;
    1359             : #endif /* CONFIG_SAE */
    1360             :         }
    1361             : 
    1362             :  fail:
    1363        4565 :         os_free(identity);
    1364        4565 :         os_free(radius_cui);
    1365        4565 :         hostapd_free_psk_list(psk);
    1366             : 
    1367        4565 :         reply_res = send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
    1368             :                                     auth_transaction + 1, resp, resp_ies,
    1369             :                                     resp_ies_len);
    1370             : 
    1371        4565 :         if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
    1372             :                                           reply_res != WLAN_STATUS_SUCCESS)) {
    1373           0 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    1374           0 :                 sta->added_unassoc = 0;
    1375             :         }
    1376             : }
    1377             : 
    1378             : 
    1379        4913 : int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
    1380             : {
    1381        4913 :         int i, j = 32, aid;
    1382             : 
    1383             :         /* get a unique AID */
    1384        4913 :         if (sta->aid > 0) {
    1385         448 :                 wpa_printf(MSG_DEBUG, "  old AID %d", sta->aid);
    1386         448 :                 return 0;
    1387             :         }
    1388             : 
    1389        4465 :         if (TEST_FAIL())
    1390           1 :                 return -1;
    1391             : 
    1392        4464 :         for (i = 0; i < AID_WORDS; i++) {
    1393        4464 :                 if (hapd->sta_aid[i] == (u32) -1)
    1394           0 :                         continue;
    1395        5201 :                 for (j = 0; j < 32; j++) {
    1396        5201 :                         if (!(hapd->sta_aid[i] & BIT(j)))
    1397        4464 :                                 break;
    1398             :                 }
    1399        4464 :                 if (j < 32)
    1400        4464 :                         break;
    1401             :         }
    1402        4464 :         if (j == 32)
    1403           0 :                 return -1;
    1404        4464 :         aid = i * 32 + j + 1;
    1405        4464 :         if (aid > 2007)
    1406           0 :                 return -1;
    1407             : 
    1408        4464 :         sta->aid = aid;
    1409        4464 :         hapd->sta_aid[i] |= BIT(j);
    1410        4464 :         wpa_printf(MSG_DEBUG, "  new AID %d", sta->aid);
    1411        4464 :         return 0;
    1412             : }
    1413             : 
    1414             : 
    1415        4803 : static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
    1416             :                       const u8 *ssid_ie, size_t ssid_ie_len)
    1417             : {
    1418        4803 :         if (ssid_ie == NULL)
    1419           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1420             : 
    1421        9606 :         if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
    1422        4803 :             os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
    1423           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1424             :                                HOSTAPD_LEVEL_INFO,
    1425             :                                "Station tried to associate with unknown SSID "
    1426             :                                "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
    1427           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1428             :         }
    1429             : 
    1430        4803 :         return WLAN_STATUS_SUCCESS;
    1431             : }
    1432             : 
    1433             : 
    1434        4803 : static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
    1435             :                      const u8 *wmm_ie, size_t wmm_ie_len)
    1436             : {
    1437        4803 :         sta->flags &= ~WLAN_STA_WMM;
    1438        4803 :         sta->qosinfo = 0;
    1439        4803 :         if (wmm_ie && hapd->conf->wmm_enabled) {
    1440             :                 struct wmm_information_element *wmm;
    1441             : 
    1442        4792 :                 if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
    1443           0 :                         hostapd_logger(hapd, sta->addr,
    1444             :                                        HOSTAPD_MODULE_WPA,
    1445             :                                        HOSTAPD_LEVEL_DEBUG,
    1446             :                                        "invalid WMM element in association "
    1447             :                                        "request");
    1448           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1449             :                 }
    1450             : 
    1451        4792 :                 sta->flags |= WLAN_STA_WMM;
    1452        4792 :                 wmm = (struct wmm_information_element *) wmm_ie;
    1453        4792 :                 sta->qosinfo = wmm->qos_info;
    1454             :         }
    1455        4803 :         return WLAN_STATUS_SUCCESS;
    1456             : }
    1457             : 
    1458             : 
    1459        4803 : static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
    1460             :                            struct ieee802_11_elems *elems)
    1461             : {
    1462        4803 :         if (!elems->supp_rates) {
    1463           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1464             :                                HOSTAPD_LEVEL_DEBUG,
    1465             :                                "No supported rates element in AssocReq");
    1466           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1467             :         }
    1468             : 
    1469        4803 :         if (elems->supp_rates_len + elems->ext_supp_rates_len >
    1470             :             sizeof(sta->supported_rates)) {
    1471           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1472             :                                HOSTAPD_LEVEL_DEBUG,
    1473             :                                "Invalid supported rates element length %d+%d",
    1474           0 :                                elems->supp_rates_len,
    1475           0 :                                elems->ext_supp_rates_len);
    1476           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1477             :         }
    1478             : 
    1479       14409 :         sta->supported_rates_len = merge_byte_arrays(
    1480        4803 :                 sta->supported_rates, sizeof(sta->supported_rates),
    1481        4803 :                 elems->supp_rates, elems->supp_rates_len,
    1482        4803 :                 elems->ext_supp_rates, elems->ext_supp_rates_len);
    1483             : 
    1484        4803 :         return WLAN_STATUS_SUCCESS;
    1485             : }
    1486             : 
    1487             : 
    1488        4803 : static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
    1489             :                            const u8 *ext_capab_ie, size_t ext_capab_ie_len)
    1490             : {
    1491             : #ifdef CONFIG_INTERWORKING
    1492             :         /* check for QoS Map support */
    1493        4803 :         if (ext_capab_ie_len >= 5) {
    1494        4573 :                 if (ext_capab_ie[4] & 0x01)
    1495        4554 :                         sta->qos_map_enabled = 1;
    1496             :         }
    1497             : #endif /* CONFIG_INTERWORKING */
    1498             : 
    1499        4803 :         if (ext_capab_ie_len > 0)
    1500        4573 :                 sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
    1501             : 
    1502        4803 :         return WLAN_STATUS_SUCCESS;
    1503             : }
    1504             : 
    1505             : 
    1506        4803 : static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
    1507             :                            const u8 *ies, size_t ies_len, int reassoc)
    1508             : {
    1509             :         struct ieee802_11_elems elems;
    1510             :         u16 resp;
    1511             :         const u8 *wpa_ie;
    1512             :         size_t wpa_ie_len;
    1513        4803 :         const u8 *p2p_dev_addr = NULL;
    1514             : 
    1515        4803 :         if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
    1516           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1517             :                                HOSTAPD_LEVEL_INFO, "Station sent an invalid "
    1518             :                                "association request");
    1519           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1520             :         }
    1521             : 
    1522        4803 :         resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
    1523        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    1524           0 :                 return resp;
    1525        4803 :         resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
    1526        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    1527           0 :                 return resp;
    1528        4803 :         resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
    1529        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    1530           0 :                 return resp;
    1531        4803 :         resp = copy_supp_rates(hapd, sta, &elems);
    1532        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    1533           0 :                 return resp;
    1534             : #ifdef CONFIG_IEEE80211N
    1535        4803 :         resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
    1536        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    1537           0 :                 return resp;
    1538        4810 :         if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
    1539           7 :             !(sta->flags & WLAN_STA_HT)) {
    1540           4 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1541             :                                HOSTAPD_LEVEL_INFO, "Station does not support "
    1542             :                                "mandatory HT PHY - reject association");
    1543           4 :                 return WLAN_STATUS_ASSOC_DENIED_NO_HT;
    1544             :         }
    1545             : #endif /* CONFIG_IEEE80211N */
    1546             : 
    1547             : #ifdef CONFIG_IEEE80211AC
    1548        4799 :         if (hapd->iconf->ieee80211ac) {
    1549          36 :                 resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
    1550          36 :                 if (resp != WLAN_STATUS_SUCCESS)
    1551           0 :                         return resp;
    1552             : 
    1553          36 :                 resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
    1554          36 :                 if (resp != WLAN_STATUS_SUCCESS)
    1555           0 :                         return resp;
    1556             :         }
    1557             : 
    1558        4802 :         if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
    1559           3 :             !(sta->flags & WLAN_STA_VHT)) {
    1560           1 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1561             :                                HOSTAPD_LEVEL_INFO, "Station does not support "
    1562             :                                "mandatory VHT PHY - reject association");
    1563           1 :                 return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
    1564             :         }
    1565             : 
    1566        4798 :         if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
    1567           2 :                 resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
    1568           2 :                                            elems.vendor_vht_len);
    1569           2 :                 if (resp != WLAN_STATUS_SUCCESS)
    1570           0 :                         return resp;
    1571             :         }
    1572             : #endif /* CONFIG_IEEE80211AC */
    1573             : 
    1574             : #ifdef CONFIG_P2P
    1575         577 :         if (elems.p2p) {
    1576         524 :                 wpabuf_free(sta->p2p_ie);
    1577         524 :                 sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
    1578             :                                                           P2P_IE_VENDOR_TYPE);
    1579         524 :                 if (sta->p2p_ie)
    1580         524 :                         p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
    1581             :         } else {
    1582          53 :                 wpabuf_free(sta->p2p_ie);
    1583          53 :                 sta->p2p_ie = NULL;
    1584             :         }
    1585             : #endif /* CONFIG_P2P */
    1586             : 
    1587        4798 :         if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
    1588        3453 :                 wpa_ie = elems.rsn_ie;
    1589        3453 :                 wpa_ie_len = elems.rsn_ie_len;
    1590        1410 :         } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
    1591          65 :                    elems.wpa_ie) {
    1592          47 :                 wpa_ie = elems.wpa_ie;
    1593          47 :                 wpa_ie_len = elems.wpa_ie_len;
    1594             :         } else {
    1595        1298 :                 wpa_ie = NULL;
    1596        1298 :                 wpa_ie_len = 0;
    1597             :         }
    1598             : 
    1599             : #ifdef CONFIG_WPS
    1600        4798 :         sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
    1601        4798 :         if (hapd->conf->wps_state && elems.wps_ie) {
    1602         535 :                 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
    1603             :                            "Request - assume WPS is used");
    1604         535 :                 sta->flags |= WLAN_STA_WPS;
    1605         535 :                 wpabuf_free(sta->wps_ie);
    1606         535 :                 sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
    1607             :                                                           WPS_IE_VENDOR_TYPE);
    1608         535 :                 if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
    1609         532 :                         wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
    1610         532 :                         sta->flags |= WLAN_STA_WPS2;
    1611             :                 }
    1612         535 :                 wpa_ie = NULL;
    1613         535 :                 wpa_ie_len = 0;
    1614        1070 :                 if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
    1615           0 :                         wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
    1616             :                                    "(Re)Association Request - reject");
    1617           0 :                         return WLAN_STATUS_INVALID_IE;
    1618             :                 }
    1619        4263 :         } else if (hapd->conf->wps_state && wpa_ie == NULL) {
    1620          18 :                 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
    1621             :                            "(Re)Association Request - possible WPS use");
    1622          18 :                 sta->flags |= WLAN_STA_MAYBE_WPS;
    1623             :         } else
    1624             : #endif /* CONFIG_WPS */
    1625        4245 :         if (hapd->conf->wpa && wpa_ie == NULL) {
    1626           1 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1627             :                                HOSTAPD_LEVEL_INFO,
    1628             :                                "No WPA/RSN IE in association request");
    1629           1 :                 return WLAN_STATUS_INVALID_IE;
    1630             :         }
    1631             : 
    1632        8259 :         if (hapd->conf->wpa && wpa_ie) {
    1633             :                 int res;
    1634        3500 :                 wpa_ie -= 2;
    1635        3500 :                 wpa_ie_len += 2;
    1636        3500 :                 if (sta->wpa_sm == NULL)
    1637        3023 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    1638        3023 :                                                         sta->addr,
    1639             :                                                         p2p_dev_addr);
    1640        3500 :                 if (sta->wpa_sm == NULL) {
    1641           0 :                         wpa_printf(MSG_WARNING, "Failed to initialize WPA "
    1642             :                                    "state machine");
    1643           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1644             :                 }
    1645        3500 :                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
    1646             :                                           wpa_ie, wpa_ie_len,
    1647        3500 :                                           elems.mdie, elems.mdie_len);
    1648        3500 :                 if (res == WPA_INVALID_GROUP)
    1649           1 :                         resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
    1650        3499 :                 else if (res == WPA_INVALID_PAIRWISE)
    1651           1 :                         resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
    1652        3498 :                 else if (res == WPA_INVALID_AKMP)
    1653           4 :                         resp = WLAN_STATUS_AKMP_NOT_VALID;
    1654        3494 :                 else if (res == WPA_ALLOC_FAIL)
    1655           0 :                         resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
    1656             : #ifdef CONFIG_IEEE80211W
    1657        3494 :                 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
    1658           1 :                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
    1659        3493 :                 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
    1660           1 :                         resp = WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
    1661             : #endif /* CONFIG_IEEE80211W */
    1662        3492 :                 else if (res == WPA_INVALID_MDIE)
    1663           0 :                         resp = WLAN_STATUS_INVALID_MDIE;
    1664        3492 :                 else if (res != WPA_IE_OK)
    1665          22 :                         resp = WLAN_STATUS_INVALID_IE;
    1666        3500 :                 if (resp != WLAN_STATUS_SUCCESS)
    1667          30 :                         return resp;
    1668             : #ifdef CONFIG_IEEE80211W
    1669        3476 :                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    1670           6 :                     sta->sa_query_count > 0)
    1671           0 :                         ap_check_sa_query_timeout(hapd, sta);
    1672        3470 :                 if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
    1673           4 :                     (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
    1674             :                         /*
    1675             :                          * STA has already been associated with MFP and SA
    1676             :                          * Query timeout has not been reached. Reject the
    1677             :                          * association attempt temporarily and start SA Query,
    1678             :                          * if one is not pending.
    1679             :                          */
    1680             : 
    1681           4 :                         if (sta->sa_query_count == 0)
    1682           4 :                                 ap_sta_start_sa_query(hapd, sta);
    1683             : 
    1684           4 :                         return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
    1685             :                 }
    1686             : 
    1687        3466 :                 if (wpa_auth_uses_mfp(sta->wpa_sm))
    1688          73 :                         sta->flags |= WLAN_STA_MFP;
    1689             :                 else
    1690        3393 :                         sta->flags &= ~WLAN_STA_MFP;
    1691             : #endif /* CONFIG_IEEE80211W */
    1692             : 
    1693             : #ifdef CONFIG_IEEE80211R
    1694        3466 :                 if (sta->auth_alg == WLAN_AUTH_FT) {
    1695         230 :                         if (!reassoc) {
    1696          12 :                                 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
    1697             :                                            "to use association (not "
    1698             :                                            "re-association) with FT auth_alg",
    1699          12 :                                            MAC2STR(sta->addr));
    1700           2 :                                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1701             :                         }
    1702             : 
    1703         228 :                         resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
    1704             :                                                        ies_len);
    1705         228 :                         if (resp != WLAN_STATUS_SUCCESS)
    1706           1 :                                 return resp;
    1707             :                 }
    1708             : #endif /* CONFIG_IEEE80211R */
    1709             : 
    1710             : #ifdef CONFIG_SAE
    1711        3535 :                 if (wpa_auth_uses_sae(sta->wpa_sm) &&
    1712          73 :                     sta->auth_alg == WLAN_AUTH_OPEN) {
    1713             :                         struct rsn_pmksa_cache_entry *sa;
    1714           2 :                         sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
    1715           2 :                         if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) {
    1716           6 :                                 wpa_printf(MSG_DEBUG,
    1717             :                                            "SAE: No PMKSA cache entry found for "
    1718           6 :                                            MACSTR, MAC2STR(sta->addr));
    1719           1 :                                 return WLAN_STATUS_INVALID_PMKID;
    1720             :                         }
    1721           6 :                         wpa_printf(MSG_DEBUG, "SAE: " MACSTR
    1722           6 :                                    " using PMKSA caching", MAC2STR(sta->addr));
    1723        3531 :                 } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
    1724          74 :                            sta->auth_alg != WLAN_AUTH_SAE &&
    1725           8 :                            !(sta->auth_alg == WLAN_AUTH_FT &&
    1726           4 :                              wpa_auth_uses_ft_sae(sta->wpa_sm))) {
    1727           0 :                         wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
    1728             :                                    "SAE AKM after non-SAE auth_alg %u",
    1729           0 :                                    MAC2STR(sta->addr), sta->auth_alg);
    1730           0 :                         return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
    1731             :                 }
    1732             : #endif /* CONFIG_SAE */
    1733             : 
    1734             : #ifdef CONFIG_IEEE80211N
    1735        6898 :                 if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
    1736        3436 :                     wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
    1737           0 :                         hostapd_logger(hapd, sta->addr,
    1738             :                                        HOSTAPD_MODULE_IEEE80211,
    1739             :                                        HOSTAPD_LEVEL_INFO,
    1740             :                                        "Station tried to use TKIP with HT "
    1741             :                                        "association");
    1742           0 :                         return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
    1743             :                 }
    1744             : #endif /* CONFIG_IEEE80211N */
    1745             : #ifdef CONFIG_HS20
    1746        1297 :         } else if (hapd->conf->osen) {
    1747           5 :                 if (elems.osen == NULL) {
    1748           3 :                         hostapd_logger(
    1749           3 :                                 hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    1750             :                                 HOSTAPD_LEVEL_INFO,
    1751             :                                 "No HS 2.0 OSEN element in association request");
    1752           3 :                         return WLAN_STATUS_INVALID_IE;
    1753             :                 }
    1754             : 
    1755           2 :                 wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
    1756           2 :                 if (sta->wpa_sm == NULL)
    1757           2 :                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
    1758           2 :                                                         sta->addr, NULL);
    1759           2 :                 if (sta->wpa_sm == NULL) {
    1760           0 :                         wpa_printf(MSG_WARNING, "Failed to initialize WPA "
    1761             :                                    "state machine");
    1762           0 :                         return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1763             :                 }
    1764           4 :                 if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
    1765           4 :                                       elems.osen - 2, elems.osen_len + 2) < 0)
    1766           0 :                         return WLAN_STATUS_INVALID_IE;
    1767             : #endif /* CONFIG_HS20 */
    1768             :         } else
    1769        1292 :                 wpa_auth_sta_no_wpa(sta->wpa_sm);
    1770             : 
    1771             : #ifdef CONFIG_P2P
    1772         576 :         p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
    1773             : #endif /* CONFIG_P2P */
    1774             : 
    1775             : #ifdef CONFIG_HS20
    1776        4756 :         wpabuf_free(sta->hs20_ie);
    1777        4756 :         if (elems.hs20 && elems.hs20_len > 4) {
    1778         114 :                 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
    1779         114 :                                                  elems.hs20_len - 4);
    1780             :         } else
    1781        4642 :                 sta->hs20_ie = NULL;
    1782             : #endif /* CONFIG_HS20 */
    1783             : 
    1784             : #ifdef CONFIG_FST
    1785        4756 :         wpabuf_free(sta->mb_ies);
    1786        4756 :         if (hapd->iface->fst)
    1787         247 :                 sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
    1788             :         else
    1789        4509 :                 sta->mb_ies = NULL;
    1790             : #endif /* CONFIG_FST */
    1791             : 
    1792             : #ifdef CONFIG_MBO
    1793        4756 :         mbo_ap_check_sta_assoc(hapd, sta, &elems);
    1794             : 
    1795        4757 :         if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
    1796           2 :             elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
    1797           0 :             hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
    1798           0 :                 wpa_printf(MSG_INFO,
    1799             :                            "MBO: Reject WPA2 association without PMF");
    1800           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    1801             :         }
    1802             : #endif /* CONFIG_MBO */
    1803             : 
    1804        4756 :         ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
    1805        4756 :                                     elems.supp_op_classes_len);
    1806             : 
    1807        4760 :         if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
    1808           8 :             elems.rrm_enabled &&
    1809           4 :             elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
    1810           4 :                 os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
    1811             :                           sizeof(sta->rrm_enabled_capa));
    1812             : 
    1813        4756 :         return WLAN_STATUS_SUCCESS;
    1814             : }
    1815             : 
    1816             : 
    1817           0 : static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
    1818             :                         u16 reason_code)
    1819             : {
    1820             :         int send_len;
    1821             :         struct ieee80211_mgmt reply;
    1822             : 
    1823           0 :         os_memset(&reply, 0, sizeof(reply));
    1824           0 :         reply.frame_control =
    1825             :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
    1826           0 :         os_memcpy(reply.da, addr, ETH_ALEN);
    1827           0 :         os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
    1828           0 :         os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
    1829             : 
    1830           0 :         send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
    1831           0 :         reply.u.deauth.reason_code = host_to_le16(reason_code);
    1832             : 
    1833           0 :         if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0) < 0)
    1834           0 :                 wpa_printf(MSG_INFO, "Failed to send deauth: %s",
    1835           0 :                            strerror(errno));
    1836           0 : }
    1837             : 
    1838             : 
    1839        4756 : static int add_associated_sta(struct hostapd_data *hapd,
    1840             :                               struct sta_info *sta)
    1841             : {
    1842             :         struct ieee80211_ht_capabilities ht_cap;
    1843             :         struct ieee80211_vht_capabilities vht_cap;
    1844             : 
    1845             :         /*
    1846             :          * Remove the STA entry to ensure the STA PS state gets cleared and
    1847             :          * configuration gets updated. This is relevant for cases, such as
    1848             :          * FT-over-the-DS, where a station re-associates back to the same AP but
    1849             :          * skips the authentication flow, or if working with a driver that
    1850             :          * does not support full AP client state.
    1851             :          */
    1852        4756 :         if (!sta->added_unassoc)
    1853         114 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    1854             : 
    1855             : #ifdef CONFIG_IEEE80211N
    1856        4756 :         if (sta->flags & WLAN_STA_HT)
    1857        4699 :                 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
    1858             : #endif /* CONFIG_IEEE80211N */
    1859             : #ifdef CONFIG_IEEE80211AC
    1860        4756 :         if (sta->flags & WLAN_STA_VHT)
    1861          35 :                 hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
    1862             : #endif /* CONFIG_IEEE80211AC */
    1863             : 
    1864             :         /*
    1865             :          * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
    1866             :          * will be set when the ACK frame for the (Re)Association Response frame
    1867             :          * is processed (TX status driver event).
    1868             :          */
    1869       47560 :         if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
    1870        9512 :                             sta->supported_rates, sta->supported_rates_len,
    1871        4756 :                             sta->listen_interval,
    1872        4756 :                             sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
    1873        4756 :                             sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
    1874        9512 :                             sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
    1875        9512 :                             sta->vht_opmode, sta->p2p_ie ? 1 : 0,
    1876        4756 :                             sta->added_unassoc)) {
    1877           0 :                 hostapd_logger(hapd, sta->addr,
    1878             :                                HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
    1879             :                                "Could not %s STA to kernel driver",
    1880           0 :                                sta->added_unassoc ? "set" : "add");
    1881             : 
    1882           0 :                 if (sta->added_unassoc) {
    1883           0 :                         hostapd_drv_sta_remove(hapd, sta->addr);
    1884           0 :                         sta->added_unassoc = 0;
    1885             :                 }
    1886             : 
    1887           0 :                 return -1;
    1888             :         }
    1889             : 
    1890        4756 :         sta->added_unassoc = 0;
    1891             : 
    1892        4756 :         return 0;
    1893             : }
    1894             : 
    1895             : 
    1896        4806 : static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
    1897             :                            u16 status_code, int reassoc, const u8 *ies,
    1898             :                            size_t ies_len)
    1899             : {
    1900             :         int send_len;
    1901             :         u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
    1902             :         struct ieee80211_mgmt *reply;
    1903             :         u8 *p;
    1904             : 
    1905        4806 :         os_memset(buf, 0, sizeof(buf));
    1906        4806 :         reply = (struct ieee80211_mgmt *) buf;
    1907        4806 :         reply->frame_control =
    1908        4806 :                 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    1909             :                              (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
    1910             :                               WLAN_FC_STYPE_ASSOC_RESP));
    1911        4806 :         os_memcpy(reply->da, sta->addr, ETH_ALEN);
    1912        4806 :         os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
    1913        4806 :         os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
    1914             : 
    1915        4806 :         send_len = IEEE80211_HDRLEN;
    1916        4806 :         send_len += sizeof(reply->u.assoc_resp);
    1917        4806 :         reply->u.assoc_resp.capab_info =
    1918        4806 :                 host_to_le16(hostapd_own_capab_info(hapd));
    1919        4806 :         reply->u.assoc_resp.status_code = host_to_le16(status_code);
    1920        4806 :         reply->u.assoc_resp.aid = host_to_le16(sta->aid | BIT(14) | BIT(15));
    1921             :         /* Supported rates */
    1922        4806 :         p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
    1923             :         /* Extended supported rates */
    1924        4806 :         p = hostapd_eid_ext_supp_rates(hapd, p);
    1925             : 
    1926             : #ifdef CONFIG_IEEE80211R
    1927        4806 :         if (status_code == WLAN_STATUS_SUCCESS) {
    1928             :                 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
    1929             :                  * Transition Information, RSN, [RIC Response] */
    1930        9512 :                 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
    1931        4756 :                                                 buf + sizeof(buf) - p,
    1932        4756 :                                                 sta->auth_alg, ies, ies_len);
    1933             :         }
    1934             : #endif /* CONFIG_IEEE80211R */
    1935             : 
    1936             : #ifdef CONFIG_IEEE80211W
    1937        4806 :         if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
    1938           4 :                 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
    1939             : #endif /* CONFIG_IEEE80211W */
    1940             : 
    1941             : #ifdef CONFIG_IEEE80211N
    1942        4806 :         p = hostapd_eid_ht_capabilities(hapd, p);
    1943        4806 :         p = hostapd_eid_ht_operation(hapd, p);
    1944             : #endif /* CONFIG_IEEE80211N */
    1945             : 
    1946             : #ifdef CONFIG_IEEE80211AC
    1947        4806 :         if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
    1948          35 :                 u32 nsts = 0, sta_nsts;
    1949             : 
    1950          35 :                 if (hapd->conf->use_sta_nsts && sta->vht_capabilities) {
    1951             :                         struct ieee80211_vht_capabilities *capa;
    1952             : 
    1953           1 :                         nsts = (hapd->iface->conf->vht_capab >>
    1954             :                                 VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
    1955           1 :                         capa = sta->vht_capabilities;
    1956           1 :                         sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
    1957             :                                     VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
    1958             : 
    1959           1 :                         if (nsts < sta_nsts)
    1960           0 :                                 nsts = 0;
    1961             :                         else
    1962           1 :                                 nsts = sta_nsts;
    1963             :                 }
    1964          35 :                 p = hostapd_eid_vht_capabilities(hapd, p, nsts);
    1965          35 :                 p = hostapd_eid_vht_operation(hapd, p);
    1966             :         }
    1967             : #endif /* CONFIG_IEEE80211AC */
    1968             : 
    1969        4806 :         p = hostapd_eid_ext_capab(hapd, p);
    1970        4806 :         p = hostapd_eid_bss_max_idle_period(hapd, p);
    1971        4806 :         if (sta->qos_map_enabled)
    1972        4669 :                 p = hostapd_eid_qos_map_set(hapd, p);
    1973             : 
    1974             : #ifdef CONFIG_FST
    1975        4806 :         if (hapd->iface->fst_ies) {
    1976         247 :                 os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
    1977             :                           wpabuf_len(hapd->iface->fst_ies));
    1978         247 :                 p += wpabuf_len(hapd->iface->fst_ies);
    1979             :         }
    1980             : #endif /* CONFIG_FST */
    1981             : 
    1982             : #ifdef CONFIG_IEEE80211AC
    1983        4806 :         if (hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
    1984           1 :                 p = hostapd_eid_vendor_vht(hapd, p);
    1985             : #endif /* CONFIG_IEEE80211AC */
    1986             : 
    1987        4806 :         if (sta->flags & WLAN_STA_WMM)
    1988        4792 :                 p = hostapd_eid_wmm(hapd, p);
    1989             : 
    1990             : #ifdef CONFIG_WPS
    1991        9077 :         if ((sta->flags & WLAN_STA_WPS) ||
    1992        4289 :             ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa)) {
    1993         535 :                 struct wpabuf *wps = wps_build_assoc_resp_ie();
    1994         535 :                 if (wps) {
    1995         534 :                         os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
    1996         534 :                         p += wpabuf_len(wps);
    1997         534 :                         wpabuf_free(wps);
    1998             :                 }
    1999             :         }
    2000             : #endif /* CONFIG_WPS */
    2001             : 
    2002             : #ifdef CONFIG_P2P
    2003         577 :         if (sta->p2p_ie && hapd->p2p_group) {
    2004             :                 struct wpabuf *p2p_resp_ie;
    2005             :                 enum p2p_status_code status;
    2006         523 :                 switch (status_code) {
    2007             :                 case WLAN_STATUS_SUCCESS:
    2008         523 :                         status = P2P_SC_SUCCESS;
    2009         523 :                         break;
    2010             :                 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
    2011           0 :                         status = P2P_SC_FAIL_LIMIT_REACHED;
    2012           0 :                         break;
    2013             :                 default:
    2014           0 :                         status = P2P_SC_FAIL_INVALID_PARAMS;
    2015           0 :                         break;
    2016             :                 }
    2017         523 :                 p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
    2018         523 :                 if (p2p_resp_ie) {
    2019         523 :                         os_memcpy(p, wpabuf_head(p2p_resp_ie),
    2020             :                                   wpabuf_len(p2p_resp_ie));
    2021         523 :                         p += wpabuf_len(p2p_resp_ie);
    2022         523 :                         wpabuf_free(p2p_resp_ie);
    2023             :                 }
    2024             :         }
    2025             : #endif /* CONFIG_P2P */
    2026             : 
    2027             : #ifdef CONFIG_P2P_MANAGER
    2028        4229 :         if (hapd->conf->p2p & P2P_MANAGE)
    2029           5 :                 p = hostapd_eid_p2p_manage(hapd, p);
    2030             : #endif /* CONFIG_P2P_MANAGER */
    2031             : 
    2032        4806 :         p = hostapd_eid_mbo(hapd, p, buf + sizeof(buf) - p);
    2033             : 
    2034        4807 :         if (hapd->conf->assocresp_elements &&
    2035           1 :             (size_t) (buf + sizeof(buf) - p) >=
    2036           1 :             wpabuf_len(hapd->conf->assocresp_elements)) {
    2037           1 :                 os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
    2038             :                           wpabuf_len(hapd->conf->assocresp_elements));
    2039           1 :                 p += wpabuf_len(hapd->conf->assocresp_elements);
    2040             :         }
    2041             : 
    2042        4806 :         send_len += p - reply->u.assoc_resp.variable;
    2043             : 
    2044        4806 :         if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
    2045           0 :                 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
    2046           0 :                            strerror(errno));
    2047           0 :                 return WLAN_STATUS_UNSPECIFIED_FAILURE;
    2048             :         }
    2049             : 
    2050        4806 :         return WLAN_STATUS_SUCCESS;
    2051             : }
    2052             : 
    2053             : 
    2054        4806 : static void handle_assoc(struct hostapd_data *hapd,
    2055             :                          const struct ieee80211_mgmt *mgmt, size_t len,
    2056             :                          int reassoc)
    2057             : {
    2058             :         u16 capab_info, listen_interval, seq_ctrl, fc;
    2059        4806 :         u16 resp = WLAN_STATUS_SUCCESS, reply_res;
    2060             :         const u8 *pos;
    2061             :         int left, i;
    2062             :         struct sta_info *sta;
    2063             : 
    2064        4806 :         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
    2065             :                                       sizeof(mgmt->u.assoc_req))) {
    2066           0 :                 wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
    2067             :                            reassoc, (unsigned long) len);
    2068           0 :                 return;
    2069             :         }
    2070             : 
    2071             : #ifdef CONFIG_TESTING_OPTIONS
    2072        4806 :         if (reassoc) {
    2073         339 :                 if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
    2074           0 :                     drand48() < hapd->iconf->ignore_reassoc_probability) {
    2075           0 :                         wpa_printf(MSG_INFO,
    2076             :                                    "TESTING: ignoring reassoc request from "
    2077           0 :                                    MACSTR, MAC2STR(mgmt->sa));
    2078           0 :                         return;
    2079             :                 }
    2080             :         } else {
    2081        4470 :                 if (hapd->iconf->ignore_assoc_probability > 0.0 &&
    2082           3 :                     drand48() < hapd->iconf->ignore_assoc_probability) {
    2083           0 :                         wpa_printf(MSG_INFO,
    2084             :                                    "TESTING: ignoring assoc request from "
    2085           0 :                                    MACSTR, MAC2STR(mgmt->sa));
    2086           0 :                         return;
    2087             :                 }
    2088             :         }
    2089             : #endif /* CONFIG_TESTING_OPTIONS */
    2090             : 
    2091        4806 :         fc = le_to_host16(mgmt->frame_control);
    2092        4806 :         seq_ctrl = le_to_host16(mgmt->seq_ctrl);
    2093             : 
    2094        4806 :         if (reassoc) {
    2095         339 :                 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
    2096         339 :                 listen_interval = le_to_host16(
    2097             :                         mgmt->u.reassoc_req.listen_interval);
    2098        4407 :                 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
    2099             :                            " capab_info=0x%02x listen_interval=%d current_ap="
    2100             :                            MACSTR " seq_ctrl=0x%x%s",
    2101        2034 :                            MAC2STR(mgmt->sa), capab_info, listen_interval,
    2102        2034 :                            MAC2STR(mgmt->u.reassoc_req.current_ap),
    2103         339 :                            seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
    2104         339 :                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
    2105         339 :                 pos = mgmt->u.reassoc_req.variable;
    2106             :         } else {
    2107        4467 :                 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
    2108        4467 :                 listen_interval = le_to_host16(
    2109             :                         mgmt->u.assoc_req.listen_interval);
    2110       31269 :                 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
    2111             :                            " capab_info=0x%02x listen_interval=%d "
    2112             :                            "seq_ctrl=0x%x%s",
    2113       26802 :                            MAC2STR(mgmt->sa), capab_info, listen_interval,
    2114        4467 :                            seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
    2115        4467 :                 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
    2116        4467 :                 pos = mgmt->u.assoc_req.variable;
    2117             :         }
    2118             : 
    2119        4806 :         sta = ap_get_sta(hapd, mgmt->sa);
    2120             : #ifdef CONFIG_IEEE80211R
    2121        5036 :         if (sta && sta->auth_alg == WLAN_AUTH_FT &&
    2122         230 :             (sta->flags & WLAN_STA_AUTH) == 0) {
    2123          30 :                 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
    2124             :                            "prior to authentication since it is using "
    2125          30 :                            "over-the-DS FT", MAC2STR(mgmt->sa));
    2126             : 
    2127             :                 /*
    2128             :                  * Mark station as authenticated, to avoid adding station
    2129             :                  * entry in the driver as associated and not authenticated
    2130             :                  */
    2131           5 :                 sta->flags |= WLAN_STA_AUTH;
    2132             :         } else
    2133             : #endif /* CONFIG_IEEE80211R */
    2134        4801 :         if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
    2135           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2136             :                                HOSTAPD_LEVEL_INFO, "Station tried to "
    2137             :                                "associate before authentication "
    2138             :                                "(aid=%d flags=0x%x)",
    2139           0 :                                sta ? sta->aid : -1,
    2140             :                                sta ? sta->flags : 0);
    2141           0 :                 send_deauth(hapd, mgmt->sa,
    2142             :                             WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
    2143           0 :                 return;
    2144             :         }
    2145             : 
    2146        4806 :         if ((fc & WLAN_FC_RETRY) &&
    2147           0 :             sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
    2148           0 :             sta->last_seq_ctrl == seq_ctrl &&
    2149           0 :             sta->last_subtype == reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
    2150             :             WLAN_FC_STYPE_ASSOC_REQ) {
    2151           0 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2152             :                                HOSTAPD_LEVEL_DEBUG,
    2153             :                                "Drop repeated association frame seq_ctrl=0x%x",
    2154             :                                seq_ctrl);
    2155           0 :                 return;
    2156             :         }
    2157        4806 :         sta->last_seq_ctrl = seq_ctrl;
    2158        4806 :         sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
    2159             :                 WLAN_FC_STYPE_ASSOC_REQ;
    2160             : 
    2161        4806 :         if (hapd->tkip_countermeasures) {
    2162           0 :                 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
    2163           0 :                 goto fail;
    2164             :         }
    2165             : 
    2166        4806 :         if (listen_interval > hapd->conf->max_listen_interval) {
    2167           2 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2168             :                                HOSTAPD_LEVEL_DEBUG,
    2169             :                                "Too large Listen Interval (%d)",
    2170             :                                listen_interval);
    2171           2 :                 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
    2172           2 :                 goto fail;
    2173             :         }
    2174             : 
    2175             : #ifdef CONFIG_MBO
    2176        4804 :         if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
    2177           1 :                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    2178           1 :                 goto fail;
    2179             :         }
    2180             : #endif /* CONFIG_MBO */
    2181             : 
    2182             :         /*
    2183             :          * sta->capability is used in check_assoc_ies() for RRM enabled
    2184             :          * capability element.
    2185             :          */
    2186        4803 :         sta->capability = capab_info;
    2187             : 
    2188             :         /* followed by SSID and Supported rates; and HT capabilities if 802.11n
    2189             :          * is used */
    2190        4803 :         resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
    2191        4803 :         if (resp != WLAN_STATUS_SUCCESS)
    2192          47 :                 goto fail;
    2193             : 
    2194        4756 :         if (hostapd_get_aid(hapd, sta) < 0) {
    2195           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2196             :                                HOSTAPD_LEVEL_INFO, "No room for more AIDs");
    2197           0 :                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    2198           0 :                 goto fail;
    2199             :         }
    2200             : 
    2201        4756 :         sta->listen_interval = listen_interval;
    2202             : 
    2203        4756 :         if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    2204        4540 :                 sta->flags |= WLAN_STA_NONERP;
    2205       30380 :         for (i = 0; i < sta->supported_rates_len; i++) {
    2206       30375 :                 if ((sta->supported_rates[i] & 0x7f) > 22) {
    2207        4751 :                         sta->flags &= ~WLAN_STA_NONERP;
    2208        4751 :                         break;
    2209             :                 }
    2210             :         }
    2211        4756 :         if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
    2212           0 :                 sta->nonerp_set = 1;
    2213           0 :                 hapd->iface->num_sta_non_erp++;
    2214           0 :                 if (hapd->iface->num_sta_non_erp == 1)
    2215           0 :                         ieee802_11_set_beacons(hapd->iface);
    2216             :         }
    2217             : 
    2218        4967 :         if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
    2219         211 :             !sta->no_short_slot_time_set) {
    2220         210 :                 sta->no_short_slot_time_set = 1;
    2221         210 :                 hapd->iface->num_sta_no_short_slot_time++;
    2222         210 :                 if (hapd->iface->current_mode->mode ==
    2223           0 :                     HOSTAPD_MODE_IEEE80211G &&
    2224           0 :                     hapd->iface->num_sta_no_short_slot_time == 1)
    2225           0 :                         ieee802_11_set_beacons(hapd->iface);
    2226             :         }
    2227             : 
    2228        4756 :         if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
    2229        4545 :                 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
    2230             :         else
    2231         211 :                 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
    2232             : 
    2233        4967 :         if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
    2234         211 :             !sta->no_short_preamble_set) {
    2235         210 :                 sta->no_short_preamble_set = 1;
    2236         210 :                 hapd->iface->num_sta_no_short_preamble++;
    2237         210 :                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
    2238           0 :                     && hapd->iface->num_sta_no_short_preamble == 1)
    2239           0 :                         ieee802_11_set_beacons(hapd->iface);
    2240             :         }
    2241             : 
    2242             : #ifdef CONFIG_IEEE80211N
    2243        4756 :         update_ht_state(hapd, sta);
    2244             : #endif /* CONFIG_IEEE80211N */
    2245             : 
    2246        4756 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2247             :                        HOSTAPD_LEVEL_DEBUG,
    2248        4756 :                        "association OK (aid %d)", sta->aid);
    2249             :         /* Station will be marked associated, after it acknowledges AssocResp
    2250             :          */
    2251        4756 :         sta->flags |= WLAN_STA_ASSOC_REQ_OK;
    2252             : 
    2253             : #ifdef CONFIG_IEEE80211W
    2254        4756 :         if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
    2255           3 :                 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
    2256             :                            "SA Query procedure", reassoc ? "re" : "");
    2257             :                 /* TODO: Send a protected Disassociate frame to the STA using
    2258             :                  * the old key and Reason Code "Previous Authentication no
    2259             :                  * longer valid". Make sure this is only sent protected since
    2260             :                  * unprotected frame would be received by the STA that is now
    2261             :                  * trying to associate.
    2262             :                  */
    2263             :         }
    2264             : #endif /* CONFIG_IEEE80211W */
    2265             : 
    2266             :         /* Make sure that the previously registered inactivity timer will not
    2267             :          * remove the STA immediately. */
    2268        4756 :         sta->timeout_next = STA_NULLFUNC;
    2269             : 
    2270             : #ifdef CONFIG_TAXONOMY
    2271        4180 :         taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
    2272             : #endif /* CONFIG_TAXONOMY */
    2273             : 
    2274             :  fail:
    2275             :         /*
    2276             :          * In case of a successful response, add the station to the driver.
    2277             :          * Otherwise, the kernel may ignore Data frames before we process the
    2278             :          * ACK frame (TX status). In case of a failure, this station will be
    2279             :          * removed.
    2280             :          *
    2281             :          * Note that this is not compliant with the IEEE 802.11 standard that
    2282             :          * states that a non-AP station should transition into the
    2283             :          * authenticated/associated state only after the station acknowledges
    2284             :          * the (Re)Association Response frame. However, still do this as:
    2285             :          *
    2286             :          * 1. In case the station does not acknowledge the (Re)Association
    2287             :          *    Response frame, it will be removed.
    2288             :          * 2. Data frames will be dropped in the kernel until the station is
    2289             :          *    set into authorized state, and there are no significant known
    2290             :          *    issues with processing other non-Data Class 3 frames during this
    2291             :          *    window.
    2292             :          */
    2293        4806 :         if (resp == WLAN_STATUS_SUCCESS && add_associated_sta(hapd, sta))
    2294           0 :                 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
    2295             : 
    2296        4806 :         reply_res = send_assoc_resp(hapd, sta, resp, reassoc, pos, left);
    2297             : 
    2298             :         /*
    2299             :          * Remove the station in case tranmission of a success response fails
    2300             :          * (the STA was added associated to the driver) or if the station was
    2301             :          * previously added unassociated.
    2302             :          */
    2303        4806 :         if ((reply_res != WLAN_STATUS_SUCCESS &&
    2304        4806 :              resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc) {
    2305          49 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    2306          49 :                 sta->added_unassoc = 0;
    2307             :         }
    2308             : }
    2309             : 
    2310             : 
    2311           1 : static void handle_disassoc(struct hostapd_data *hapd,
    2312             :                             const struct ieee80211_mgmt *mgmt, size_t len)
    2313             : {
    2314             :         struct sta_info *sta;
    2315             : 
    2316           1 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
    2317           0 :                 wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
    2318             :                            (unsigned long) len);
    2319           0 :                 return;
    2320             :         }
    2321             : 
    2322           7 :         wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
    2323           6 :                    MAC2STR(mgmt->sa),
    2324           1 :                    le_to_host16(mgmt->u.disassoc.reason_code));
    2325             : 
    2326           1 :         sta = ap_get_sta(hapd, mgmt->sa);
    2327           1 :         if (sta == NULL) {
    2328           0 :                 wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated",
    2329           0 :                            MAC2STR(mgmt->sa));
    2330           0 :                 return;
    2331             :         }
    2332             : 
    2333           1 :         ap_sta_set_authorized(hapd, sta, 0);
    2334           1 :         sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
    2335           1 :         sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
    2336           1 :         wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
    2337           1 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2338             :                        HOSTAPD_LEVEL_INFO, "disassociated");
    2339           1 :         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    2340           1 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    2341             :         /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
    2342             :          * authenticated. */
    2343           1 :         accounting_sta_stop(hapd, sta);
    2344           1 :         ieee802_1x_free_station(hapd, sta);
    2345           1 :         if (sta->ipaddr)
    2346           0 :                 hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
    2347           1 :         ap_sta_ip6addr_del(hapd, sta);
    2348           1 :         hostapd_drv_sta_remove(hapd, sta->addr);
    2349           1 :         sta->added_unassoc = 0;
    2350             : 
    2351           1 :         if (sta->timeout_next == STA_NULLFUNC ||
    2352           0 :             sta->timeout_next == STA_DISASSOC) {
    2353           1 :                 sta->timeout_next = STA_DEAUTH;
    2354           1 :                 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    2355           1 :                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
    2356             :                                        hapd, sta);
    2357             :         }
    2358             : 
    2359           1 :         mlme_disassociate_indication(
    2360           1 :                 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
    2361             : }
    2362             : 
    2363             : 
    2364        3882 : static void handle_deauth(struct hostapd_data *hapd,
    2365             :                           const struct ieee80211_mgmt *mgmt, size_t len)
    2366             : {
    2367             :         struct sta_info *sta;
    2368             : 
    2369        3882 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
    2370           0 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
    2371             :                         "payload (len=%lu)", (unsigned long) len);
    2372           0 :                 return;
    2373             :         }
    2374             : 
    2375       27174 :         wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
    2376             :                 " reason_code=%d",
    2377       27174 :                 MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
    2378             : 
    2379        3882 :         sta = ap_get_sta(hapd, mgmt->sa);
    2380        3882 :         if (sta == NULL) {
    2381           0 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
    2382             :                         "to deauthenticate, but it is not authenticated",
    2383           0 :                         MAC2STR(mgmt->sa));
    2384           0 :                 return;
    2385             :         }
    2386             : 
    2387        3882 :         ap_sta_set_authorized(hapd, sta, 0);
    2388        3882 :         sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
    2389        3882 :         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
    2390             :                         WLAN_STA_ASSOC_REQ_OK);
    2391        3882 :         wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
    2392        3882 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2393             :                        HOSTAPD_LEVEL_DEBUG, "deauthenticated");
    2394        3882 :         mlme_deauthenticate_indication(
    2395        3882 :                 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
    2396        3882 :         sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
    2397        3882 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
    2398        3882 :         ap_free_sta(hapd, sta);
    2399             : }
    2400             : 
    2401             : 
    2402       11630 : static void handle_beacon(struct hostapd_data *hapd,
    2403             :                           const struct ieee80211_mgmt *mgmt, size_t len,
    2404             :                           struct hostapd_frame_info *fi)
    2405             : {
    2406             :         struct ieee802_11_elems elems;
    2407             : 
    2408       11630 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
    2409           0 :                 wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
    2410             :                            (unsigned long) len);
    2411       11630 :                 return;
    2412             :         }
    2413             : 
    2414       11630 :         (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
    2415             :                                       len - (IEEE80211_HDRLEN +
    2416             :                                              sizeof(mgmt->u.beacon)), &elems,
    2417             :                                       0);
    2418             : 
    2419       11630 :         ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
    2420             : }
    2421             : 
    2422             : 
    2423             : #ifdef CONFIG_IEEE80211W
    2424             : 
    2425           5 : static int hostapd_sa_query_action(struct hostapd_data *hapd,
    2426             :                                    const struct ieee80211_mgmt *mgmt,
    2427             :                                    size_t len)
    2428             : {
    2429             :         const u8 *end;
    2430             : 
    2431           5 :         end = mgmt->u.action.u.sa_query_resp.trans_id +
    2432             :                 WLAN_SA_QUERY_TR_ID_LEN;
    2433           5 :         if (((u8 *) mgmt) + len < end) {
    2434           0 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short SA Query Action "
    2435             :                            "frame (len=%lu)", (unsigned long) len);
    2436           0 :                 return 0;
    2437             :         }
    2438             : 
    2439           5 :         ieee802_11_sa_query_action(hapd, mgmt->sa,
    2440           5 :                                    mgmt->u.action.u.sa_query_resp.action,
    2441           5 :                                    mgmt->u.action.u.sa_query_resp.trans_id);
    2442           5 :         return 1;
    2443             : }
    2444             : 
    2445             : 
    2446           0 : static int robust_action_frame(u8 category)
    2447             : {
    2448           0 :         return category != WLAN_ACTION_PUBLIC &&
    2449             :                 category != WLAN_ACTION_HT;
    2450             : }
    2451             : #endif /* CONFIG_IEEE80211W */
    2452             : 
    2453             : 
    2454        1671 : static int handle_action(struct hostapd_data *hapd,
    2455             :                          const struct ieee80211_mgmt *mgmt, size_t len)
    2456             : {
    2457             :         struct sta_info *sta;
    2458        1671 :         sta = ap_get_sta(hapd, mgmt->sa);
    2459             : 
    2460        1671 :         if (len < IEEE80211_HDRLEN + 1) {
    2461           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2462             :                                HOSTAPD_LEVEL_DEBUG,
    2463             :                                "handle_action - too short payload (len=%lu)",
    2464             :                                (unsigned long) len);
    2465           0 :                 return 0;
    2466             :         }
    2467             : 
    2468        1671 :         if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
    2469        1067 :             (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
    2470           0 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
    2471             :                            "frame (category=%u) from unassociated STA " MACSTR,
    2472           0 :                            MAC2STR(mgmt->sa), mgmt->u.action.category);
    2473           0 :                 return 0;
    2474             :         }
    2475             : 
    2476             : #ifdef CONFIG_IEEE80211W
    2477        1689 :         if (sta && (sta->flags & WLAN_STA_MFP) &&
    2478          18 :             !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
    2479           0 :             robust_action_frame(mgmt->u.action.category)) {
    2480           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2481             :                                HOSTAPD_LEVEL_DEBUG,
    2482             :                                "Dropped unprotected Robust Action frame from "
    2483             :                                "an MFP STA");
    2484           0 :                 return 0;
    2485             :         }
    2486             : #endif /* CONFIG_IEEE80211W */
    2487             : 
    2488        1671 :         if (sta) {
    2489        1276 :                 u16 fc = le_to_host16(mgmt->frame_control);
    2490        1276 :                 u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
    2491             : 
    2492        1276 :                 if ((fc & WLAN_FC_RETRY) &&
    2493           0 :                     sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
    2494           0 :                     sta->last_seq_ctrl == seq_ctrl &&
    2495           0 :                     sta->last_subtype == WLAN_FC_STYPE_ACTION) {
    2496           0 :                         hostapd_logger(hapd, sta->addr,
    2497             :                                        HOSTAPD_MODULE_IEEE80211,
    2498             :                                        HOSTAPD_LEVEL_DEBUG,
    2499             :                                        "Drop repeated action frame seq_ctrl=0x%x",
    2500             :                                        seq_ctrl);
    2501           0 :                         return 1;
    2502             :                 }
    2503             : 
    2504        1276 :                 sta->last_seq_ctrl = seq_ctrl;
    2505        1276 :                 sta->last_subtype = WLAN_FC_STYPE_ACTION;
    2506             :         }
    2507             : 
    2508        1671 :         switch (mgmt->u.action.category) {
    2509             : #ifdef CONFIG_IEEE80211R
    2510             :         case WLAN_ACTION_FT:
    2511         230 :                 if (!sta ||
    2512         115 :                     wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
    2513             :                                      len - IEEE80211_HDRLEN))
    2514             :                         break;
    2515         115 :                 return 1;
    2516             : #endif /* CONFIG_IEEE80211R */
    2517             :         case WLAN_ACTION_WMM:
    2518           6 :                 hostapd_wmm_action(hapd, mgmt, len);
    2519           6 :                 return 1;
    2520             : #ifdef CONFIG_IEEE80211W
    2521             :         case WLAN_ACTION_SA_QUERY:
    2522           5 :                 return hostapd_sa_query_action(hapd, mgmt, len);
    2523             : #endif /* CONFIG_IEEE80211W */
    2524             : #ifdef CONFIG_WNM
    2525             :         case WLAN_ACTION_WNM:
    2526         323 :                 ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
    2527         323 :                 return 1;
    2528             : #endif /* CONFIG_WNM */
    2529             : #ifdef CONFIG_FST
    2530             :         case WLAN_ACTION_FST:
    2531         592 :                 if (hapd->iface->fst)
    2532         592 :                         fst_rx_action(hapd->iface->fst, mgmt, len);
    2533             :                 else
    2534           0 :                         wpa_printf(MSG_DEBUG,
    2535             :                                    "FST: Ignore FST Action frame - no FST attached");
    2536         592 :                 return 1;
    2537             : #endif /* CONFIG_FST */
    2538             :         case WLAN_ACTION_PUBLIC:
    2539             :         case WLAN_ACTION_PROTECTED_DUAL:
    2540             : #ifdef CONFIG_IEEE80211N
    2541        1214 :                 if (len >= IEEE80211_HDRLEN + 2 &&
    2542         607 :                     mgmt->u.action.u.public_action.action ==
    2543             :                     WLAN_PA_20_40_BSS_COEX) {
    2544          84 :                         wpa_printf(MSG_DEBUG,
    2545             :                                    "HT20/40 coex mgmt frame received from STA "
    2546          84 :                                    MACSTR, MAC2STR(mgmt->sa));
    2547          14 :                         hostapd_2040_coex_action(hapd, mgmt, len);
    2548             :                 }
    2549             : #endif /* CONFIG_IEEE80211N */
    2550         607 :                 if (hapd->public_action_cb) {
    2551         168 :                         hapd->public_action_cb(hapd->public_action_cb_ctx,
    2552             :                                                (u8 *) mgmt, len,
    2553          84 :                                                hapd->iface->freq);
    2554             :                 }
    2555         607 :                 if (hapd->public_action_cb2) {
    2556        1214 :                         hapd->public_action_cb2(hapd->public_action_cb2_ctx,
    2557             :                                                 (u8 *) mgmt, len,
    2558         607 :                                                 hapd->iface->freq);
    2559             :                 }
    2560         607 :                 if (hapd->public_action_cb || hapd->public_action_cb2)
    2561         607 :                         return 1;
    2562           0 :                 break;
    2563             :         case WLAN_ACTION_VENDOR_SPECIFIC:
    2564           5 :                 if (hapd->vendor_action_cb) {
    2565          10 :                         if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
    2566             :                                                    (u8 *) mgmt, len,
    2567           5 :                                                    hapd->iface->freq) == 0)
    2568           5 :                                 return 1;
    2569             :                 }
    2570           0 :                 break;
    2571             :         case WLAN_ACTION_RADIO_MEASUREMENT:
    2572          18 :                 hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
    2573          18 :                 return 1;
    2574             :         }
    2575             : 
    2576           0 :         hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2577             :                        HOSTAPD_LEVEL_DEBUG,
    2578             :                        "handle_action - unknown action category %d or invalid "
    2579             :                        "frame",
    2580           0 :                        mgmt->u.action.category);
    2581           0 :         if (!is_multicast_ether_addr(mgmt->da) &&
    2582           0 :             !(mgmt->u.action.category & 0x80) &&
    2583           0 :             !is_multicast_ether_addr(mgmt->sa)) {
    2584             :                 struct ieee80211_mgmt *resp;
    2585             : 
    2586             :                 /*
    2587             :                  * IEEE 802.11-REVma/D9.0 - 7.3.1.11
    2588             :                  * Return the Action frame to the source without change
    2589             :                  * except that MSB of the Category set to 1.
    2590             :                  */
    2591           0 :                 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
    2592             :                            "frame back to sender");
    2593           0 :                 resp = os_malloc(len);
    2594           0 :                 if (resp == NULL)
    2595           0 :                         return 0;
    2596           0 :                 os_memcpy(resp, mgmt, len);
    2597           0 :                 os_memcpy(resp->da, resp->sa, ETH_ALEN);
    2598           0 :                 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
    2599           0 :                 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
    2600           0 :                 resp->u.action.category |= 0x80;
    2601             : 
    2602           0 :                 if (hostapd_drv_send_mlme(hapd, resp, len, 0) < 0) {
    2603           0 :                         wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
    2604             :                                    "Action frame");
    2605             :                 }
    2606           0 :                 os_free(resp);
    2607             :         }
    2608             : 
    2609           0 :         return 1;
    2610             : }
    2611             : 
    2612             : 
    2613             : /**
    2614             :  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
    2615             :  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
    2616             :  * sent to)
    2617             :  * @buf: management frame data (starting from IEEE 802.11 header)
    2618             :  * @len: length of frame data in octets
    2619             :  * @fi: meta data about received frame (signal level, etc.)
    2620             :  *
    2621             :  * Process all incoming IEEE 802.11 management frames. This will be called for
    2622             :  * each frame received from the kernel driver through wlan#ap interface. In
    2623             :  * addition, it can be called to re-inserted pending frames (e.g., when using
    2624             :  * external RADIUS server as an MAC ACL).
    2625             :  */
    2626       32268 : int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
    2627             :                     struct hostapd_frame_info *fi)
    2628             : {
    2629             :         struct ieee80211_mgmt *mgmt;
    2630             :         u16 fc, stype;
    2631       32268 :         int ret = 0;
    2632             : 
    2633       32268 :         if (len < 24)
    2634           0 :                 return 0;
    2635             : 
    2636       32268 :         mgmt = (struct ieee80211_mgmt *) buf;
    2637       32268 :         fc = le_to_host16(mgmt->frame_control);
    2638       32268 :         stype = WLAN_FC_GET_STYPE(fc);
    2639             : 
    2640       32268 :         if (stype == WLAN_FC_STYPE_BEACON) {
    2641       11630 :                 handle_beacon(hapd, mgmt, len, fi);
    2642       11630 :                 return 1;
    2643             :         }
    2644             : 
    2645       36536 :         if (!is_broadcast_ether_addr(mgmt->bssid) &&
    2646             : #ifdef CONFIG_P2P
    2647             :             /* Invitation responses can be sent with the peer MAC as BSSID */
    2648        3512 :             !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
    2649        1937 :               stype == WLAN_FC_STYPE_ACTION) &&
    2650             : #endif /* CONFIG_P2P */
    2651             : #ifdef CONFIG_MESH
    2652        3452 :             !(hapd->conf->mesh & MESH_ENABLED) &&
    2653             : #endif /* CONFIG_MESH */
    2654       15387 :             os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
    2655           0 :                 wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
    2656           0 :                            MAC2STR(mgmt->bssid));
    2657           0 :                 return 0;
    2658             :         }
    2659             : 
    2660             : 
    2661       20638 :         if (stype == WLAN_FC_STYPE_PROBE_REQ) {
    2662        4979 :                 handle_probe_req(hapd, mgmt, len, fi->ssi_signal);
    2663        4979 :                 return 1;
    2664             :         }
    2665             : 
    2666       15659 :         if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
    2667           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2668             :                                HOSTAPD_LEVEL_DEBUG,
    2669             :                                "MGMT: DA=" MACSTR " not our address",
    2670           0 :                                MAC2STR(mgmt->da));
    2671           0 :                 return 0;
    2672             :         }
    2673             : 
    2674       15659 :         if (hapd->iconf->track_sta_max_num)
    2675          23 :                 sta_track_add(hapd->iface, mgmt->sa);
    2676             : 
    2677       15659 :         switch (stype) {
    2678             :         case WLAN_FC_STYPE_AUTH:
    2679        5299 :                 wpa_printf(MSG_DEBUG, "mgmt::auth");
    2680        5299 :                 handle_auth(hapd, mgmt, len);
    2681        5299 :                 ret = 1;
    2682        5299 :                 break;
    2683             :         case WLAN_FC_STYPE_ASSOC_REQ:
    2684        4467 :                 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
    2685        4467 :                 handle_assoc(hapd, mgmt, len, 0);
    2686        4467 :                 ret = 1;
    2687        4467 :                 break;
    2688             :         case WLAN_FC_STYPE_REASSOC_REQ:
    2689         339 :                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
    2690         339 :                 handle_assoc(hapd, mgmt, len, 1);
    2691         339 :                 ret = 1;
    2692         339 :                 break;
    2693             :         case WLAN_FC_STYPE_DISASSOC:
    2694           1 :                 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
    2695           1 :                 handle_disassoc(hapd, mgmt, len);
    2696           1 :                 ret = 1;
    2697           1 :                 break;
    2698             :         case WLAN_FC_STYPE_DEAUTH:
    2699        3882 :                 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
    2700        3882 :                 handle_deauth(hapd, mgmt, len);
    2701        3882 :                 ret = 1;
    2702        3882 :                 break;
    2703             :         case WLAN_FC_STYPE_ACTION:
    2704        1671 :                 wpa_printf(MSG_DEBUG, "mgmt::action");
    2705        1671 :                 ret = handle_action(hapd, mgmt, len);
    2706        1671 :                 break;
    2707             :         default:
    2708           0 :                 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
    2709             :                                HOSTAPD_LEVEL_DEBUG,
    2710             :                                "unknown mgmt frame subtype %d", stype);
    2711           0 :                 break;
    2712             :         }
    2713             : 
    2714       15659 :         return ret;
    2715             : }
    2716             : 
    2717             : 
    2718        4863 : static void handle_auth_cb(struct hostapd_data *hapd,
    2719             :                            const struct ieee80211_mgmt *mgmt,
    2720             :                            size_t len, int ok)
    2721             : {
    2722             :         u16 auth_alg, auth_transaction, status_code;
    2723             :         struct sta_info *sta;
    2724             : 
    2725        4863 :         sta = ap_get_sta(hapd, mgmt->da);
    2726        4863 :         if (!sta) {
    2727         222 :                 wpa_printf(MSG_INFO, "handle_auth_cb: STA " MACSTR " not found",
    2728         222 :                            MAC2STR(mgmt->da));
    2729          37 :                 return;
    2730             :         }
    2731             : 
    2732        4826 :         auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
    2733        4826 :         auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
    2734        4826 :         status_code = le_to_host16(mgmt->u.auth.status_code);
    2735             : 
    2736        4826 :         if (!ok) {
    2737           1 :                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
    2738             :                                HOSTAPD_LEVEL_NOTICE,
    2739             :                                "did not acknowledge authentication response");
    2740           1 :                 goto fail;
    2741             :         }
    2742             : 
    2743        4825 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
    2744           0 :                 wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
    2745             :                            (unsigned long) len);
    2746           0 :                 goto fail;
    2747             :         }
    2748             : 
    2749        4825 :         if (status_code == WLAN_STATUS_SUCCESS &&
    2750        4492 :             ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
    2751          26 :              (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
    2752        4505 :                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2753             :                                HOSTAPD_LEVEL_INFO, "authenticated");
    2754        4505 :                 sta->flags |= WLAN_STA_AUTH;
    2755        4505 :                 if (sta->added_unassoc)
    2756        4427 :                         hostapd_set_sta_flags(hapd, sta);
    2757        4505 :                 return;
    2758             :         }
    2759             : 
    2760             : fail:
    2761         321 :         if (status_code != WLAN_STATUS_SUCCESS && sta->added_unassoc) {
    2762           0 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    2763           0 :                 sta->added_unassoc = 0;
    2764             :         }
    2765             : }
    2766             : 
    2767             : 
    2768           1 : static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
    2769             :                                        struct sta_info *sta,
    2770             :                                        char *ifname_wds)
    2771             : {
    2772             :         int i;
    2773           1 :         struct hostapd_ssid *ssid = &hapd->conf->ssid;
    2774             : 
    2775           1 :         if (hapd->conf->ieee802_1x || hapd->conf->wpa)
    2776           2 :                 return;
    2777             : 
    2778           0 :         for (i = 0; i < 4; i++) {
    2779           0 :                 if (ssid->wep.key[i] &&
    2780           0 :                     hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
    2781           0 :                                         i == ssid->wep.idx, NULL, 0,
    2782           0 :                                         ssid->wep.key[i], ssid->wep.len[i])) {
    2783           0 :                         wpa_printf(MSG_WARNING,
    2784             :                                    "Could not set WEP keys for WDS interface; %s",
    2785             :                                    ifname_wds);
    2786           0 :                         break;
    2787             :                 }
    2788             :         }
    2789             : }
    2790             : 
    2791             : 
    2792        4806 : static void handle_assoc_cb(struct hostapd_data *hapd,
    2793             :                             const struct ieee80211_mgmt *mgmt,
    2794             :                             size_t len, int reassoc, int ok)
    2795             : {
    2796             :         u16 status;
    2797             :         struct sta_info *sta;
    2798        4806 :         int new_assoc = 1;
    2799             : 
    2800        4806 :         sta = ap_get_sta(hapd, mgmt->da);
    2801        4806 :         if (!sta) {
    2802           0 :                 wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
    2803           0 :                            MAC2STR(mgmt->da));
    2804           0 :                 return;
    2805             :         }
    2806             : 
    2807        4806 :         if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
    2808             :                                       sizeof(mgmt->u.assoc_resp))) {
    2809           0 :                 wpa_printf(MSG_INFO,
    2810             :                            "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
    2811             :                            reassoc, (unsigned long) len);
    2812           0 :                 hostapd_drv_sta_remove(hapd, sta->addr);
    2813           0 :                 return;
    2814             :         }
    2815             : 
    2816        4806 :         if (reassoc)
    2817         339 :                 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
    2818             :         else
    2819        4467 :                 status = le_to_host16(mgmt->u.assoc_resp.status_code);
    2820             : 
    2821        4806 :         if (!ok) {
    2822           0 :                 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
    2823             :                                HOSTAPD_LEVEL_DEBUG,
    2824             :                                "did not acknowledge association response");
    2825           0 :                 sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
    2826             :                 /* The STA is added only in case of SUCCESS */
    2827           0 :                 if (status == WLAN_STATUS_SUCCESS)
    2828           0 :                         hostapd_drv_sta_remove(hapd, sta->addr);
    2829             : 
    2830           0 :                 return;
    2831             :         }
    2832             : 
    2833        4806 :         if (status != WLAN_STATUS_SUCCESS)
    2834          50 :                 return;
    2835             : 
    2836             :         /* Stop previous accounting session, if one is started, and allocate
    2837             :          * new session id for the new session. */
    2838        4756 :         accounting_sta_stop(hapd, sta);
    2839             : 
    2840        4756 :         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
    2841             :                        HOSTAPD_LEVEL_INFO,
    2842             :                        "associated (aid %d)",
    2843        4756 :                        sta->aid);
    2844             : 
    2845        4756 :         if (sta->flags & WLAN_STA_ASSOC)
    2846           3 :                 new_assoc = 0;
    2847        4756 :         sta->flags |= WLAN_STA_ASSOC;
    2848        4756 :         sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
    2849        8750 :         if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) ||
    2850        3994 :             sta->auth_alg == WLAN_AUTH_FT) {
    2851             :                 /*
    2852             :                  * Open, static WEP, or FT protocol; no separate authorization
    2853             :                  * step.
    2854             :                  */
    2855         989 :                 ap_sta_set_authorized(hapd, sta, 1);
    2856             :         }
    2857             : 
    2858        4756 :         if (reassoc)
    2859         336 :                 mlme_reassociate_indication(hapd, sta);
    2860             :         else
    2861        4420 :                 mlme_associate_indication(hapd, sta);
    2862             : 
    2863             : #ifdef CONFIG_IEEE80211W
    2864        4756 :         sta->sa_query_timed_out = 0;
    2865             : #endif /* CONFIG_IEEE80211W */
    2866             : 
    2867        4756 :         if (sta->flags & WLAN_STA_WDS) {
    2868             :                 int ret;
    2869             :                 char ifname_wds[IFNAMSIZ + 1];
    2870             : 
    2871           0 :                 ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
    2872           0 :                                           sta->aid, 1);
    2873           0 :                 if (!ret)
    2874           0 :                         hostapd_set_wds_encryption(hapd, sta, ifname_wds);
    2875             :         }
    2876             : 
    2877        4756 :         if (sta->eapol_sm == NULL) {
    2878             :                 /*
    2879             :                  * This STA does not use RADIUS server for EAP authentication,
    2880             :                  * so bind it to the selected VLAN interface now, since the
    2881             :                  * interface selection is not going to change anymore.
    2882             :                  */
    2883        4586 :                 if (ap_sta_bind_vlan(hapd, sta) < 0)
    2884           0 :                         return;
    2885         170 :         } else if (sta->vlan_id) {
    2886             :                 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
    2887           0 :                 if (ap_sta_bind_vlan(hapd, sta) < 0)
    2888           0 :                         return;
    2889             :         }
    2890             : 
    2891        4756 :         hostapd_set_sta_flags(hapd, sta);
    2892             : 
    2893        4756 :         if (sta->auth_alg == WLAN_AUTH_FT)
    2894         227 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
    2895             :         else
    2896        4529 :                 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
    2897        4756 :         hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
    2898        4756 :         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
    2899             : 
    2900        4756 :         if (sta->pending_eapol_rx) {
    2901             :                 struct os_reltime now, age;
    2902             : 
    2903           0 :                 os_get_reltime(&now);
    2904           0 :                 os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
    2905           0 :                 if (age.sec == 0 && age.usec < 200000) {
    2906           0 :                         wpa_printf(MSG_DEBUG,
    2907             :                                    "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
    2908           0 :                                    MAC2STR(sta->addr));
    2909           0 :                         ieee802_1x_receive(
    2910           0 :                                 hapd, mgmt->da,
    2911           0 :                                 wpabuf_head(sta->pending_eapol_rx->buf),
    2912           0 :                                 wpabuf_len(sta->pending_eapol_rx->buf));
    2913             :                 }
    2914           0 :                 wpabuf_free(sta->pending_eapol_rx->buf);
    2915           0 :                 os_free(sta->pending_eapol_rx);
    2916           0 :                 sta->pending_eapol_rx = NULL;
    2917             :         }
    2918             : }
    2919             : 
    2920             : 
    2921         871 : static void handle_deauth_cb(struct hostapd_data *hapd,
    2922             :                              const struct ieee80211_mgmt *mgmt,
    2923             :                              size_t len, int ok)
    2924             : {
    2925             :         struct sta_info *sta;
    2926         871 :         if (is_multicast_ether_addr(mgmt->da))
    2927          31 :                 return;
    2928         840 :         sta = ap_get_sta(hapd, mgmt->da);
    2929         840 :         if (!sta) {
    2930        3042 :                 wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
    2931        3042 :                            " not found", MAC2STR(mgmt->da));
    2932         507 :                 return;
    2933             :         }
    2934         333 :         if (ok)
    2935        1986 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
    2936        1986 :                            MAC2STR(sta->addr));
    2937             :         else
    2938          12 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
    2939          12 :                            "deauth", MAC2STR(sta->addr));
    2940             : 
    2941         333 :         ap_sta_deauth_cb(hapd, sta);
    2942             : }
    2943             : 
    2944             : 
    2945          29 : static void handle_disassoc_cb(struct hostapd_data *hapd,
    2946             :                                const struct ieee80211_mgmt *mgmt,
    2947             :                                size_t len, int ok)
    2948             : {
    2949             :         struct sta_info *sta;
    2950          29 :         if (is_multicast_ether_addr(mgmt->da))
    2951           1 :                 return;
    2952          28 :         sta = ap_get_sta(hapd, mgmt->da);
    2953          28 :         if (!sta) {
    2954           0 :                 wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
    2955           0 :                            " not found", MAC2STR(mgmt->da));
    2956           0 :                 return;
    2957             :         }
    2958          28 :         if (ok)
    2959         156 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
    2960         156 :                            MAC2STR(sta->addr));
    2961             :         else
    2962          12 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
    2963          12 :                            "disassoc", MAC2STR(sta->addr));
    2964             : 
    2965          28 :         ap_sta_disassoc_cb(hapd, sta);
    2966             : }
    2967             : 
    2968             : 
    2969             : /**
    2970             :  * ieee802_11_mgmt_cb - Process management frame TX status callback
    2971             :  * @hapd: hostapd BSS data structure (the BSS from which the management frame
    2972             :  * was sent from)
    2973             :  * @buf: management frame data (starting from IEEE 802.11 header)
    2974             :  * @len: length of frame data in octets
    2975             :  * @stype: management frame subtype from frame control field
    2976             :  * @ok: Whether the frame was ACK'ed
    2977             :  */
    2978       12567 : void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
    2979             :                         u16 stype, int ok)
    2980             : {
    2981             :         const struct ieee80211_mgmt *mgmt;
    2982       12567 :         mgmt = (const struct ieee80211_mgmt *) buf;
    2983             : 
    2984             : #ifdef CONFIG_TESTING_OPTIONS
    2985       12567 :         if (hapd->ext_mgmt_frame_handling) {
    2986         359 :                 wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-TX-STATUS stype=%u ok=%d",
    2987             :                         stype, ok);
    2988       12926 :                 return;
    2989             :         }
    2990             : #endif /* CONFIG_TESTING_OPTIONS */
    2991             : 
    2992       12208 :         switch (stype) {
    2993             :         case WLAN_FC_STYPE_AUTH:
    2994        4863 :                 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
    2995        4863 :                 handle_auth_cb(hapd, mgmt, len, ok);
    2996        4863 :                 break;
    2997             :         case WLAN_FC_STYPE_ASSOC_RESP:
    2998        4467 :                 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
    2999        4467 :                 handle_assoc_cb(hapd, mgmt, len, 0, ok);
    3000        4467 :                 break;
    3001             :         case WLAN_FC_STYPE_REASSOC_RESP:
    3002         339 :                 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
    3003         339 :                 handle_assoc_cb(hapd, mgmt, len, 1, ok);
    3004         339 :                 break;
    3005             :         case WLAN_FC_STYPE_PROBE_RESP:
    3006         599 :                 wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
    3007         599 :                 break;
    3008             :         case WLAN_FC_STYPE_DEAUTH:
    3009         871 :                 wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
    3010         871 :                 handle_deauth_cb(hapd, mgmt, len, ok);
    3011         871 :                 break;
    3012             :         case WLAN_FC_STYPE_DISASSOC:
    3013          29 :                 wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
    3014          29 :                 handle_disassoc_cb(hapd, mgmt, len, ok);
    3015          29 :                 break;
    3016             :         case WLAN_FC_STYPE_ACTION:
    3017        1040 :                 wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
    3018        1040 :                 break;
    3019             :         default:
    3020           0 :                 wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
    3021           0 :                 break;
    3022             :         }
    3023             : }
    3024             : 
    3025             : 
    3026          13 : int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
    3027             : {
    3028             :         /* TODO */
    3029          13 :         return 0;
    3030             : }
    3031             : 
    3032             : 
    3033         221 : int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
    3034             :                            char *buf, size_t buflen)
    3035             : {
    3036             :         /* TODO */
    3037         221 :         return 0;
    3038             : }
    3039             : 
    3040             : 
    3041        2347 : void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
    3042             :                        const u8 *buf, size_t len, int ack)
    3043             : {
    3044             :         struct sta_info *sta;
    3045        2347 :         struct hostapd_iface *iface = hapd->iface;
    3046             : 
    3047        2347 :         sta = ap_get_sta(hapd, addr);
    3048        2347 :         if (sta == NULL && iface->num_bss > 1) {
    3049             :                 size_t j;
    3050           0 :                 for (j = 0; j < iface->num_bss; j++) {
    3051           0 :                         hapd = iface->bss[j];
    3052           0 :                         sta = ap_get_sta(hapd, addr);
    3053           0 :                         if (sta)
    3054           0 :                                 break;
    3055             :                 }
    3056             :         }
    3057        2347 :         if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
    3058        2602 :                 return;
    3059        2092 :         if (sta->flags & WLAN_STA_PENDING_POLL) {
    3060           0 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
    3061           0 :                            "activity poll", MAC2STR(sta->addr),
    3062             :                            ack ? "ACKed" : "did not ACK");
    3063           0 :                 if (ack)
    3064           0 :                         sta->flags &= ~WLAN_STA_PENDING_POLL;
    3065             :         }
    3066             : 
    3067        2092 :         ieee802_1x_tx_status(hapd, sta, buf, len, ack);
    3068             : }
    3069             : 
    3070             : 
    3071       16402 : void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
    3072             :                              const u8 *data, size_t len, int ack)
    3073             : {
    3074             :         struct sta_info *sta;
    3075       16402 :         struct hostapd_iface *iface = hapd->iface;
    3076             : 
    3077       16402 :         sta = ap_get_sta(hapd, dst);
    3078       16402 :         if (sta == NULL && iface->num_bss > 1) {
    3079             :                 size_t j;
    3080          61 :                 for (j = 0; j < iface->num_bss; j++) {
    3081          61 :                         hapd = iface->bss[j];
    3082          61 :                         sta = ap_get_sta(hapd, dst);
    3083          61 :                         if (sta)
    3084          29 :                                 break;
    3085             :                 }
    3086             :         }
    3087       16402 :         if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
    3088        3210 :                 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
    3089             :                            MACSTR " that is not currently associated",
    3090        3210 :                            MAC2STR(dst));
    3091       16937 :                 return;
    3092             :         }
    3093             : 
    3094       15867 :         ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
    3095             : }
    3096             : 
    3097             : 
    3098           2 : void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
    3099             : {
    3100             :         struct sta_info *sta;
    3101           2 :         struct hostapd_iface *iface = hapd->iface;
    3102             : 
    3103           2 :         sta = ap_get_sta(hapd, addr);
    3104           2 :         if (sta == NULL && iface->num_bss > 1) {
    3105             :                 size_t j;
    3106           0 :                 for (j = 0; j < iface->num_bss; j++) {
    3107           0 :                         hapd = iface->bss[j];
    3108           0 :                         sta = ap_get_sta(hapd, addr);
    3109           0 :                         if (sta)
    3110           0 :                                 break;
    3111             :                 }
    3112             :         }
    3113           2 :         if (sta == NULL)
    3114           0 :                 return;
    3115          12 :         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
    3116          12 :                 MAC2STR(sta->addr));
    3117           2 :         if (!(sta->flags & WLAN_STA_PENDING_POLL))
    3118           1 :                 return;
    3119             : 
    3120           6 :         wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
    3121           6 :                    "activity poll", MAC2STR(sta->addr));
    3122           1 :         sta->flags &= ~WLAN_STA_PENDING_POLL;
    3123             : }
    3124             : 
    3125             : 
    3126          10 : void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
    3127             :                                 int wds)
    3128             : {
    3129             :         struct sta_info *sta;
    3130             : 
    3131          10 :         sta = ap_get_sta(hapd, src);
    3132          10 :         if (sta && (sta->flags & WLAN_STA_ASSOC)) {
    3133           5 :                 if (!hapd->conf->wds_sta)
    3134           4 :                         return;
    3135             : 
    3136           1 :                 if (wds && !(sta->flags & WLAN_STA_WDS)) {
    3137             :                         int ret;
    3138             :                         char ifname_wds[IFNAMSIZ + 1];
    3139             : 
    3140           7 :                         wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
    3141             :                                    "STA " MACSTR " (aid %u)",
    3142           7 :                                    MAC2STR(sta->addr), sta->aid);
    3143           1 :                         sta->flags |= WLAN_STA_WDS;
    3144           2 :                         ret = hostapd_set_wds_sta(hapd, ifname_wds,
    3145           2 :                                                   sta->addr, sta->aid, 1);
    3146           1 :                         if (!ret)
    3147           1 :                                 hostapd_set_wds_encryption(hapd, sta,
    3148             :                                                            ifname_wds);
    3149             :                 }
    3150           1 :                 return;
    3151             :         }
    3152             : 
    3153          30 :         wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
    3154          30 :                    MACSTR, MAC2STR(src));
    3155           5 :         if (is_multicast_ether_addr(src)) {
    3156             :                 /* Broadcast bit set in SA?! Ignore the frame silently. */
    3157           0 :                 return;
    3158             :         }
    3159             : 
    3160           5 :         if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
    3161           0 :                 wpa_printf(MSG_DEBUG, "Association Response to the STA has "
    3162             :                            "already been sent, but no TX status yet known - "
    3163             :                            "ignore Class 3 frame issue with " MACSTR,
    3164           0 :                            MAC2STR(src));
    3165           0 :                 return;
    3166             :         }
    3167             : 
    3168           5 :         if (sta && (sta->flags & WLAN_STA_AUTH))
    3169           1 :                 hostapd_drv_sta_disassoc(
    3170             :                         hapd, src,
    3171             :                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
    3172             :         else
    3173           4 :                 hostapd_drv_sta_deauth(
    3174             :                         hapd, src,
    3175             :                         WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
    3176             : }
    3177             : 
    3178             : 
    3179             : #endif /* CONFIG_NATIVE_WINDOWS */

Generated by: LCOV version 1.10