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 "