From 0e2e565a44ab7b073491cab00847f7bc62731483 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 22 Sep 2010 10:46:44 -0700 Subject: [PATCH] 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(). --- src/ap/ap_drv_ops.c | 12 ++++++++++-- src/drivers/driver.h | 10 ++++++++-- src/drivers/driver_atheros.c | 6 +++++- src/drivers/driver_hostap.c | 3 ++- src/drivers/driver_madwifi.c | 3 ++- src/drivers/driver_test.c | 3 ++- wpa_supplicant/driver_i.h | 5 +++-- wpa_supplicant/p2p_supplicant.c | 2 +- 8 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 17c024ce0..5aed879ce 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -17,6 +17,7 @@ #include "utils/common.h" #include "drivers/driver.h" #include "common/ieee802_11_defs.h" +#include "wps/wps.h" #include "hostapd.h" #include "ieee802_11.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) { - struct wpabuf *beacon, *proberesp; + struct wpabuf *beacon, *proberesp, *assocresp = NULL; int ret; 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 */ - 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 wpabuf_free(beacon); wpabuf_free(proberesp); #endif /* CONFIG_P2P */ + wpabuf_free(assocresp); return ret; } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 6274639b8..96dec770e 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1658,12 +1658,17 @@ struct wpa_driver_ops { * @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 * 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 * * 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 * 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 * frames when operating as a GO. The driver is responsible for adding @@ -1674,7 +1679,8 @@ struct wpa_driver_ops { * internally. */ 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 diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index f246a12d4..c0dd731d7 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -754,8 +754,12 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) static int 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, beacon ? wpabuf_len(beacon) : 0, IEEE80211_APPIE_FRAME_BEACON)) diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index 952f3891a..e47983cb7 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -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, - const struct wpabuf *proberesp) + const struct wpabuf *proberesp, + const struct wpabuf *assocresp) { struct hostap_driver_data *drv = priv; diff --git a/src/drivers/driver_madwifi.c b/src/drivers/driver_madwifi.c index 8687404db..834d65dd3 100644 --- a/src/drivers/driver_madwifi.c +++ b/src/drivers/driver_madwifi.c @@ -787,7 +787,8 @@ madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) static int 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, beacon ? wpabuf_len(beacon) : 0, diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index 8374e1111..c630e4c2c 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -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, - const struct wpabuf *proberesp) + const struct wpabuf *proberesp, + const struct wpabuf *assocresp) { struct test_driver_bss *bss = priv; diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h index b5c9fc853..af8232a76 100644 --- a/wpa_supplicant/driver_i.h +++ b/wpa_supplicant/driver_i.h @@ -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, const struct wpabuf *beacon, - const struct wpabuf *proberesp) + const struct wpabuf *proberesp, + const struct wpabuf *assocresp) { if (!wpa_s->driver->set_ap_wps_ie) return -1; 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) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 056d6f163..da90c28e0 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1021,7 +1021,7 @@ static int wpas_start_listen(void *ctx, unsigned int freq, { 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) { wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "