WPS 2.0: Provide (Re)Association Response WPS IE to driver
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 22 Sep 2010 17:46:44 +0000 (10:46 -0700)
committerJouni Malinen <j@w1.fi>
Wed, 22 Sep 2010 17:46:44 +0000 (10:46 -0700)
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
src/drivers/driver.h
src/drivers/driver_atheros.c
src/drivers/driver_hostap.c
src/drivers/driver_madwifi.c
src/drivers/driver_test.c
wpa_supplicant/driver_i.h
wpa_supplicant/p2p_supplicant.c

index 17c024c..5aed879 100644 (file)
@@ -17,6 +17,7 @@
 #include "utils/common.h"
 #include "drivers/driver.h"
 #include "common/ieee802_11_defs.h"
 #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"
 #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)
 {
 
 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)
        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 */
 
        }
 #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 */
 
 #ifdef CONFIG_P2P
        wpabuf_free(beacon);
        wpabuf_free(proberesp);
 #endif /* CONFIG_P2P */
+       wpabuf_free(assocresp);
 
        return ret;
 }
 
        return ret;
 }
index 6274639..96dec77 100644 (file)
@@ -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)
         * @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()
         * 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
         *
         * 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,
         * 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
 
        /**
         * set_supp_port - Set IEEE 802.1X Supplicant Port status
index f246a12..c0dd731 100644 (file)
@@ -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,
 
 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))
        if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
                               beacon ? wpabuf_len(beacon) : 0,
                               IEEE80211_APPIE_FRAME_BEACON))
index 952f389..e47983c 100644 (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;
 
index 8687404..834d65d 100644 (file)
@@ -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,
 
 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,
 {
        if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
                               beacon ? wpabuf_len(beacon) : 0,
index 8374e11..c630e4c 100644 (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;
 
index b5c9fc8..af8232a 100644 (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,
                                        const struct wpabuf *beacon,
 
 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,
 {
        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)
 }
 
 static inline int wpa_drv_shared_freq(struct wpa_supplicant *wpa_s)
index 056d6f1..da90c28 100644 (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) {
                wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "
 
        if (wpa_drv_probe_req_report(wpa_s, 1) < 0) {
                wpa_printf(MSG_DEBUG, "P2P: Failed to request the driver to "