Fix spelling mistakes in number of comments
[mech_eap.git] / src / ap / ieee802_11.c
index 781afa2..4e04169 100644 (file)
@@ -44,6 +44,7 @@
 #include "dfs.h"
 #include "mbo_ap.h"
 #include "rrm.h"
+#include "taxonomy.h"
 
 
 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
@@ -518,6 +519,9 @@ static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
        if (sae_check_big_sync(sta))
                return;
        sta->sae->sync++;
+       wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
+                  " (sync=%d state=%d)",
+                  MAC2STR(sta->addr), sta->sae->sync, sta->sae->state);
 
        switch (sta->sae->state) {
        case SAE_COMMITTED:
@@ -615,7 +619,7 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
                                 * message now to get alternating sequence of
                                 * Authentication frames between the AP and STA.
                                 * Confirm will be sent in
-                                * Commited -> Confirmed/Accepted transition
+                                * Committed -> Confirmed/Accepted transition
                                 * when receiving Confirm from STA.
                                 */
                        }
@@ -724,6 +728,44 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
 }
 
 
+static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
+{
+       struct sae_data *sae = sta->sae;
+       int i, *groups = hapd->conf->sae_groups;
+
+       if (sae->state != SAE_COMMITTED)
+               return;
+
+       wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
+
+       for (i = 0; groups && groups[i] > 0; i++) {
+               if (sae->group == groups[i])
+                       break;
+       }
+
+       if (!groups || groups[i] <= 0) {
+               wpa_printf(MSG_DEBUG,
+                          "SAE: Previously selected group not found from the current configuration");
+               return;
+       }
+
+       for (;;) {
+               i++;
+               if (groups[i] <= 0) {
+                       wpa_printf(MSG_DEBUG,
+                                  "SAE: No alternative group enabled");
+                       return;
+               }
+
+               if (sae_set_group(sae, groups[i]) < 0)
+                       continue;
+
+               break;
+       }
+       wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
+}
+
+
 static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
                            const struct ieee80211_mgmt *mgmt, size_t len,
                            u16 auth_transaction, u16 status_code)
@@ -811,6 +853,16 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
                        return;
                }
 
+               if ((hapd->conf->mesh & MESH_ENABLED) &&
+                   status_code ==
+                   WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
+                   sta->sae->tmp) {
+                       wpa_printf(MSG_DEBUG,
+                                  "SAE: Peer did not accept our SAE group");
+                       sae_pick_next_group(hapd, sta);
+                       goto remove_sta;
+               }
+
                if (status_code != WLAN_STATUS_SUCCESS)
                        goto remove_sta;
 
@@ -1226,7 +1278,7 @@ static void handle_auth(struct hostapd_data *hapd,
                sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
                                WLAN_STA_AUTHORIZED);
 
-               if (hostapd_sta_add(hapd, sta->addr, 0, 0, 0, 0, 0,
+               if (hostapd_sta_add(hapd, sta->addr, 0, 0, NULL, 0, 0,
                                    NULL, NULL, sta->flags, 0, 0, 0, 0)) {
                        hostapd_logger(hapd, sta->addr,
                                       HOSTAPD_MODULE_IEEE80211,
@@ -1334,6 +1386,9 @@ int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
                return 0;
        }
 
+       if (TEST_FAIL())
+               return -1;
+
        for (i = 0; i < AID_WORDS; i++) {
                if (hapd->sta_aid[i] == (u32) -1)
                        continue;
@@ -1890,7 +1945,23 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
 
 #ifdef CONFIG_IEEE80211AC
        if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-               p = hostapd_eid_vht_capabilities(hapd, p);
+               u32 nsts = 0, sta_nsts;
+
+               if (hapd->conf->use_sta_nsts && sta->vht_capabilities) {
+                       struct ieee80211_vht_capabilities *capa;
+
+                       nsts = (hapd->iface->conf->vht_capab >>
+                               VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+                       capa = sta->vht_capabilities;
+                       sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
+                                   VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
+
+                       if (nsts < sta_nsts)
+                               nsts = 0;
+                       else
+                               nsts = sta_nsts;
+               }
+               p = hostapd_eid_vht_capabilities(hapd, p, nsts);
                p = hostapd_eid_vht_operation(hapd, p);
        }
 #endif /* CONFIG_IEEE80211AC */
@@ -2196,6 +2267,10 @@ static void handle_assoc(struct hostapd_data *hapd,
         * remove the STA immediately. */
        sta->timeout_next = STA_NULLFUNC;
 
+#ifdef CONFIG_TAXONOMY
+       taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
+#endif /* CONFIG_TAXONOMY */
+
  fail:
        /*
         * In case of a successful response, add the station to the driver.
@@ -2503,8 +2578,9 @@ static int handle_action(struct hostapd_data *hapd,
                       "handle_action - unknown action category %d or invalid "
                       "frame",
                       mgmt->u.action.category);
-       if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
-           !(mgmt->sa[0] & 0x01)) {
+       if (!is_multicast_ether_addr(mgmt->da) &&
+           !(mgmt->u.action.category & 0x80) &&
+           !is_multicast_ether_addr(mgmt->sa)) {
                struct ieee80211_mgmt *resp;
 
                /*
@@ -2551,7 +2627,6 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
                    struct hostapd_frame_info *fi)
 {
        struct ieee80211_mgmt *mgmt;
-       int broadcast;
        u16 fc, stype;
        int ret = 0;
 
@@ -2567,11 +2642,7 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
                return 1;
        }
 
-       broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
-               mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
-               mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
-
-       if (!broadcast &&
+       if (!is_broadcast_ether_addr(mgmt->bssid) &&
 #ifdef CONFIG_P2P
            /* Invitation responses can be sent with the peer MAC as BSSID */
            !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
@@ -2852,7 +2923,7 @@ static void handle_deauth_cb(struct hostapd_data *hapd,
                             size_t len, int ok)
 {
        struct sta_info *sta;
-       if (mgmt->da[0] & 0x01)
+       if (is_multicast_ether_addr(mgmt->da))
                return;
        sta = ap_get_sta(hapd, mgmt->da);
        if (!sta) {
@@ -2876,7 +2947,7 @@ static void handle_disassoc_cb(struct hostapd_data *hapd,
                               size_t len, int ok)
 {
        struct sta_info *sta;
-       if (mgmt->da[0] & 0x01)
+       if (is_multicast_ether_addr(mgmt->da))
                return;
        sta = ap_get_sta(hapd, mgmt->da);
        if (!sta) {
@@ -3081,7 +3152,7 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
 
        wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
                   MACSTR, MAC2STR(src));
-       if (src[0] & 0x01) {
+       if (is_multicast_ether_addr(src)) {
                /* Broadcast bit set in SA?! Ignore the frame silently. */
                return;
        }