Split Probe Response generation into a separate function
authorArik Nemtsov <arik@wizery.com>
Sat, 10 Dec 2011 18:52:16 +0000 (20:52 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 10 Dec 2011 19:11:32 +0000 (21:11 +0200)
This is needed for Probe Response template, so move the code into a
separate function that can be shared.

Signed-hostap: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
src/ap/beacon.c

index 710436f..44f99ff 100644 (file)
@@ -186,18 +186,121 @@ static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
 }
 
 
+static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
+                                  struct sta_info *sta,
+                                  const struct ieee80211_mgmt *req,
+                                  int is_p2p, size_t *resp_len)
+{
+       struct ieee80211_mgmt *resp;
+       u8 *pos, *epos;
+       size_t buflen;
+
+#define MAX_PROBERESP_LEN 768
+       buflen = MAX_PROBERESP_LEN;
+#ifdef CONFIG_WPS
+       if (hapd->wps_probe_resp_ie)
+               buflen += wpabuf_len(hapd->wps_probe_resp_ie);
+#endif /* CONFIG_WPS */
+#ifdef CONFIG_P2P
+       if (hapd->p2p_probe_resp_ie)
+               buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
+#endif /* CONFIG_P2P */
+       resp = os_zalloc(buflen);
+       if (resp == NULL)
+               return NULL;
+
+       epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
+
+       resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+                                          WLAN_FC_STYPE_PROBE_RESP);
+       if (req)
+               os_memcpy(resp->da, req->sa, ETH_ALEN);
+       os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
+
+       os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
+       resp->u.probe_resp.beacon_int =
+               host_to_le16(hapd->iconf->beacon_int);
+
+       /* hardware or low-level driver will setup seq_ctrl and timestamp */
+       resp->u.probe_resp.capab_info =
+               host_to_le16(hostapd_own_capab_info(hapd, sta, 1));
+
+       pos = resp->u.probe_resp.variable;
+       *pos++ = WLAN_EID_SSID;
+       *pos++ = hapd->conf->ssid.ssid_len;
+       os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
+       pos += hapd->conf->ssid.ssid_len;
+
+       /* Supported rates */
+       pos = hostapd_eid_supp_rates(hapd, pos);
+
+       /* DS Params */
+       pos = hostapd_eid_ds_params(hapd, pos);
+
+       pos = hostapd_eid_country(hapd, pos, epos - pos);
+
+       /* ERP Information element */
+       pos = hostapd_eid_erp_info(hapd, pos);
+
+       /* Extended supported rates */
+       pos = hostapd_eid_ext_supp_rates(hapd, pos);
+
+       /* RSN, MDIE, WPA */
+       pos = hostapd_eid_wpa(hapd, pos, epos - pos);
+
+#ifdef CONFIG_IEEE80211N
+       pos = hostapd_eid_ht_capabilities(hapd, pos);
+       pos = hostapd_eid_ht_operation(hapd, pos);
+#endif /* CONFIG_IEEE80211N */
+
+       pos = hostapd_eid_ext_capab(hapd, pos);
+
+       pos = hostapd_eid_time_adv(hapd, pos);
+       pos = hostapd_eid_time_zone(hapd, pos);
+
+       pos = hostapd_eid_interworking(hapd, pos);
+       pos = hostapd_eid_adv_proto(hapd, pos);
+       pos = hostapd_eid_roaming_consortium(hapd, pos);
+
+       /* Wi-Fi Alliance WMM */
+       pos = hostapd_eid_wmm(hapd, pos);
+
+#ifdef CONFIG_WPS
+       if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
+               os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
+                         wpabuf_len(hapd->wps_probe_resp_ie));
+               pos += wpabuf_len(hapd->wps_probe_resp_ie);
+       }
+#endif /* CONFIG_WPS */
+
+#ifdef CONFIG_P2P
+       if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p &&
+           hapd->p2p_probe_resp_ie) {
+               os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
+                         wpabuf_len(hapd->p2p_probe_resp_ie));
+               pos += wpabuf_len(hapd->p2p_probe_resp_ie);
+       }
+#endif /* CONFIG_P2P */
+#ifdef CONFIG_P2P_MANAGER
+       if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
+           P2P_MANAGE)
+               pos = hostapd_eid_p2p_manage(hapd, pos);
+#endif /* CONFIG_P2P_MANAGER */
+
+       *resp_len = pos - (u8 *) resp;
+       return (u8 *) resp;
+}
+
+
 void handle_probe_req(struct hostapd_data *hapd,
                      const struct ieee80211_mgmt *mgmt, size_t len)
 {
-       struct ieee80211_mgmt *resp;
+       u8 *resp;
        struct ieee802_11_elems elems;
-       char *ssid;
-       u8 *pos, *epos;
        const u8 *ie;
-       size_t ssid_len, ie_len;
+       size_t ie_len;
        struct sta_info *sta = NULL;
-       size_t buflen;
-       size_t i;
+       size_t i, resp_len;
        int noack;
 
        ie = mgmt->u.probe_req.variable;
@@ -220,9 +323,6 @@ void handle_probe_req(struct hostapd_data *hapd,
                return;
        }
 
-       ssid = NULL;
-       ssid_len = 0;
-
        if ((!elems.ssid || !elems.supp_rates)) {
                wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
                           "without SSID or supported rates element",
@@ -267,13 +367,9 @@ void handle_probe_req(struct hostapd_data *hapd,
            (elems.ssid_len == hapd->conf->ssid.ssid_len &&
             os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
             0)) {
-               ssid = hapd->conf->ssid.ssid;
-               ssid_len = hapd->conf->ssid.ssid_len;
                if (sta)
                        sta->ssid_probe = &hapd->conf->ssid;
-       }
-
-       if (!ssid) {
+       } else {
                if (!(mgmt->da[0] & 0x01)) {
                        char ssid_txt[33];
                        ieee802_11_print_ssid(ssid_txt, elems.ssid,
@@ -318,95 +414,11 @@ void handle_probe_req(struct hostapd_data *hapd,
 
        /* TODO: verify that supp_rates contains at least one matching rate
         * with AP configuration */
-#define MAX_PROBERESP_LEN 768
-       buflen = MAX_PROBERESP_LEN;
-#ifdef CONFIG_WPS
-       if (hapd->wps_probe_resp_ie)
-               buflen += wpabuf_len(hapd->wps_probe_resp_ie);
-#endif /* CONFIG_WPS */
-#ifdef CONFIG_P2P
-       if (hapd->p2p_probe_resp_ie)
-               buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
-#endif /* CONFIG_P2P */
-       resp = os_zalloc(buflen);
+
+       resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL,
+                                     &resp_len);
        if (resp == NULL)
                return;
-       epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
-
-       resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
-                                          WLAN_FC_STYPE_PROBE_RESP);
-       os_memcpy(resp->da, mgmt->sa, ETH_ALEN);
-       os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
-
-       os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
-       resp->u.probe_resp.beacon_int =
-               host_to_le16(hapd->iconf->beacon_int);
-
-       /* hardware or low-level driver will setup seq_ctrl and timestamp */
-       resp->u.probe_resp.capab_info =
-               host_to_le16(hostapd_own_capab_info(hapd, sta, 1));
-
-       pos = resp->u.probe_resp.variable;
-       *pos++ = WLAN_EID_SSID;
-       *pos++ = ssid_len;
-       os_memcpy(pos, ssid, ssid_len);
-       pos += ssid_len;
-
-       /* Supported rates */
-       pos = hostapd_eid_supp_rates(hapd, pos);
-
-       /* DS Params */
-       pos = hostapd_eid_ds_params(hapd, pos);
-
-       pos = hostapd_eid_country(hapd, pos, epos - pos);
-
-       /* ERP Information element */
-       pos = hostapd_eid_erp_info(hapd, pos);
-
-       /* Extended supported rates */
-       pos = hostapd_eid_ext_supp_rates(hapd, pos);
-
-       /* RSN, MDIE, WPA */
-       pos = hostapd_eid_wpa(hapd, pos, epos - pos);
-
-#ifdef CONFIG_IEEE80211N
-       pos = hostapd_eid_ht_capabilities(hapd, pos);
-       pos = hostapd_eid_ht_operation(hapd, pos);
-#endif /* CONFIG_IEEE80211N */
-
-       pos = hostapd_eid_ext_capab(hapd, pos);
-
-       pos = hostapd_eid_time_adv(hapd, pos);
-       pos = hostapd_eid_time_zone(hapd, pos);
-
-       pos = hostapd_eid_interworking(hapd, pos);
-       pos = hostapd_eid_adv_proto(hapd, pos);
-       pos = hostapd_eid_roaming_consortium(hapd, pos);
-
-       /* Wi-Fi Alliance WMM */
-       pos = hostapd_eid_wmm(hapd, pos);
-
-#ifdef CONFIG_WPS
-       if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
-               os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
-                         wpabuf_len(hapd->wps_probe_resp_ie));
-               pos += wpabuf_len(hapd->wps_probe_resp_ie);
-       }
-#endif /* CONFIG_WPS */
-
-#ifdef CONFIG_P2P
-       if ((hapd->conf->p2p & P2P_ENABLED) && elems.p2p &&
-           hapd->p2p_probe_resp_ie) {
-               os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
-                         wpabuf_len(hapd->p2p_probe_resp_ie));
-               pos += wpabuf_len(hapd->p2p_probe_resp_ie);
-       }
-#endif /* CONFIG_P2P */
-#ifdef CONFIG_P2P_MANAGER
-       if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
-           P2P_MANAGE)
-               pos = hostapd_eid_p2p_manage(hapd, pos);
-#endif /* CONFIG_P2P_MANAGER */
 
        /*
         * If this is a broadcast probe request, apply no ack policy to avoid
@@ -414,7 +426,7 @@ void handle_probe_req(struct hostapd_data *hapd,
         */
        noack = !!(elems.ssid_len == 0 && is_broadcast_ether_addr(mgmt->da));
 
-       if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp, noack) < 0)
+       if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0)
                perror("handle_probe_req: send");
 
        os_free(resp);