aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/scan.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-11-23 19:34:26 +0200
committerJouni Malinen <j@w1.fi>2008-11-23 19:34:26 +0200
commitad08c3633cc2858d28b30a3545341e1e4dda4a90 (patch)
tree90b8f0ed5762d876df61013e851acc539f29f320 /wpa_supplicant/scan.c
parent6e89cc438e1af4b9b23341faee40bbe271b3de8d (diff)
downloadexternal_wpa_supplicant_8_ti-ad08c3633cc2858d28b30a3545341e1e4dda4a90.zip
external_wpa_supplicant_8_ti-ad08c3633cc2858d28b30a3545341e1e4dda4a90.tar.gz
external_wpa_supplicant_8_ti-ad08c3633cc2858d28b30a3545341e1e4dda4a90.tar.bz2
Added preliminary Wi-Fi Protected Setup (WPS) implementation
This adds WPS support for both hostapd and wpa_supplicant. Both programs can be configured to act as WPS Enrollee and Registrar. Both PBC and PIN methods are supported. Currently, hostapd has more complete configuration option for WPS parameters and wpa_supplicant configuration style will likely change in the future. External Registrars are not yet supported in hostapd or wpa_supplicant. While wpa_supplicant has initial support for acting as an Registrar to configure an AP, this is still using number of hardcoded parameters which will need to be made configurable for proper operation.
Diffstat (limited to 'wpa_supplicant/scan.c')
-rw-r--r--wpa_supplicant/scan.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 3c5bad9..04b6d44 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -20,6 +20,7 @@
#include "wpa_supplicant_i.h"
#include "mlme.h"
#include "uuid.h"
+#include "wps/wps.h"
static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
@@ -41,13 +42,45 @@ static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
}
+#ifdef CONFIG_WPS
+static int wpas_wps_in_use(struct wpa_config *conf, u8 *uuid)
+{
+ struct wpa_ssid *ssid;
+ int wps = 0;
+ const char *pos;
+
+ for (ssid = conf->ssid; ssid; ssid = ssid->next) {
+ if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
+ continue;
+
+ wps = 1;
+ if (!ssid->eap.phase1)
+ continue;
+
+ pos = os_strstr(ssid->eap.phase1, "uuid=");
+ if (pos)
+ uuid_str2bin(pos + 5, uuid);
+
+ if (os_strstr(ssid->eap.phase1, "pbc=1"))
+ return 2;
+ }
+
+ return wps;
+}
+#endif /* CONFIG_WPS */
+
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_ssid *ssid;
int enabled, scan_req = 0, ret;
+ struct wpabuf *wps_ie = NULL;
const u8 *extra_ie = NULL;
size_t extra_ie_len = 0;
+ int wps = 0;
+#ifdef CONFIG_WPS
+ u8 uuid[UUID_LEN];
+#endif /* CONFIG_WPS */
if (wpa_s->disconnected && !wpa_s->scan_req)
return;
@@ -134,8 +167,12 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
} else
wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+#ifdef CONFIG_WPS
+ wps = wpas_wps_in_use(wpa_s->conf, uuid);
+#endif /* CONFIG_WPS */
+
if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
- !wpa_s->use_client_mlme) {
+ !wpa_s->use_client_mlme && wps != 2) {
wpa_s->scan_res_tried++;
wpa_s->scan_req = scan_req;
wpa_printf(MSG_DEBUG, "Trying to get current scan results "
@@ -145,6 +182,16 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
return;
}
+#ifdef CONFIG_WPS
+ if (wps) {
+ wps_ie = wps_enrollee_build_probe_req_ie(wps == 2, uuid);
+ if (wps_ie) {
+ extra_ie = wpabuf_head(wps_ie);
+ extra_ie_len = wpabuf_len(wps_ie);
+ }
+ }
+#endif /* CONFIG_WPS */
+
if (wpa_s->use_client_mlme) {
ieee80211_sta_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len);
ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
@@ -155,6 +202,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
ssid ? ssid->ssid_len : 0);
}
+ wpabuf_free(wps_ie);
+
if (ret) {
wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
wpa_supplicant_req_scan(wpa_s, 10, 0);