hostapd: Use stations nsts capability in (Re)Association Response frame
[mech_eap.git] / src / ap / ieee802_11.c
index f6fca67..2ecd78f 100644 (file)
@@ -1277,7 +1277,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,
@@ -1385,6 +1385,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;
@@ -1941,7 +1944,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 */
@@ -2554,8 +2573,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;
 
                /*
@@ -2602,7 +2622,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;
 
@@ -2618,11 +2637,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) &&
@@ -2903,7 +2918,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) {
@@ -2927,7 +2942,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) {
@@ -3132,7 +3147,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;
        }