WPS 2.0: Provide (Re)Association Response WPS IE to driver

WPS 2.0 mandates the AP to include WPS IE in (Re)Association Response
if the matching (Re)Association Request included WPS IE. Provide the
needed WPS IE information to the driver_ops API for drivers that
process association frames internally.

Note: This modifies the driver_ops API by adding a new argument to
set_ap_wps_ie().
This commit is contained in:
Jouni Malinen 2010-09-22 10:46:44 -07:00 committed by Jouni Malinen
parent baf7081ccd
commit 0e2e565a44
8 changed files with 33 additions and 11 deletions

View file

@ -17,6 +17,7 @@
#include "utils/common.h" #include "utils/common.h"
#include "drivers/driver.h" #include "drivers/driver.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "wps/wps.h"
#include "hostapd.h" #include "hostapd.h"
#include "ieee802_11.h" #include "ieee802_11.h"
#include "sta_info.h" #include "sta_info.h"
@ -41,7 +42,7 @@ static int hostapd_sta_flags_to_drv(int flags)
static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd) static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
{ {
struct wpabuf *beacon, *proberesp; struct wpabuf *beacon, *proberesp, *assocresp = NULL;
int ret; int ret;
if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL) if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
@ -85,12 +86,19 @@ static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp); #ifdef CONFIG_WPS2
if (hapd->conf->wps_state)
assocresp = wps_build_assoc_resp_ie();
#endif /* CONFIG_WPS2 */
ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
assocresp);
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
wpabuf_free(beacon); wpabuf_free(beacon);
wpabuf_free(proberesp); wpabuf_free(proberesp);
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
wpabuf_free(assocresp);
return ret; return ret;
} }

View file

@ -1658,12 +1658,17 @@ struct wpa_driver_ops {
* @beacon: WPS IE(s) for Beacon frames or %NULL to remove extra IE(s) * @beacon: WPS IE(s) for Beacon frames or %NULL to remove extra IE(s)
* @proberesp: WPS IE(s) for Probe Response frames or %NULL to remove * @proberesp: WPS IE(s) for Probe Response frames or %NULL to remove
* extra IE(s) * extra IE(s)
* @assocresp: WPS IE(s) for (Re)Association Response frames or %NULL
* to remove extra IE(s)
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
* *
* This is an optional function to add WPS IE in the kernel driver for * This is an optional function to add WPS IE in the kernel driver for
* Beacon and Probe Response frames. This can be left undefined (set * Beacon and Probe Response frames. This can be left undefined (set
* to %NULL) if the driver uses the Beacon template from set_beacon() * to %NULL) if the driver uses the Beacon template from set_beacon()
* and does not process Probe Request frames. * and does not process Probe Request frames. If the driver takes care
* of (Re)Association frame processing, the assocresp buffer includes
* WPS IE(s) that need to be added to (Re)Association Response frames
* whenever a (Re)Association Request frame indicated use of WPS.
* *
* This will also be used to add P2P IE(s) into Beacon/Probe Response * This will also be used to add P2P IE(s) into Beacon/Probe Response
* frames when operating as a GO. The driver is responsible for adding * frames when operating as a GO. The driver is responsible for adding
@ -1674,7 +1679,8 @@ struct wpa_driver_ops {
* internally. * internally.
*/ */
int (*set_ap_wps_ie)(void *priv, const struct wpabuf *beacon, int (*set_ap_wps_ie)(void *priv, const struct wpabuf *beacon,
const struct wpabuf *proberesp); const struct wpabuf *proberesp,
const struct wpabuf *assocresp);
/** /**
* set_supp_port - Set IEEE 802.1X Supplicant Port status * set_supp_port - Set IEEE 802.1X Supplicant Port status

View file

@ -754,8 +754,12 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
static int static int
madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
const struct wpabuf *proberesp) const struct wpabuf *proberesp,
const struct wpabuf *assocresp)
{ {
madwifi_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL,
assocresp ? wpabuf_len(assocresp) : 0,
IEEE80211_APPIE_FRAME_ASSOC_RESP);
if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
beacon ? wpabuf_len(beacon) : 0, beacon ? wpabuf_len(beacon) : 0,
IEEE80211_APPIE_FRAME_BEACON)) IEEE80211_APPIE_FRAME_BEACON))

View file

@ -763,7 +763,8 @@ static int hostap_set_generic_elem(void *priv,
static int hostap_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, static int hostap_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
const struct wpabuf *proberesp) const struct wpabuf *proberesp,
const struct wpabuf *assocresp)
{ {
struct hostap_driver_data *drv = priv; struct hostap_driver_data *drv = priv;

View file

@ -787,7 +787,8 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
static int static int
madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
const struct wpabuf *proberesp) const struct wpabuf *proberesp,
const struct wpabuf *assocresp)
{ {
if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
beacon ? wpabuf_len(beacon) : 0, beacon ? wpabuf_len(beacon) : 0,

View file

@ -841,7 +841,8 @@ static int test_driver_set_generic_elem(void *priv,
static int test_driver_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, static int test_driver_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
const struct wpabuf *proberesp) const struct wpabuf *proberesp,
const struct wpabuf *assocresp)
{ {
struct test_driver_bss *bss = priv; struct test_driver_bss *bss = priv;

View file

@ -499,12 +499,13 @@ static inline int wpa_drv_signal_monitor(struct wpa_supplicant *wpa_s,
static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s, static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
const struct wpabuf *beacon, const struct wpabuf *beacon,
const struct wpabuf *proberesp) const struct wpabuf *proberesp,
const struct wpabuf *assocresp)
{ {
if (!wpa_s->driver->set_ap_wps_ie) if (!wpa_s->driver->set_ap_wps_ie)
return -1; return -1;
return wpa_s->driver->set_ap_wps_ie(wpa_s->drv_priv, beacon, return wpa_s->driver->set_ap_wps_ie(wpa_s->drv_priv, beacon,
proberesp); proberesp, assocresp);
} }
static inline int wpa_drv_shared_freq(struct wpa_supplicant *wpa_s) static inline int wpa_drv_shared_freq(struct wpa_supplicant *wpa_s)

View file

@ -1021,7 +1021,7 @@ static int wpas_start_listen(void *ctx, unsigned int freq,
{ {
struct wpa_supplicant *wpa_s = ctx; struct wpa_supplicant *wpa_s = ctx;
wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie); wpa_drv_set_ap_wps_ie(wpa_s, NULL, probe_resp_ie, NULL);
if (wpa_drv_probe_req_report(wpa_s, 1) < 0) { if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to " wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "