Allow SCAN command to specify scan_ssid=1 SSIDs

The new "scan_id=<comma separated list of network ids>" parameter can
now be used to specify a list of network ids that have scan_ssid=1 to
indicate active scanning of the SSID. This adds the listed SSIDs to the
scan command to allow manual scan requests to perform active scans for
hidden SSIDs. For example, "SCAN scan_id=1,7,11" would run a scan with
the SSID fetched from the configured network blocks 1, 7, and 11
(assuming those are set with scan_ssid=1). The SSIDs will be included
even from network blocks that are currently disabled.

The maximum number of SSIDs added to the request is limited by the
driver support. If more than supported values are specified, the command
will fail (returns "FAIL").

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Li Jianyun 2014-07-01 23:22:56 +08:00 committed by Jouni Malinen
parent 18389abcca
commit 6891f0e6f4
3 changed files with 74 additions and 0 deletions

View file

@ -5986,6 +5986,25 @@ static int set_scan_freqs(struct wpa_supplicant *wpa_s, char *val)
} }
static int scan_id_list_parse(struct wpa_supplicant *wpa_s, const char *value)
{
const char *pos = value;
while (pos) {
if (*pos == ' ' || *pos == '\0')
break;
if (wpa_s->scan_id_count == MAX_SCAN_ID)
return -1;
wpa_s->scan_id[wpa_s->scan_id_count++] = atoi(pos);
pos = os_strchr(pos, ',');
if (pos)
pos++;
}
return 0;
}
static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params, static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
char *reply, int reply_size, int *reply_len) char *reply, int reply_size, int *reply_len)
{ {
@ -5999,6 +6018,7 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
wpa_s->manual_scan_passive = 0; wpa_s->manual_scan_passive = 0;
wpa_s->manual_scan_use_id = 0; wpa_s->manual_scan_use_id = 0;
wpa_s->manual_scan_only_new = 0; wpa_s->manual_scan_only_new = 0;
wpa_s->scan_id_count = 0;
if (params) { if (params) {
if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0) if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0)
@ -6021,6 +6041,12 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params,
pos = os_strstr(params, "only_new=1"); pos = os_strstr(params, "only_new=1");
if (pos) if (pos)
wpa_s->manual_scan_only_new = 1; wpa_s->manual_scan_only_new = 1;
pos = os_strstr(params, "scan_id=");
if (pos && scan_id_list_parse(wpa_s, pos + 8) < 0) {
*reply_len = -1;
return;
}
} else { } else {
os_free(wpa_s->manual_scan_freqs); os_free(wpa_s->manual_scan_freqs);
wpa_s->manual_scan_freqs = NULL; wpa_s->manual_scan_freqs = NULL;

View file

@ -548,6 +548,47 @@ static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
} }
static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
struct wpa_driver_scan_params *params,
size_t max_ssids)
{
unsigned int i;
struct wpa_ssid *ssid;
for (i = 0; i < wpa_s->scan_id_count; i++) {
unsigned int j;
ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
if (!ssid || !ssid->scan_ssid)
continue;
for (j = 0; j < params->num_ssids; j++) {
if (params->ssids[j].ssid_len == ssid->ssid_len &&
params->ssids[j].ssid &&
os_memcmp(params->ssids[j].ssid, ssid->ssid,
ssid->ssid_len) == 0)
break;
}
if (j < params->num_ssids)
continue; /* already in the list */
if (params->num_ssids + 1 > max_ssids) {
wpa_printf(MSG_DEBUG,
"Over max scan SSIDs for manual request");
break;
}
wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
params->ssids[params->num_ssids].ssid = ssid->ssid;
params->ssids[params->num_ssids].ssid_len = ssid->ssid_len;
params->num_ssids++;
}
wpa_s->scan_id_count = 0;
}
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{ {
struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_supplicant *wpa_s = eloop_ctx;
@ -758,6 +799,10 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
ssid = wpa_s->conf->ssid; ssid = wpa_s->conf->ssid;
} }
if (wpa_s->scan_id_count &&
wpa_s->last_scan_req == MANUAL_SCAN_REQ)
wpa_set_scan_ssids(wpa_s, &params, max_ssids);
for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) {
if (wpas_network_disabled(wpa_s, tssid)) if (wpas_network_disabled(wpa_s, tssid))
continue; continue;

View file

@ -568,6 +568,9 @@ struct wpa_supplicant {
int normal_scans; /* normal scans run before sched_scan */ int normal_scans; /* normal scans run before sched_scan */
int scan_for_connection; /* whether the scan request was triggered for int scan_for_connection; /* whether the scan request was triggered for
* finding a connection */ * finding a connection */
#define MAX_SCAN_ID 16
int scan_id[MAX_SCAN_ID];
unsigned int scan_id_count;
unsigned int drv_flags; unsigned int drv_flags;
unsigned int drv_enc; unsigned int drv_enc;