taxonomy: Store Probe Request frames in hostapd_sta_info
[mech_eap.git] / src / ap / beacon.c
index 0720e14..233320d 100644 (file)
@@ -29,6 +29,7 @@
 #include "beacon.h"
 #include "hs20.h"
 #include "dfs.h"
+#include "taxonomy.h"
 
 
 #ifdef NEED_AP_MLME
 static u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
                                         size_t len)
 {
-       if (!hapd->conf->radio_measurements || len < 2 + 4)
+       size_t i;
+
+       for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
+               if (hapd->conf->radio_measurements[i])
+                       break;
+       }
+
+       if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
                return eid;
 
        *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
-       *eid++ = 5;
-       *eid++ = (hapd->conf->radio_measurements & BIT(0)) ?
-               WLAN_RRM_CAPS_NEIGHBOR_REPORT : 0x00;
-       *eid++ = 0x00;
-       *eid++ = 0x00;
-       *eid++ = 0x00;
-       *eid++ = 0x00;
-       return eid;
+       *eid++ = RRM_CAPABILITIES_IE_LEN;
+       os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
+
+       return eid + RRM_CAPABILITIES_IE_LEN;
 }
 
 
@@ -482,7 +486,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211AC
        if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-               pos = hostapd_eid_vht_capabilities(hapd, pos);
+               pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
                pos = hostapd_eid_vht_operation(hapd, pos);
                pos = hostapd_eid_txpower_envelope(hapd, pos);
                pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
@@ -596,7 +600,7 @@ void sta_track_expire(struct hostapd_iface *iface, int force)
                           MAC2STR(info->addr));
                dl_list_del(&info->list);
                iface->num_sta_seen--;
-               os_free(info);
+               sta_track_del(info);
        }
 }
 
@@ -629,6 +633,8 @@ void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
 
        /* Add a new entry */
        info = os_zalloc(sizeof(*info));
+       if (info == NULL)
+               return;
        os_memcpy(info->addr, addr, ETH_ALEN);
        os_get_reltime(&info->last_seen);
 
@@ -670,6 +676,23 @@ sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
 }
 
 
+#ifdef CONFIG_TAXONOMY
+void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
+                                  struct wpabuf **probe_ie_taxonomy)
+{
+       struct hostapd_sta_info *info;
+
+       info = sta_track_get(iface, addr);
+       if (!info)
+               return;
+
+       wpabuf_free(*probe_ie_taxonomy);
+       *probe_ie_taxonomy = info->probe_ie_taxonomy;
+       info->probe_ie_taxonomy = NULL;
+}
+#endif /* CONFIG_TAXONOMY */
+
+
 void handle_probe_req(struct hostapd_data *hapd,
                      const struct ieee80211_mgmt *mgmt, size_t len,
                      int ssi_signal)
@@ -685,12 +708,12 @@ void handle_probe_req(struct hostapd_data *hapd,
        u16 csa_offs[2];
        size_t csa_offs_len;
 
-       ie = mgmt->u.probe_req.variable;
-       if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
+       if (len < IEEE80211_HDRLEN)
                return;
+       ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
        if (hapd->iconf->track_sta_max_num)
                sta_track_add(hapd->iface, mgmt->sa);
-       ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
+       ie_len = len - IEEE80211_HDRLEN;
 
        for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
                if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
@@ -779,6 +802,21 @@ void handle_probe_req(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_TAXONOMY
+       {
+               struct sta_info *sta;
+               struct hostapd_sta_info *info;
+
+               if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
+                       taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
+               } else if ((info = sta_track_get(hapd->iface,
+                                                mgmt->sa)) != NULL) {
+                       taxonomy_hostapd_sta_info_probe_req(hapd, info,
+                                                           ie, ie_len);
+               }
+       }
+#endif /* CONFIG_TAXONOMY */
+
        res = ssid_match(hapd, elems.ssid, elems.ssid_len,
                         elems.ssid_list, elems.ssid_list_len);
        if (res == NO_SSID_MATCH) {
@@ -947,6 +985,16 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
 #endif /* NEED_AP_MLME */
 
 
+void sta_track_del(struct hostapd_sta_info *info)
+{
+#ifdef CONFIG_TAXONOMY
+       wpabuf_free(info->probe_ie_taxonomy);
+       info->probe_ie_taxonomy = NULL;
+#endif /* CONFIG_TAXONOMY */
+       os_free(info);
+}
+
+
 int ieee802_11_build_ap_params(struct hostapd_data *hapd,
                               struct wpa_driver_ap_params *params)
 {
@@ -1102,7 +1150,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211AC
        if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
-               tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
+               tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
                tailpos = hostapd_eid_vht_operation(hapd, tailpos);
                tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
                tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);