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 1443382998 Lines: 1138 1466 77.6 %
Date: 2015-09-27 Functions: 47 49 95.9 %

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

Generated by: LCOV version 1.10