Provide extra IEs for AP mode management frames with set_ap

Drivers that build Beacon, Probe Response, and (Re)Association
Response frames can use this information to and WPS and P2P IE
when needed.
This commit is contained in:
Jouni Malinen 2011-08-26 21:14:25 +03:00 committed by Jouni Malinen
parent 97a7a0b504
commit fb91db5639
5 changed files with 114 additions and 43 deletions

View file

@ -41,49 +41,47 @@ u32 hostapd_sta_flags_to_drv(u32 flags)
}
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
struct wpabuf **beacon,
struct wpabuf **proberesp,
struct wpabuf **assocresp)
{
struct wpabuf *beacon, *proberesp, *assocresp = NULL;
int ret;
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
return 0;
beacon = hapd->wps_beacon_ie;
proberesp = hapd->wps_probe_resp_ie;
*beacon = hapd->wps_beacon_ie;
*proberesp = hapd->wps_probe_resp_ie;
*assocresp = NULL;
#ifdef CONFIG_P2P
if (hapd->wps_beacon_ie == NULL && hapd->p2p_beacon_ie == NULL)
beacon = NULL;
*beacon = NULL;
else {
beacon = wpabuf_alloc((hapd->wps_beacon_ie ?
wpabuf_len(hapd->wps_beacon_ie) : 0) +
(hapd->p2p_beacon_ie ?
wpabuf_len(hapd->p2p_beacon_ie) : 0));
if (beacon == NULL)
*beacon = wpabuf_alloc((hapd->wps_beacon_ie ?
wpabuf_len(hapd->wps_beacon_ie) : 0) +
(hapd->p2p_beacon_ie ?
wpabuf_len(hapd->p2p_beacon_ie) : 0));
if (*beacon == NULL)
return -1;
if (hapd->wps_beacon_ie)
wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
wpabuf_put_buf(*beacon, hapd->wps_beacon_ie);
if (hapd->p2p_beacon_ie)
wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
wpabuf_put_buf(*beacon, hapd->p2p_beacon_ie);
}
if (hapd->wps_probe_resp_ie == NULL && hapd->p2p_probe_resp_ie == NULL)
proberesp = NULL;
*proberesp = NULL;
else {
proberesp = wpabuf_alloc(
*proberesp = wpabuf_alloc(
(hapd->wps_probe_resp_ie ?
wpabuf_len(hapd->wps_probe_resp_ie) : 0) +
(hapd->p2p_probe_resp_ie ?
wpabuf_len(hapd->p2p_probe_resp_ie) : 0));
if (proberesp == NULL) {
wpabuf_free(beacon);
if (*proberesp == NULL) {
wpabuf_free(*beacon);
return -1;
}
if (hapd->wps_probe_resp_ie)
wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
wpabuf_put_buf(*proberesp, hapd->wps_probe_resp_ie);
if (hapd->p2p_probe_resp_ie)
wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
wpabuf_put_buf(*proberesp, hapd->p2p_probe_resp_ie);
}
#endif /* CONFIG_P2P */
@ -91,67 +89,91 @@ int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
if (hapd->conf->p2p & P2P_MANAGE) {
struct wpabuf *a;
a = wpabuf_alloc(100 + (beacon ? wpabuf_len(beacon) : 0));
a = wpabuf_alloc(100 + (*beacon ? wpabuf_len(*beacon) : 0));
if (a) {
u8 *start, *p;
if (beacon)
wpabuf_put_buf(a, beacon);
if (beacon != hapd->wps_beacon_ie)
wpabuf_free(beacon);
if (*beacon)
wpabuf_put_buf(a, *beacon);
if (*beacon != hapd->wps_beacon_ie)
wpabuf_free(*beacon);
start = wpabuf_put(a, 0);
p = hostapd_eid_p2p_manage(hapd, start);
wpabuf_put(a, p - start);
beacon = a;
*beacon = a;
}
a = wpabuf_alloc(100 + (proberesp ? wpabuf_len(proberesp) :
a = wpabuf_alloc(100 + (*proberesp ? wpabuf_len(*proberesp) :
0));
if (a) {
u8 *start, *p;
if (proberesp)
wpabuf_put_buf(a, proberesp);
if (proberesp != hapd->wps_probe_resp_ie)
wpabuf_free(proberesp);
if (*proberesp)
wpabuf_put_buf(a, *proberesp);
if (*proberesp != hapd->wps_probe_resp_ie)
wpabuf_free(*proberesp);
start = wpabuf_put(a, 0);
p = hostapd_eid_p2p_manage(hapd, start);
wpabuf_put(a, p - start);
proberesp = a;
*proberesp = a;
}
}
#endif /* CONFIG_P2P_MANAGER */
#ifdef CONFIG_WPS2
if (hapd->conf->wps_state)
assocresp = wps_build_assoc_resp_ie();
*assocresp = wps_build_assoc_resp_ie();
#endif /* CONFIG_WPS2 */
#ifdef CONFIG_P2P_MANAGER
if (hapd->conf->p2p & P2P_MANAGE) {
struct wpabuf *a;
a = wpabuf_alloc(100 + (assocresp ? wpabuf_len(assocresp) :
a = wpabuf_alloc(100 + (*assocresp ? wpabuf_len(*assocresp) :
0));
if (a) {
u8 *start, *p;
start = wpabuf_put(a, 0);
p = hostapd_eid_p2p_manage(hapd, start);
wpabuf_put(a, p - start);
if (assocresp) {
wpabuf_put_buf(a, assocresp);
wpabuf_free(assocresp);
if (*assocresp) {
wpabuf_put_buf(a, *assocresp);
wpabuf_free(*assocresp);
}
assocresp = a;
*assocresp = a;
}
}
#endif /* CONFIG_P2P_MANAGER */
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
assocresp);
return 0;
}
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon,
struct wpabuf *proberesp,
struct wpabuf *assocresp)
{
if (beacon != hapd->wps_beacon_ie)
wpabuf_free(beacon);
if (proberesp != hapd->wps_probe_resp_ie)
wpabuf_free(proberesp);
wpabuf_free(assocresp);
}
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
{
struct wpabuf *beacon, *proberesp, *assocresp;
int ret;
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
return 0;
if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
0)
return -1;
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
assocresp);
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
return ret;
}

View file

@ -21,6 +21,13 @@ struct wpa_driver_scan_params;
struct ieee80211_ht_capabilities;
u32 hostapd_sta_flags_to_drv(u32 flags);
int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
struct wpabuf **beacon,
struct wpabuf **proberesp,
struct wpabuf **assocresp);
void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon,
struct wpabuf *proberesp,
struct wpabuf *assocresp);
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
int hostapd_set_authorized(struct hostapd_data *hapd,
struct sta_info *sta, int authorized);

View file

@ -399,6 +399,7 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
u16 capab_info;
size_t head_len, tail_len;
struct wpa_driver_ap_params params;
struct wpabuf *beacon, *proberesp, *assocresp;
#ifdef CONFIG_P2P
if ((hapd->conf->p2p & (P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_ENABLED)
@ -541,8 +542,13 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
params.hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
break;
}
hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp);
params.beacon_ies = beacon;
params.proberesp_ies = proberesp;
params.assocresp_ies = assocresp;
if (hostapd_drv_set_ap(hapd, &params))
wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
os_free(tail);
os_free(head);