#include "common/wpa_ctrl.h"
#include "radius/radius.h"
#include "radius/radius_client.h"
+#include "wps/wps.h"
#include "hostapd.h"
#include "beacon.h"
#include "ieee802_11_auth.h"
if (sta->flags & WLAN_STA_WMM)
p = hostapd_eid_wmm(hapd, p);
+#ifdef CONFIG_WPS
+ if (sta->flags & WLAN_STA_WPS) {
+ struct wpabuf *wps = wps_build_assoc_resp_ie();
+ if (wps) {
+ os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
+ p += wpabuf_len(wps);
+ wpabuf_free(wps);
+ }
+ }
+#endif /* CONFIG_WPS */
+
send_len += p - reply->u.assoc_resp.variable;
if (hapd->drv.send_mgmt_frame(hapd, reply, send_len) < 0)
/**
+ * wps_build_assoc_resp_ie - Build WPS IE for (Re)Association Response
+ * Returns: WPS IE or %NULL on failure
+ *
+ * The caller is responsible for freeing the buffer.
+ */
+struct wpabuf * wps_build_assoc_resp_ie(void)
+{
+ struct wpabuf *ie;
+ u8 *len;
+
+ wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
+ "Response");
+ ie = wpabuf_alloc(100);
+ if (ie == NULL)
+ return NULL;
+
+ wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
+ len = wpabuf_put(ie, 1);
+ wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
+
+ if (wps_build_version(ie) ||
+ wps_build_resp_type(ie, WPS_RESP_AP)) {
+ wpabuf_free(ie);
+ return NULL;
+ }
+
+ *len = wpabuf_len(ie) - 2;
+
+ return ie;
+}
+
+
+/**
* wps_build_probe_req_ie - Build WPS IE for Probe Request
* @pbc: Whether searching for PBC mode APs
* @dev: Device attributes
const u8 * wps_get_uuid_e(const struct wpabuf *msg);
struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type);
+struct wpabuf * wps_build_assoc_resp_ie(void);
struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
const u8 *uuid,
enum wps_request_type req_type);
}
+int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type)
+{
+ wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", type);
+ wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
+ wpabuf_put_be16(msg, 1);
+ wpabuf_put_u8(msg, type);
+ return 0;
+}
+
+
int wps_build_config_methods(struct wpabuf *msg, u16 methods)
{
wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods);
/* wps_attr_build.c */
int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type);
+int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type);
int wps_build_config_methods(struct wpabuf *msg, u16 methods);
int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
int wps_build_dev_password_id(struct wpabuf *msg, u16 id);
}
-static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
-{
- u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
- wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", resp);
- wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
- wpabuf_put_be16(msg, 1);
- wpabuf_put_u8(msg, resp);
- return 0;
-}
-
-
/**
* wps_registrar_init - Initialize WPS Registrar data
* @wps: Pointer to longterm WPS context
wps_build_selected_registrar(reg, probe) ||
wps_build_sel_reg_dev_password_id(reg, probe) ||
wps_build_sel_reg_config_methods(reg, probe) ||
- wps_build_resp_type(reg, probe) ||
+ wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
+ WPS_RESP_REGISTRAR) ||
wps_build_uuid_e(probe, reg->wps->uuid) ||
wps_build_device_attrs(®->wps->dev, probe) ||
wps_build_probe_config_methods(reg, probe) ||