• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant - Scanning
3  * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/ieee802_11_defs.h"
14 #include "common/wpa_ctrl.h"
15 #include "config.h"
16 #include "wpa_supplicant_i.h"
17 #include "driver_i.h"
18 #include "wps_supplicant.h"
19 #include "p2p_supplicant.h"
20 #include "p2p/p2p.h"
21 #include "hs20_supplicant.h"
22 #include "notify.h"
23 #include "bss.h"
24 #include "scan.h"
25 
26 
wpa_supplicant_gen_assoc_event(struct wpa_supplicant * wpa_s)27 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
28 {
29 	struct wpa_ssid *ssid;
30 	union wpa_event_data data;
31 
32 	ssid = wpa_supplicant_get_ssid(wpa_s);
33 	if (ssid == NULL)
34 		return;
35 
36 	if (wpa_s->current_ssid == NULL) {
37 		wpa_s->current_ssid = ssid;
38 		if (wpa_s->current_ssid != NULL)
39 			wpas_notify_network_changed(wpa_s);
40 	}
41 	wpa_supplicant_initiate_eapol(wpa_s);
42 	wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured "
43 		"network - generating associated event");
44 	os_memset(&data, 0, sizeof(data));
45 	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
46 }
47 
48 
49 #ifdef CONFIG_WPS
wpas_wps_in_use(struct wpa_supplicant * wpa_s,enum wps_request_type * req_type)50 static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
51 			   enum wps_request_type *req_type)
52 {
53 	struct wpa_ssid *ssid;
54 	int wps = 0;
55 
56 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
57 		if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
58 			continue;
59 
60 		wps = 1;
61 		*req_type = wpas_wps_get_req_type(ssid);
62 		if (!ssid->eap.phase1)
63 			continue;
64 
65 		if (os_strstr(ssid->eap.phase1, "pbc=1"))
66 			return 2;
67 	}
68 
69 #ifdef CONFIG_P2P
70 	if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
71 	    !wpa_s->conf->p2p_disabled) {
72 		wpa_s->wps->dev.p2p = 1;
73 		if (!wps) {
74 			wps = 1;
75 			*req_type = WPS_REQ_ENROLLEE_INFO;
76 		}
77 	}
78 #endif /* CONFIG_P2P */
79 
80 	return wps;
81 }
82 #endif /* CONFIG_WPS */
83 
84 
85 /**
86  * wpa_supplicant_enabled_networks - Check whether there are enabled networks
87  * @wpa_s: Pointer to wpa_supplicant data
88  * Returns: 0 if no networks are enabled, >0 if networks are enabled
89  *
90  * This function is used to figure out whether any networks (or Interworking
91  * with enabled credentials and auto_interworking) are present in the current
92  * configuration.
93  */
wpa_supplicant_enabled_networks(struct wpa_supplicant * wpa_s)94 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
95 {
96 	struct wpa_ssid *ssid = wpa_s->conf->ssid;
97 	int count = 0, disabled = 0;
98 	while (ssid) {
99 		if (!wpas_network_disabled(wpa_s, ssid))
100 			count++;
101 		else
102 			disabled++;
103 		ssid = ssid->next;
104 	}
105 	if (wpa_s->conf->cred && wpa_s->conf->interworking &&
106 	    wpa_s->conf->auto_interworking)
107 		count++;
108 	if (count == 0 && disabled > 0) {
109 		wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled "
110 			"networks)", disabled);
111 	}
112 	return count;
113 }
114 
115 
wpa_supplicant_assoc_try(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)116 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
117 				     struct wpa_ssid *ssid)
118 {
119 	while (ssid) {
120 		if (!wpas_network_disabled(wpa_s, ssid))
121 			break;
122 		ssid = ssid->next;
123 	}
124 
125 	/* ap_scan=2 mode - try to associate with each SSID. */
126 	if (ssid == NULL) {
127 		wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
128 			"end of scan list - go back to beginning");
129 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
130 		wpa_supplicant_req_scan(wpa_s, 0, 0);
131 		return;
132 	}
133 	if (ssid->next) {
134 		/* Continue from the next SSID on the next attempt. */
135 		wpa_s->prev_scan_ssid = ssid;
136 	} else {
137 		/* Start from the beginning of the SSID list. */
138 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
139 	}
140 	wpa_supplicant_associate(wpa_s, NULL, ssid);
141 }
142 
143 
wpas_trigger_scan_cb(struct wpa_radio_work * work,int deinit)144 static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
145 {
146 	struct wpa_supplicant *wpa_s = work->wpa_s;
147 	struct wpa_driver_scan_params *params = work->ctx;
148 	int ret;
149 
150 	if (deinit) {
151 		if (!work->started) {
152 			wpa_scan_free_params(params);
153 			return;
154 		}
155 		wpa_supplicant_notify_scanning(wpa_s, 0);
156 		wpas_notify_scan_done(wpa_s, 0);
157 		wpa_s->scan_work = NULL;
158 		return;
159 	}
160 
161 	wpa_supplicant_notify_scanning(wpa_s, 1);
162 
163 	if (wpa_s->clear_driver_scan_cache)
164 		params->only_new_results = 1;
165 	ret = wpa_drv_scan(wpa_s, params);
166 	wpa_scan_free_params(params);
167 	work->ctx = NULL;
168 	if (ret) {
169 		wpa_supplicant_notify_scanning(wpa_s, 0);
170 		wpas_notify_scan_done(wpa_s, 0);
171 		radio_work_done(work);
172 		return;
173 	}
174 
175 	os_get_reltime(&wpa_s->scan_trigger_time);
176 	wpa_s->scan_runs++;
177 	wpa_s->normal_scans++;
178 	wpa_s->own_scan_requested = 1;
179 	wpa_s->clear_driver_scan_cache = 0;
180 	wpa_s->scan_work = work;
181 }
182 
183 
184 /**
185  * wpa_supplicant_trigger_scan - Request driver to start a scan
186  * @wpa_s: Pointer to wpa_supplicant data
187  * @params: Scan parameters
188  * Returns: 0 on success, -1 on failure
189  */
wpa_supplicant_trigger_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)190 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
191 				struct wpa_driver_scan_params *params)
192 {
193 	struct wpa_driver_scan_params *ctx;
194 
195 	if (wpa_s->scan_work) {
196 		wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
197 		return -1;
198 	}
199 
200 	ctx = wpa_scan_clone_params(params);
201 	if (ctx == NULL)
202 		return -1;
203 
204 	if (radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
205 	{
206 		wpa_scan_free_params(ctx);
207 		return -1;
208 	}
209 
210 	return 0;
211 }
212 
213 
214 static void
wpa_supplicant_delayed_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)215 wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
216 {
217 	struct wpa_supplicant *wpa_s = eloop_ctx;
218 
219 	wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
220 
221 	if (wpa_supplicant_req_sched_scan(wpa_s))
222 		wpa_supplicant_req_scan(wpa_s, 0, 0);
223 }
224 
225 
226 static void
wpa_supplicant_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)227 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
228 {
229 	struct wpa_supplicant *wpa_s = eloop_ctx;
230 
231 	wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
232 
233 	wpa_s->sched_scan_timed_out = 1;
234 	wpa_supplicant_cancel_sched_scan(wpa_s);
235 }
236 
237 
wpa_supplicant_start_sched_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,int interval)238 int wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
239 				    struct wpa_driver_scan_params *params,
240 				    int interval)
241 {
242 	int ret;
243 
244 	wpa_supplicant_notify_scanning(wpa_s, 1);
245 	ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000);
246 	if (ret)
247 		wpa_supplicant_notify_scanning(wpa_s, 0);
248 	else
249 		wpa_s->sched_scanning = 1;
250 
251 	return ret;
252 }
253 
254 
wpa_supplicant_stop_sched_scan(struct wpa_supplicant * wpa_s)255 int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
256 {
257 	int ret;
258 
259 	ret = wpa_drv_stop_sched_scan(wpa_s);
260 	if (ret) {
261 		wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
262 		/* TODO: what to do if stopping fails? */
263 		return -1;
264 	}
265 
266 	return ret;
267 }
268 
269 
270 static struct wpa_driver_scan_filter *
wpa_supplicant_build_filter_ssids(struct wpa_config * conf,size_t * num_ssids)271 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
272 {
273 	struct wpa_driver_scan_filter *ssids;
274 	struct wpa_ssid *ssid;
275 	size_t count;
276 
277 	*num_ssids = 0;
278 	if (!conf->filter_ssids)
279 		return NULL;
280 
281 	for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
282 		if (ssid->ssid && ssid->ssid_len)
283 			count++;
284 	}
285 	if (count == 0)
286 		return NULL;
287 	ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter));
288 	if (ssids == NULL)
289 		return NULL;
290 
291 	for (ssid = conf->ssid; ssid; ssid = ssid->next) {
292 		if (!ssid->ssid || !ssid->ssid_len)
293 			continue;
294 		os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
295 		ssids[*num_ssids].ssid_len = ssid->ssid_len;
296 		(*num_ssids)++;
297 	}
298 
299 	return ssids;
300 }
301 
302 
wpa_supplicant_optimize_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)303 static void wpa_supplicant_optimize_freqs(
304 	struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
305 {
306 #ifdef CONFIG_P2P
307 	if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
308 	    wpa_s->go_params) {
309 		/* Optimize provisioning state scan based on GO information */
310 		if (wpa_s->p2p_in_provisioning < 5 &&
311 		    wpa_s->go_params->freq > 0) {
312 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
313 				"preferred frequency %d MHz",
314 				wpa_s->go_params->freq);
315 			params->freqs = os_zalloc(2 * sizeof(int));
316 			if (params->freqs)
317 				params->freqs[0] = wpa_s->go_params->freq;
318 		} else if (wpa_s->p2p_in_provisioning < 8 &&
319 			   wpa_s->go_params->freq_list[0]) {
320 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
321 				"channels");
322 			int_array_concat(&params->freqs,
323 					 wpa_s->go_params->freq_list);
324 			if (params->freqs)
325 				int_array_sort_unique(params->freqs);
326 		}
327 		wpa_s->p2p_in_provisioning++;
328 	}
329 
330 	if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
331 		/*
332 		 * Optimize scan based on GO information during persistent
333 		 * group reinvocation
334 		 */
335 		if (wpa_s->p2p_in_invitation < 5 &&
336 		    wpa_s->p2p_invite_go_freq > 0) {
337 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
338 				wpa_s->p2p_invite_go_freq);
339 			params->freqs = os_zalloc(2 * sizeof(int));
340 			if (params->freqs)
341 				params->freqs[0] = wpa_s->p2p_invite_go_freq;
342 		}
343 		wpa_s->p2p_in_invitation++;
344 		if (wpa_s->p2p_in_invitation > 20) {
345 			/*
346 			 * This should not really happen since the variable is
347 			 * cleared on group removal, but if it does happen, make
348 			 * sure we do not get stuck in special invitation scan
349 			 * mode.
350 			 */
351 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
352 			wpa_s->p2p_in_invitation = 0;
353 		}
354 	}
355 #endif /* CONFIG_P2P */
356 
357 #ifdef CONFIG_WPS
358 	if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
359 		/*
360 		 * Optimize post-provisioning scan based on channel used
361 		 * during provisioning.
362 		 */
363 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
364 			"that was used during provisioning", wpa_s->wps_freq);
365 		params->freqs = os_zalloc(2 * sizeof(int));
366 		if (params->freqs)
367 			params->freqs[0] = wpa_s->wps_freq;
368 		wpa_s->after_wps--;
369 	} else if (wpa_s->after_wps)
370 		wpa_s->after_wps--;
371 
372 	if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq)
373 	{
374 		/* Optimize provisioning scan based on already known channel */
375 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz",
376 			wpa_s->wps_freq);
377 		params->freqs = os_zalloc(2 * sizeof(int));
378 		if (params->freqs)
379 			params->freqs[0] = wpa_s->wps_freq;
380 		wpa_s->known_wps_freq = 0; /* only do this once */
381 	}
382 #endif /* CONFIG_WPS */
383 }
384 
385 
386 #ifdef CONFIG_INTERWORKING
wpas_add_interworking_elements(struct wpa_supplicant * wpa_s,struct wpabuf * buf)387 static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
388 					   struct wpabuf *buf)
389 {
390 	if (wpa_s->conf->interworking == 0)
391 		return;
392 
393 	wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB);
394 	wpabuf_put_u8(buf, 6);
395 	wpabuf_put_u8(buf, 0x00);
396 	wpabuf_put_u8(buf, 0x00);
397 	wpabuf_put_u8(buf, 0x00);
398 	wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */
399 	wpabuf_put_u8(buf, 0x00);
400 #ifdef CONFIG_HS20
401 	wpabuf_put_u8(buf, 0x40); /* Bit 46 - WNM-Notification */
402 #else /* CONFIG_HS20 */
403 	wpabuf_put_u8(buf, 0x00);
404 #endif /* CONFIG_HS20 */
405 
406 	wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
407 	wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
408 		      1 + ETH_ALEN);
409 	wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
410 	/* No Venue Info */
411 	if (!is_zero_ether_addr(wpa_s->conf->hessid))
412 		wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
413 }
414 #endif /* CONFIG_INTERWORKING */
415 
416 
wpa_supplicant_extra_ies(struct wpa_supplicant * wpa_s)417 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
418 {
419 	struct wpabuf *extra_ie = NULL;
420 #ifdef CONFIG_WPS
421 	int wps = 0;
422 	enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
423 #endif /* CONFIG_WPS */
424 
425 #ifdef CONFIG_INTERWORKING
426 	if (wpa_s->conf->interworking &&
427 	    wpabuf_resize(&extra_ie, 100) == 0)
428 		wpas_add_interworking_elements(wpa_s, extra_ie);
429 #endif /* CONFIG_INTERWORKING */
430 
431 #ifdef CONFIG_WPS
432 	wps = wpas_wps_in_use(wpa_s, &req_type);
433 
434 	if (wps) {
435 		struct wpabuf *wps_ie;
436 		wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON :
437 						DEV_PW_DEFAULT,
438 						&wpa_s->wps->dev,
439 						wpa_s->wps->uuid, req_type,
440 						0, NULL);
441 		if (wps_ie) {
442 			if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
443 				wpabuf_put_buf(extra_ie, wps_ie);
444 			wpabuf_free(wps_ie);
445 		}
446 	}
447 
448 #ifdef CONFIG_P2P
449 	if (wps) {
450 		size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
451 		if (wpabuf_resize(&extra_ie, ielen) == 0)
452 			wpas_p2p_scan_ie(wpa_s, extra_ie);
453 	}
454 #endif /* CONFIG_P2P */
455 
456 #endif /* CONFIG_WPS */
457 
458 #ifdef CONFIG_HS20
459 	if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 7) == 0)
460 		wpas_hs20_add_indication(extra_ie, -1);
461 #endif /* CONFIG_HS20 */
462 
463 	return extra_ie;
464 }
465 
466 
467 #ifdef CONFIG_P2P
468 
469 /*
470  * Check whether there are any enabled networks or credentials that could be
471  * used for a non-P2P connection.
472  */
non_p2p_network_enabled(struct wpa_supplicant * wpa_s)473 static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
474 {
475 	struct wpa_ssid *ssid;
476 
477 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
478 		if (wpas_network_disabled(wpa_s, ssid))
479 			continue;
480 		if (!ssid->p2p_group)
481 			return 1;
482 	}
483 
484 	if (wpa_s->conf->cred && wpa_s->conf->interworking &&
485 	    wpa_s->conf->auto_interworking)
486 		return 1;
487 
488 	return 0;
489 }
490 
491 #endif /* CONFIG_P2P */
492 
493 
get_mode(struct hostapd_hw_modes * modes,u16 num_modes,enum hostapd_hw_mode mode)494 static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
495 					  u16 num_modes,
496 					  enum hostapd_hw_mode mode)
497 {
498 	u16 i;
499 
500 	for (i = 0; i < num_modes; i++) {
501 		if (modes[i].mode == mode)
502 			return &modes[i];
503 	}
504 
505 	return NULL;
506 }
507 
508 
wpa_setband_scan_freqs_list(struct wpa_supplicant * wpa_s,enum hostapd_hw_mode band,struct wpa_driver_scan_params * params)509 static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
510 					enum hostapd_hw_mode band,
511 					struct wpa_driver_scan_params *params)
512 {
513 	/* Include only supported channels for the specified band */
514 	struct hostapd_hw_modes *mode;
515 	int count, i;
516 
517 	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
518 	if (mode == NULL) {
519 		/* No channels supported in this band - use empty list */
520 		params->freqs = os_zalloc(sizeof(int));
521 		return;
522 	}
523 
524 	params->freqs = os_zalloc((mode->num_channels + 1) * sizeof(int));
525 	if (params->freqs == NULL)
526 		return;
527 	for (count = 0, i = 0; i < mode->num_channels; i++) {
528 		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
529 			continue;
530 		params->freqs[count++] = mode->channels[i].freq;
531 	}
532 }
533 
534 
wpa_setband_scan_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)535 static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
536 				   struct wpa_driver_scan_params *params)
537 {
538 	if (wpa_s->hw.modes == NULL)
539 		return; /* unknown what channels the driver supports */
540 	if (params->freqs)
541 		return; /* already using a limited channel set */
542 	if (wpa_s->setband == WPA_SETBAND_5G)
543 		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
544 					    params);
545 	else if (wpa_s->setband == WPA_SETBAND_2G)
546 		wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
547 					    params);
548 }
549 
550 
wpa_set_scan_ssids(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids)551 static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
552 			       struct wpa_driver_scan_params *params,
553 			       size_t max_ssids)
554 {
555 	unsigned int i;
556 	struct wpa_ssid *ssid;
557 
558 	for (i = 0; i < wpa_s->scan_id_count; i++) {
559 		unsigned int j;
560 
561 		ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
562 		if (!ssid || !ssid->scan_ssid)
563 			continue;
564 
565 		for (j = 0; j < params->num_ssids; j++) {
566 			if (params->ssids[j].ssid_len == ssid->ssid_len &&
567 			    params->ssids[j].ssid &&
568 			    os_memcmp(params->ssids[j].ssid, ssid->ssid,
569 				      ssid->ssid_len) == 0)
570 				break;
571 		}
572 		if (j < params->num_ssids)
573 			continue; /* already in the list */
574 
575 		if (params->num_ssids + 1 > max_ssids) {
576 			wpa_printf(MSG_DEBUG,
577 				   "Over max scan SSIDs for manual request");
578 			break;
579 		}
580 
581 		wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
582 			   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
583 		params->ssids[params->num_ssids].ssid = ssid->ssid;
584 		params->ssids[params->num_ssids].ssid_len = ssid->ssid_len;
585 		params->num_ssids++;
586 	}
587 
588 	wpa_s->scan_id_count = 0;
589 }
590 
591 
wpa_supplicant_scan(void * eloop_ctx,void * timeout_ctx)592 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
593 {
594 	struct wpa_supplicant *wpa_s = eloop_ctx;
595 	struct wpa_ssid *ssid;
596 	int ret;
597 	struct wpabuf *extra_ie = NULL;
598 	struct wpa_driver_scan_params params;
599 	struct wpa_driver_scan_params *scan_params;
600 	size_t max_ssids;
601 	enum wpa_states prev_state;
602 
603 	if (wpa_s->pno || wpa_s->pno_sched_pending) {
604 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - PNO is in progress");
605 		return;
606 	}
607 
608 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
609 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
610 		return;
611 	}
612 
613 	if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
614 		wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
615 		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
616 		return;
617 	}
618 
619 	if (wpa_s->scanning) {
620 		/*
621 		 * If we are already in scanning state, we shall reschedule the
622 		 * the incoming scan request.
623 		 */
624 		wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Reschedule the incoming scan req");
625 		wpa_supplicant_req_scan(wpa_s, 1, 0);
626 		return;
627 	}
628 
629 	if (!wpa_supplicant_enabled_networks(wpa_s) &&
630 	    wpa_s->scan_req == NORMAL_SCAN_REQ) {
631 		wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
632 		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
633 		return;
634 	}
635 
636 	if (wpa_s->conf->ap_scan != 0 &&
637 	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
638 		wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
639 			"overriding ap_scan configuration");
640 		wpa_s->conf->ap_scan = 0;
641 		wpas_notify_ap_scan_changed(wpa_s);
642 	}
643 
644 	if (wpa_s->conf->ap_scan == 0) {
645 		wpa_supplicant_gen_assoc_event(wpa_s);
646 		return;
647 	}
648 
649 	if (wpas_p2p_in_progress(wpa_s)) {
650 		wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan while P2P operation is in progress");
651 		wpa_supplicant_req_scan(wpa_s, 5, 0);
652 		return;
653 	}
654 
655 	if (wpa_s->conf->ap_scan == 2)
656 		max_ssids = 1;
657 	else {
658 		max_ssids = wpa_s->max_scan_ssids;
659 		if (max_ssids > WPAS_MAX_SCAN_SSIDS)
660 			max_ssids = WPAS_MAX_SCAN_SSIDS;
661 	}
662 
663 	wpa_s->last_scan_req = wpa_s->scan_req;
664 	wpa_s->scan_req = NORMAL_SCAN_REQ;
665 
666 	os_memset(&params, 0, sizeof(params));
667 
668 	prev_state = wpa_s->wpa_state;
669 	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
670 	    wpa_s->wpa_state == WPA_INACTIVE)
671 		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
672 
673 	/*
674 	 * If autoscan has set its own scanning parameters
675 	 */
676 	if (wpa_s->autoscan_params != NULL) {
677 		scan_params = wpa_s->autoscan_params;
678 		goto scan;
679 	}
680 
681 	if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
682 	    wpa_s->connect_without_scan) {
683 		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
684 			if (ssid == wpa_s->connect_without_scan)
685 				break;
686 		}
687 		wpa_s->connect_without_scan = NULL;
688 		if (ssid) {
689 			wpa_printf(MSG_DEBUG, "Start a pre-selected network "
690 				   "without scan step");
691 			wpa_supplicant_associate(wpa_s, NULL, ssid);
692 			return;
693 		}
694 	}
695 
696 #ifdef CONFIG_P2P
697 	if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
698 	    wpa_s->go_params) {
699 		wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during P2P group formation (p2p_in_provisioning=%d show_group_started=%d)",
700 			   wpa_s->p2p_in_provisioning,
701 			   wpa_s->show_group_started);
702 		params.ssids[0].ssid = wpa_s->go_params->ssid;
703 		params.ssids[0].ssid_len = wpa_s->go_params->ssid_len;
704 		params.num_ssids = 1;
705 		goto ssid_list_set;
706 	}
707 
708 	if (wpa_s->p2p_in_invitation) {
709 		if (wpa_s->current_ssid) {
710 			wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
711 			params.ssids[0].ssid = wpa_s->current_ssid->ssid;
712 			params.ssids[0].ssid_len =
713 				wpa_s->current_ssid->ssid_len;
714 			params.num_ssids = 1;
715 		} else {
716 			wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
717 		}
718 		goto ssid_list_set;
719 	}
720 #endif /* CONFIG_P2P */
721 
722 	/* Find the starting point from which to continue scanning */
723 	ssid = wpa_s->conf->ssid;
724 	if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
725 		while (ssid) {
726 			if (ssid == wpa_s->prev_scan_ssid) {
727 				ssid = ssid->next;
728 				break;
729 			}
730 			ssid = ssid->next;
731 		}
732 	}
733 
734 	if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
735 	    wpa_s->conf->ap_scan == 2) {
736 		wpa_s->connect_without_scan = NULL;
737 		wpa_s->prev_scan_wildcard = 0;
738 		wpa_supplicant_assoc_try(wpa_s, ssid);
739 		return;
740 	} else if (wpa_s->conf->ap_scan == 2) {
741 		/*
742 		 * User-initiated scan request in ap_scan == 2; scan with
743 		 * wildcard SSID.
744 		 */
745 		ssid = NULL;
746 	} else if (wpa_s->reattach && wpa_s->current_ssid != NULL) {
747 		/*
748 		 * Perform single-channel single-SSID scan for
749 		 * reassociate-to-same-BSS operation.
750 		 */
751 		/* Setup SSID */
752 		ssid = wpa_s->current_ssid;
753 		wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
754 				  ssid->ssid, ssid->ssid_len);
755 		params.ssids[0].ssid = ssid->ssid;
756 		params.ssids[0].ssid_len = ssid->ssid_len;
757 		params.num_ssids = 1;
758 
759 		/*
760 		 * Allocate memory for frequency array, allocate one extra
761 		 * slot for the zero-terminator.
762 		 */
763 		params.freqs = os_malloc(sizeof(int) * 2);
764 		if (params.freqs == NULL) {
765 			wpa_dbg(wpa_s, MSG_ERROR, "Memory allocation failed");
766 			return;
767 		}
768 		params.freqs[0] = wpa_s->assoc_freq;
769 		params.freqs[1] = 0;
770 
771 		/*
772 		 * Reset the reattach flag so that we fall back to full scan if
773 		 * this scan fails.
774 		 */
775 		wpa_s->reattach = 0;
776 	} else {
777 		struct wpa_ssid *start = ssid, *tssid;
778 		int freqs_set = 0;
779 		if (ssid == NULL && max_ssids > 1)
780 			ssid = wpa_s->conf->ssid;
781 		while (ssid) {
782 			if (!wpas_network_disabled(wpa_s, ssid) &&
783 			    ssid->scan_ssid) {
784 				wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
785 						  ssid->ssid, ssid->ssid_len);
786 				params.ssids[params.num_ssids].ssid =
787 					ssid->ssid;
788 				params.ssids[params.num_ssids].ssid_len =
789 					ssid->ssid_len;
790 				params.num_ssids++;
791 				if (params.num_ssids + 1 >= max_ssids)
792 					break;
793 			}
794 			ssid = ssid->next;
795 			if (ssid == start)
796 				break;
797 			if (ssid == NULL && max_ssids > 1 &&
798 			    start != wpa_s->conf->ssid)
799 				ssid = wpa_s->conf->ssid;
800 		}
801 
802 		if (wpa_s->scan_id_count &&
803 		    wpa_s->last_scan_req == MANUAL_SCAN_REQ)
804 			wpa_set_scan_ssids(wpa_s, &params, max_ssids);
805 
806 		for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) {
807 			if (wpas_network_disabled(wpa_s, tssid))
808 				continue;
809 			if ((params.freqs || !freqs_set) && tssid->scan_freq) {
810 				int_array_concat(&params.freqs,
811 						 tssid->scan_freq);
812 			} else {
813 				os_free(params.freqs);
814 				params.freqs = NULL;
815 			}
816 			freqs_set = 1;
817 		}
818 		int_array_sort_unique(params.freqs);
819 	}
820 
821 	if (ssid && max_ssids == 1) {
822 		/*
823 		 * If the driver is limited to 1 SSID at a time interleave
824 		 * wildcard SSID scans with specific SSID scans to avoid
825 		 * waiting a long time for a wildcard scan.
826 		 */
827 		if (!wpa_s->prev_scan_wildcard) {
828 			params.ssids[0].ssid = NULL;
829 			params.ssids[0].ssid_len = 0;
830 			wpa_s->prev_scan_wildcard = 1;
831 			wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for "
832 				"wildcard SSID (Interleave with specific)");
833 		} else {
834 			wpa_s->prev_scan_ssid = ssid;
835 			wpa_s->prev_scan_wildcard = 0;
836 			wpa_dbg(wpa_s, MSG_DEBUG,
837 				"Starting AP scan for specific SSID: %s",
838 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
839 		}
840 	} else if (ssid) {
841 		/* max_ssids > 1 */
842 
843 		wpa_s->prev_scan_ssid = ssid;
844 		wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
845 			"the scan request");
846 		params.num_ssids++;
847 	} else if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
848 		   wpa_s->manual_scan_passive && params.num_ssids == 0) {
849 		wpa_dbg(wpa_s, MSG_DEBUG, "Use passive scan based on manual request");
850 	} else {
851 		wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
852 		params.num_ssids++;
853 		wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
854 			"SSID");
855 	}
856 #ifdef CONFIG_P2P
857 ssid_list_set:
858 #endif /* CONFIG_P2P */
859 
860 	wpa_supplicant_optimize_freqs(wpa_s, &params);
861 	extra_ie = wpa_supplicant_extra_ies(wpa_s);
862 
863 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
864 	    wpa_s->manual_scan_only_new)
865 		params.only_new_results = 1;
866 
867 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL &&
868 	    wpa_s->manual_scan_freqs) {
869 		wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels");
870 		params.freqs = wpa_s->manual_scan_freqs;
871 		wpa_s->manual_scan_freqs = NULL;
872 	}
873 
874 	if (params.freqs == NULL && wpa_s->next_scan_freqs) {
875 		wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
876 			"generated frequency list");
877 		params.freqs = wpa_s->next_scan_freqs;
878 	} else
879 		os_free(wpa_s->next_scan_freqs);
880 	wpa_s->next_scan_freqs = NULL;
881 	wpa_setband_scan_freqs(wpa_s, &params);
882 
883 	/* See if user specified frequencies. If so, scan only those. */
884 	if (wpa_s->conf->freq_list && !params.freqs) {
885 		wpa_dbg(wpa_s, MSG_DEBUG,
886 			"Optimize scan based on conf->freq_list");
887 		int_array_concat(&params.freqs, wpa_s->conf->freq_list);
888 	}
889 
890 	/* Use current associated channel? */
891 	if (wpa_s->conf->scan_cur_freq && !params.freqs) {
892 		unsigned int num = wpa_s->num_multichan_concurrent;
893 
894 		params.freqs = os_calloc(num + 1, sizeof(int));
895 		if (params.freqs) {
896 			num = get_shared_radio_freqs(wpa_s, params.freqs, num);
897 			if (num > 0) {
898 				wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
899 					"current operating channels since "
900 					"scan_cur_freq is enabled");
901 			} else {
902 				os_free(params.freqs);
903 				params.freqs = NULL;
904 			}
905 		}
906 	}
907 
908 	params.filter_ssids = wpa_supplicant_build_filter_ssids(
909 		wpa_s->conf, &params.num_filter_ssids);
910 	if (extra_ie) {
911 		params.extra_ies = wpabuf_head(extra_ie);
912 		params.extra_ies_len = wpabuf_len(extra_ie);
913 	}
914 
915 #ifdef CONFIG_P2P
916 	if (wpa_s->p2p_in_provisioning || wpa_s->p2p_in_invitation ||
917 	    (wpa_s->show_group_started && wpa_s->go_params)) {
918 		/*
919 		 * The interface may not yet be in P2P mode, so we have to
920 		 * explicitly request P2P probe to disable CCK rates.
921 		 */
922 		params.p2p_probe = 1;
923 	}
924 #endif /* CONFIG_P2P */
925 
926 	scan_params = &params;
927 
928 scan:
929 #ifdef CONFIG_P2P
930 	/*
931 	 * If the driver does not support multi-channel concurrency and a
932 	 * virtual interface that shares the same radio with the wpa_s interface
933 	 * is operating there may not be need to scan other channels apart from
934 	 * the current operating channel on the other virtual interface. Filter
935 	 * out other channels in case we are trying to find a connection for a
936 	 * station interface when we are not configured to prefer station
937 	 * connection and a concurrent operation is already in process.
938 	 */
939 	if (wpa_s->scan_for_connection &&
940 	    wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
941 	    !scan_params->freqs && !params.freqs &&
942 	    wpas_is_p2p_prioritized(wpa_s) &&
943 	    wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
944 	    non_p2p_network_enabled(wpa_s)) {
945 		unsigned int num = wpa_s->num_multichan_concurrent;
946 
947 		params.freqs = os_calloc(num + 1, sizeof(int));
948 		if (params.freqs) {
949 			num = get_shared_radio_freqs(wpa_s, params.freqs, num);
950 			if (num > 0 && num == wpa_s->num_multichan_concurrent) {
951 				wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used");
952 			} else {
953 				os_free(params.freqs);
954 				params.freqs = NULL;
955 			}
956 		}
957 	}
958 #endif /* CONFIG_P2P */
959 
960 	ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
961 
962 	if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
963 	    !wpa_s->manual_scan_freqs) {
964 		/* Restore manual_scan_freqs for the next attempt */
965 		wpa_s->manual_scan_freqs = params.freqs;
966 		params.freqs = NULL;
967 	}
968 
969 	wpabuf_free(extra_ie);
970 	os_free(params.freqs);
971 	os_free(params.filter_ssids);
972 
973 	if (ret) {
974 		wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
975 		if (prev_state != wpa_s->wpa_state)
976 			wpa_supplicant_set_state(wpa_s, prev_state);
977 		/* Restore scan_req since we will try to scan again */
978 		wpa_s->scan_req = wpa_s->last_scan_req;
979 		wpa_supplicant_req_scan(wpa_s, 1, 0);
980 	} else {
981 		wpa_s->scan_for_connection = 0;
982 	}
983 }
984 
985 
wpa_supplicant_update_scan_int(struct wpa_supplicant * wpa_s,int sec)986 void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec)
987 {
988 	struct os_reltime remaining, new_int;
989 	int cancelled;
990 
991 	cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL,
992 					     &remaining);
993 
994 	new_int.sec = sec;
995 	new_int.usec = 0;
996 	if (cancelled && os_reltime_before(&remaining, &new_int)) {
997 		new_int.sec = remaining.sec;
998 		new_int.usec = remaining.usec;
999 	}
1000 
1001 	if (cancelled) {
1002 		eloop_register_timeout(new_int.sec, new_int.usec,
1003 				       wpa_supplicant_scan, wpa_s, NULL);
1004 	}
1005 	wpa_s->scan_interval = sec;
1006 }
1007 
1008 
1009 /**
1010  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
1011  * @wpa_s: Pointer to wpa_supplicant data
1012  * @sec: Number of seconds after which to scan
1013  * @usec: Number of microseconds after which to scan
1014  *
1015  * This function is used to schedule a scan for neighboring access points after
1016  * the specified time.
1017  */
wpa_supplicant_req_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1018 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
1019 {
1020 	int res = eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s,
1021 					NULL);
1022 	if (res == 1) {
1023 		wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d.%06d sec",
1024 			sec, usec);
1025 	} else if (res == 0) {
1026 		wpa_dbg(wpa_s, MSG_DEBUG, "Ignore new scan request for %d.%06d sec since an earlier request is scheduled to trigger sooner",
1027 			sec, usec);
1028 	} else {
1029 		wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d.%06d sec",
1030 			sec, usec);
1031 		eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
1032 	}
1033 }
1034 
1035 
1036 /**
1037  * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
1038  * @wpa_s: Pointer to wpa_supplicant data
1039  * @sec: Number of seconds after which to scan
1040  * @usec: Number of microseconds after which to scan
1041  * Returns: 0 on success or -1 otherwise
1042  *
1043  * This function is used to schedule periodic scans for neighboring
1044  * access points after the specified time.
1045  */
wpa_supplicant_delayed_sched_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1046 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
1047 				      int sec, int usec)
1048 {
1049 	if (!wpa_s->sched_scan_supported)
1050 		return -1;
1051 
1052 	eloop_register_timeout(sec, usec,
1053 			       wpa_supplicant_delayed_sched_scan_timeout,
1054 			       wpa_s, NULL);
1055 
1056 	return 0;
1057 }
1058 
1059 
1060 /**
1061  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
1062  * @wpa_s: Pointer to wpa_supplicant data
1063  * Returns: 0 is sched_scan was started or -1 otherwise
1064  *
1065  * This function is used to schedule periodic scans for neighboring
1066  * access points repeating the scan continuously.
1067  */
wpa_supplicant_req_sched_scan(struct wpa_supplicant * wpa_s)1068 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
1069 {
1070 	struct wpa_driver_scan_params params;
1071 	struct wpa_driver_scan_params *scan_params;
1072 	enum wpa_states prev_state;
1073 	struct wpa_ssid *ssid = NULL;
1074 	struct wpabuf *extra_ie = NULL;
1075 	int ret;
1076 	unsigned int max_sched_scan_ssids;
1077 	int wildcard = 0;
1078 	int need_ssids;
1079 
1080 	if (!wpa_s->sched_scan_supported)
1081 		return -1;
1082 
1083 	if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
1084 		max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
1085 	else
1086 		max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
1087 	if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload)
1088 		return -1;
1089 
1090 	if (wpa_s->sched_scanning) {
1091 		wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
1092 		return 0;
1093 	}
1094 
1095 	need_ssids = 0;
1096 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1097 		if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
1098 			/* Use wildcard SSID to find this network */
1099 			wildcard = 1;
1100 		} else if (!wpas_network_disabled(wpa_s, ssid) &&
1101 			   ssid->ssid_len)
1102 			need_ssids++;
1103 
1104 #ifdef CONFIG_WPS
1105 		if (!wpas_network_disabled(wpa_s, ssid) &&
1106 		    ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
1107 			/*
1108 			 * Normal scan is more reliable and faster for WPS
1109 			 * operations and since these are for short periods of
1110 			 * time, the benefit of trying to use sched_scan would
1111 			 * be limited.
1112 			 */
1113 			wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1114 				"sched_scan for WPS");
1115 			return -1;
1116 		}
1117 #endif /* CONFIG_WPS */
1118 	}
1119 	if (wildcard)
1120 		need_ssids++;
1121 
1122 	if (wpa_s->normal_scans < 3 &&
1123 	    (need_ssids <= wpa_s->max_scan_ssids ||
1124 	     wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
1125 		/*
1126 		 * When normal scan can speed up operations, use that for the
1127 		 * first operations before starting the sched_scan to allow
1128 		 * user space sleep more. We do this only if the normal scan
1129 		 * has functionality that is suitable for this or if the
1130 		 * sched_scan does not have better support for multiple SSIDs.
1131 		 */
1132 		wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1133 			"sched_scan for initial scans (normal_scans=%d)",
1134 			wpa_s->normal_scans);
1135 		return -1;
1136 	}
1137 
1138 	os_memset(&params, 0, sizeof(params));
1139 
1140 	/* If we can't allocate space for the filters, we just don't filter */
1141 	params.filter_ssids = os_zalloc(wpa_s->max_match_sets *
1142 					sizeof(struct wpa_driver_scan_filter));
1143 
1144 	prev_state = wpa_s->wpa_state;
1145 	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
1146 	    wpa_s->wpa_state == WPA_INACTIVE)
1147 		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
1148 
1149 	if (wpa_s->autoscan_params != NULL) {
1150 		scan_params = wpa_s->autoscan_params;
1151 		goto scan;
1152 	}
1153 
1154 	/* Find the starting point from which to continue scanning */
1155 	ssid = wpa_s->conf->ssid;
1156 	if (wpa_s->prev_sched_ssid) {
1157 		while (ssid) {
1158 			if (ssid == wpa_s->prev_sched_ssid) {
1159 				ssid = ssid->next;
1160 				break;
1161 			}
1162 			ssid = ssid->next;
1163 		}
1164 	}
1165 
1166 	if (!ssid || !wpa_s->prev_sched_ssid) {
1167 		wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
1168 		if (wpa_s->conf->sched_scan_interval)
1169 			wpa_s->sched_scan_interval =
1170 				wpa_s->conf->sched_scan_interval;
1171 		if (wpa_s->sched_scan_interval == 0)
1172 			wpa_s->sched_scan_interval = 10;
1173 		wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1174 		wpa_s->first_sched_scan = 1;
1175 		ssid = wpa_s->conf->ssid;
1176 		wpa_s->prev_sched_ssid = ssid;
1177 	}
1178 
1179 	if (wildcard) {
1180 		wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
1181 		params.num_ssids++;
1182 	}
1183 
1184 	while (ssid) {
1185 		if (wpas_network_disabled(wpa_s, ssid))
1186 			goto next;
1187 
1188 		if (params.num_filter_ssids < wpa_s->max_match_sets &&
1189 		    params.filter_ssids && ssid->ssid && ssid->ssid_len) {
1190 			wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
1191 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1192 			os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
1193 				  ssid->ssid, ssid->ssid_len);
1194 			params.filter_ssids[params.num_filter_ssids].ssid_len =
1195 				ssid->ssid_len;
1196 			params.num_filter_ssids++;
1197 		} else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
1198 		{
1199 			wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
1200 				"filter for sched_scan - drop filter");
1201 			os_free(params.filter_ssids);
1202 			params.filter_ssids = NULL;
1203 			params.num_filter_ssids = 0;
1204 		}
1205 
1206 		if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
1207 			if (params.num_ssids == max_sched_scan_ssids)
1208 				break; /* only room for broadcast SSID */
1209 			wpa_dbg(wpa_s, MSG_DEBUG,
1210 				"add to active scan ssid: %s",
1211 				wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1212 			params.ssids[params.num_ssids].ssid =
1213 				ssid->ssid;
1214 			params.ssids[params.num_ssids].ssid_len =
1215 				ssid->ssid_len;
1216 			params.num_ssids++;
1217 			if (params.num_ssids >= max_sched_scan_ssids) {
1218 				wpa_s->prev_sched_ssid = ssid;
1219 				do {
1220 					ssid = ssid->next;
1221 				} while (ssid &&
1222 					 (wpas_network_disabled(wpa_s, ssid) ||
1223 					  !ssid->scan_ssid));
1224 				break;
1225 			}
1226 		}
1227 
1228 	next:
1229 		wpa_s->prev_sched_ssid = ssid;
1230 		ssid = ssid->next;
1231 	}
1232 
1233 	if (params.num_filter_ssids == 0) {
1234 		os_free(params.filter_ssids);
1235 		params.filter_ssids = NULL;
1236 	}
1237 
1238 	extra_ie = wpa_supplicant_extra_ies(wpa_s);
1239 	if (extra_ie) {
1240 		params.extra_ies = wpabuf_head(extra_ie);
1241 		params.extra_ies_len = wpabuf_len(extra_ie);
1242 	}
1243 
1244 	if (wpa_s->conf->filter_rssi)
1245 		params.filter_rssi = wpa_s->conf->filter_rssi;
1246 
1247 	scan_params = &params;
1248 
1249 scan:
1250 	if (ssid || !wpa_s->first_sched_scan) {
1251 		wpa_dbg(wpa_s, MSG_DEBUG,
1252 			"Starting sched scan: interval %d timeout %d",
1253 			wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout);
1254 	} else {
1255 		wpa_dbg(wpa_s, MSG_DEBUG,
1256 			"Starting sched scan: interval %d (no timeout)",
1257 			wpa_s->sched_scan_interval);
1258 	}
1259 
1260 	wpa_setband_scan_freqs(wpa_s, scan_params);
1261 
1262 	ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params,
1263 					      wpa_s->sched_scan_interval);
1264 	wpabuf_free(extra_ie);
1265 	os_free(params.filter_ssids);
1266 	if (ret) {
1267 		wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
1268 		if (prev_state != wpa_s->wpa_state)
1269 			wpa_supplicant_set_state(wpa_s, prev_state);
1270 		return ret;
1271 	}
1272 
1273 	/* If we have more SSIDs to scan, add a timeout so we scan them too */
1274 	if (ssid || !wpa_s->first_sched_scan) {
1275 		wpa_s->sched_scan_timed_out = 0;
1276 		eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
1277 				       wpa_supplicant_sched_scan_timeout,
1278 				       wpa_s, NULL);
1279 		wpa_s->first_sched_scan = 0;
1280 		wpa_s->sched_scan_timeout /= 2;
1281 		wpa_s->sched_scan_interval *= 2;
1282 		if (wpa_s->sched_scan_timeout < wpa_s->sched_scan_interval) {
1283 			wpa_s->sched_scan_interval = 10;
1284 			wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1285 		}
1286 	}
1287 
1288 	/* If there is no more ssids, start next time from the beginning */
1289 	if (!ssid)
1290 		wpa_s->prev_sched_ssid = NULL;
1291 
1292 	return 0;
1293 }
1294 
1295 
1296 /**
1297  * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
1298  * @wpa_s: Pointer to wpa_supplicant data
1299  *
1300  * This function is used to cancel a scan request scheduled with
1301  * wpa_supplicant_req_scan().
1302  */
wpa_supplicant_cancel_scan(struct wpa_supplicant * wpa_s)1303 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
1304 {
1305 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
1306 	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1307 }
1308 
1309 
1310 /**
1311  * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan
1312  * @wpa_s: Pointer to wpa_supplicant data
1313  *
1314  * This function is used to stop a delayed scheduled scan.
1315  */
wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant * wpa_s)1316 void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s)
1317 {
1318 	if (!wpa_s->sched_scan_supported)
1319 		return;
1320 
1321 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan");
1322 	eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
1323 			     wpa_s, NULL);
1324 }
1325 
1326 
1327 /**
1328  * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
1329  * @wpa_s: Pointer to wpa_supplicant data
1330  *
1331  * This function is used to stop a periodic scheduled scan.
1332  */
wpa_supplicant_cancel_sched_scan(struct wpa_supplicant * wpa_s)1333 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
1334 {
1335 	if (!wpa_s->sched_scanning)
1336 		return;
1337 
1338 	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
1339 	eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
1340 	wpa_supplicant_stop_sched_scan(wpa_s);
1341 }
1342 
1343 
1344 /**
1345  * wpa_supplicant_notify_scanning - Indicate possible scan state change
1346  * @wpa_s: Pointer to wpa_supplicant data
1347  * @scanning: Whether scanning is currently in progress
1348  *
1349  * This function is to generate scanning notifycations. It is called whenever
1350  * there may have been a change in scanning (scan started, completed, stopped).
1351  * wpas_notify_scanning() is called whenever the scanning state changed from the
1352  * previously notified state.
1353  */
wpa_supplicant_notify_scanning(struct wpa_supplicant * wpa_s,int scanning)1354 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
1355 				    int scanning)
1356 {
1357 	if (wpa_s->scanning != scanning) {
1358 		wpa_s->scanning = scanning;
1359 		wpas_notify_scanning(wpa_s);
1360 	}
1361 }
1362 
1363 
wpa_scan_get_max_rate(const struct wpa_scan_res * res)1364 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
1365 {
1366 	int rate = 0;
1367 	const u8 *ie;
1368 	int i;
1369 
1370 	ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
1371 	for (i = 0; ie && i < ie[1]; i++) {
1372 		if ((ie[i + 2] & 0x7f) > rate)
1373 			rate = ie[i + 2] & 0x7f;
1374 	}
1375 
1376 	ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
1377 	for (i = 0; ie && i < ie[1]; i++) {
1378 		if ((ie[i + 2] & 0x7f) > rate)
1379 			rate = ie[i + 2] & 0x7f;
1380 	}
1381 
1382 	return rate;
1383 }
1384 
1385 
1386 /**
1387  * wpa_scan_get_ie - Fetch a specified information element from a scan result
1388  * @res: Scan result entry
1389  * @ie: Information element identitifier (WLAN_EID_*)
1390  * Returns: Pointer to the information element (id field) or %NULL if not found
1391  *
1392  * This function returns the first matching information element in the scan
1393  * result.
1394  */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)1395 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
1396 {
1397 	const u8 *end, *pos;
1398 
1399 	pos = (const u8 *) (res + 1);
1400 	end = pos + res->ie_len;
1401 
1402 	while (pos + 1 < end) {
1403 		if (pos + 2 + pos[1] > end)
1404 			break;
1405 		if (pos[0] == ie)
1406 			return pos;
1407 		pos += 2 + pos[1];
1408 	}
1409 
1410 	return NULL;
1411 }
1412 
1413 
1414 /**
1415  * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result
1416  * @res: Scan result entry
1417  * @vendor_type: Vendor type (four octets starting the IE payload)
1418  * Returns: Pointer to the information element (id field) or %NULL if not found
1419  *
1420  * This function returns the first matching information element in the scan
1421  * result.
1422  */
wpa_scan_get_vendor_ie(const struct wpa_scan_res * res,u32 vendor_type)1423 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
1424 				  u32 vendor_type)
1425 {
1426 	const u8 *end, *pos;
1427 
1428 	pos = (const u8 *) (res + 1);
1429 	end = pos + res->ie_len;
1430 
1431 	while (pos + 1 < end) {
1432 		if (pos + 2 + pos[1] > end)
1433 			break;
1434 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1435 		    vendor_type == WPA_GET_BE32(&pos[2]))
1436 			return pos;
1437 		pos += 2 + pos[1];
1438 	}
1439 
1440 	return NULL;
1441 }
1442 
1443 
1444 /**
1445  * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
1446  * @res: Scan result entry
1447  * @vendor_type: Vendor type (four octets starting the IE payload)
1448  * Returns: Pointer to the information element (id field) or %NULL if not found
1449  *
1450  * This function returns the first matching information element in the scan
1451  * result.
1452  *
1453  * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
1454  * from Beacon frames instead of either Beacon or Probe Response frames.
1455  */
wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res * res,u32 vendor_type)1456 const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
1457 					 u32 vendor_type)
1458 {
1459 	const u8 *end, *pos;
1460 
1461 	if (res->beacon_ie_len == 0)
1462 		return NULL;
1463 
1464 	pos = (const u8 *) (res + 1);
1465 	pos += res->ie_len;
1466 	end = pos + res->beacon_ie_len;
1467 
1468 	while (pos + 1 < end) {
1469 		if (pos + 2 + pos[1] > end)
1470 			break;
1471 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1472 		    vendor_type == WPA_GET_BE32(&pos[2]))
1473 			return pos;
1474 		pos += 2 + pos[1];
1475 	}
1476 
1477 	return NULL;
1478 }
1479 
1480 
1481 /**
1482  * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
1483  * @res: Scan result entry
1484  * @vendor_type: Vendor type (four octets starting the IE payload)
1485  * Returns: Pointer to the information element payload or %NULL if not found
1486  *
1487  * This function returns concatenated payload of possibly fragmented vendor
1488  * specific information elements in the scan result. The caller is responsible
1489  * for freeing the returned buffer.
1490  */
wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res * res,u32 vendor_type)1491 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
1492 					     u32 vendor_type)
1493 {
1494 	struct wpabuf *buf;
1495 	const u8 *end, *pos;
1496 
1497 	buf = wpabuf_alloc(res->ie_len);
1498 	if (buf == NULL)
1499 		return NULL;
1500 
1501 	pos = (const u8 *) (res + 1);
1502 	end = pos + res->ie_len;
1503 
1504 	while (pos + 1 < end) {
1505 		if (pos + 2 + pos[1] > end)
1506 			break;
1507 		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1508 		    vendor_type == WPA_GET_BE32(&pos[2]))
1509 			wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
1510 		pos += 2 + pos[1];
1511 	}
1512 
1513 	if (wpabuf_len(buf) == 0) {
1514 		wpabuf_free(buf);
1515 		buf = NULL;
1516 	}
1517 
1518 	return buf;
1519 }
1520 
1521 
1522 /*
1523  * Channels with a great SNR can operate at full rate. What is a great SNR?
1524  * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
1525  * rule of thumb is that any SNR above 20 is good." This one
1526  * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
1527  * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a
1528  * conservative value.
1529  */
1530 #define GREAT_SNR 30
1531 
1532 /* Compare function for sorting scan results. Return >0 if @b is considered
1533  * better. */
wpa_scan_result_compar(const void * a,const void * b)1534 static int wpa_scan_result_compar(const void *a, const void *b)
1535 {
1536 #define IS_5GHZ(n) (n > 4000)
1537 #define MIN(a,b) a < b ? a : b
1538 	struct wpa_scan_res **_wa = (void *) a;
1539 	struct wpa_scan_res **_wb = (void *) b;
1540 	struct wpa_scan_res *wa = *_wa;
1541 	struct wpa_scan_res *wb = *_wb;
1542 	int wpa_a, wpa_b, maxrate_a, maxrate_b;
1543 	int snr_a, snr_b;
1544 
1545 	/* WPA/WPA2 support preferred */
1546 	wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
1547 		wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
1548 	wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
1549 		wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
1550 
1551 	if (wpa_b && !wpa_a)
1552 		return 1;
1553 	if (!wpa_b && wpa_a)
1554 		return -1;
1555 
1556 	/* privacy support preferred */
1557 	if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
1558 	    (wb->caps & IEEE80211_CAP_PRIVACY))
1559 		return 1;
1560 	if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
1561 	    (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
1562 		return -1;
1563 
1564 	if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) &&
1565 	    !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) {
1566 		snr_a = MIN(wa->level - wa->noise, GREAT_SNR);
1567 		snr_b = MIN(wb->level - wb->noise, GREAT_SNR);
1568 	} else {
1569 		/* Not suitable information to calculate SNR, so use level */
1570 		snr_a = wa->level;
1571 		snr_b = wb->level;
1572 	}
1573 
1574 	/* best/max rate preferred if SNR close enough */
1575         if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
1576 	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
1577 		maxrate_a = wpa_scan_get_max_rate(wa);
1578 		maxrate_b = wpa_scan_get_max_rate(wb);
1579 		if (maxrate_a != maxrate_b)
1580 			return maxrate_b - maxrate_a;
1581 		if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
1582 			return IS_5GHZ(wa->freq) ? -1 : 1;
1583 	}
1584 
1585 	/* use freq for channel preference */
1586 
1587 	/* all things being equal, use SNR; if SNRs are
1588 	 * identical, use quality values since some drivers may only report
1589 	 * that value and leave the signal level zero */
1590 	if (snr_b == snr_a)
1591 		return wb->qual - wa->qual;
1592 	return snr_b - snr_a;
1593 #undef MIN
1594 #undef IS_5GHZ
1595 }
1596 
1597 
1598 #ifdef CONFIG_WPS
1599 /* Compare function for sorting scan results when searching a WPS AP for
1600  * provisioning. Return >0 if @b is considered better. */
wpa_scan_result_wps_compar(const void * a,const void * b)1601 static int wpa_scan_result_wps_compar(const void *a, const void *b)
1602 {
1603 	struct wpa_scan_res **_wa = (void *) a;
1604 	struct wpa_scan_res **_wb = (void *) b;
1605 	struct wpa_scan_res *wa = *_wa;
1606 	struct wpa_scan_res *wb = *_wb;
1607 	int uses_wps_a, uses_wps_b;
1608 	struct wpabuf *wps_a, *wps_b;
1609 	int res;
1610 
1611 	/* Optimization - check WPS IE existence before allocated memory and
1612 	 * doing full reassembly. */
1613 	uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
1614 	uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
1615 	if (uses_wps_a && !uses_wps_b)
1616 		return -1;
1617 	if (!uses_wps_a && uses_wps_b)
1618 		return 1;
1619 
1620 	if (uses_wps_a && uses_wps_b) {
1621 		wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
1622 		wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
1623 		res = wps_ap_priority_compar(wps_a, wps_b);
1624 		wpabuf_free(wps_a);
1625 		wpabuf_free(wps_b);
1626 		if (res)
1627 			return res;
1628 	}
1629 
1630 	/*
1631 	 * Do not use current AP security policy as a sorting criteria during
1632 	 * WPS provisioning step since the AP may get reconfigured at the
1633 	 * completion of provisioning.
1634 	 */
1635 
1636 	/* all things being equal, use signal level; if signal levels are
1637 	 * identical, use quality values since some drivers may only report
1638 	 * that value and leave the signal level zero */
1639 	if (wb->level == wa->level)
1640 		return wb->qual - wa->qual;
1641 	return wb->level - wa->level;
1642 }
1643 #endif /* CONFIG_WPS */
1644 
1645 
dump_scan_res(struct wpa_scan_results * scan_res)1646 static void dump_scan_res(struct wpa_scan_results *scan_res)
1647 {
1648 #ifndef CONFIG_NO_STDOUT_DEBUG
1649 	size_t i;
1650 
1651 	if (scan_res->res == NULL || scan_res->num == 0)
1652 		return;
1653 
1654 	wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
1655 
1656 	for (i = 0; i < scan_res->num; i++) {
1657 		struct wpa_scan_res *r = scan_res->res[i];
1658 		u8 *pos;
1659 		if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID))
1660 		    == WPA_SCAN_LEVEL_DBM) {
1661 			int snr = r->level - r->noise;
1662 			wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
1663 				   "noise=%d level=%d snr=%d%s flags=0x%x "
1664 				   "age=%u",
1665 				   MAC2STR(r->bssid), r->freq, r->qual,
1666 				   r->noise, r->level, snr,
1667 				   snr >= GREAT_SNR ? "*" : "", r->flags,
1668 				   r->age);
1669 		} else {
1670 			wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
1671 				   "noise=%d level=%d flags=0x%x age=%u",
1672 				   MAC2STR(r->bssid), r->freq, r->qual,
1673 				   r->noise, r->level, r->flags, r->age);
1674 		}
1675 		pos = (u8 *) (r + 1);
1676 		if (r->ie_len)
1677 			wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len);
1678 		pos += r->ie_len;
1679 		if (r->beacon_ie_len)
1680 			wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs",
1681 				    pos, r->beacon_ie_len);
1682 	}
1683 #endif /* CONFIG_NO_STDOUT_DEBUG */
1684 }
1685 
1686 
1687 /**
1688  * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed
1689  * @wpa_s: Pointer to wpa_supplicant data
1690  * @bssid: BSSID to check
1691  * Returns: 0 if the BSSID is filtered or 1 if not
1692  *
1693  * This function is used to filter out specific BSSIDs from scan reslts mainly
1694  * for testing purposes (SET bssid_filter ctrl_iface command).
1695  */
wpa_supplicant_filter_bssid_match(struct wpa_supplicant * wpa_s,const u8 * bssid)1696 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
1697 				      const u8 *bssid)
1698 {
1699 	size_t i;
1700 
1701 	if (wpa_s->bssid_filter == NULL)
1702 		return 1;
1703 
1704 	for (i = 0; i < wpa_s->bssid_filter_count; i++) {
1705 		if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
1706 			      ETH_ALEN) == 0)
1707 			return 1;
1708 	}
1709 
1710 	return 0;
1711 }
1712 
1713 
filter_scan_res(struct wpa_supplicant * wpa_s,struct wpa_scan_results * res)1714 static void filter_scan_res(struct wpa_supplicant *wpa_s,
1715 			    struct wpa_scan_results *res)
1716 {
1717 	size_t i, j;
1718 
1719 	if (wpa_s->bssid_filter == NULL)
1720 		return;
1721 
1722 	for (i = 0, j = 0; i < res->num; i++) {
1723 		if (wpa_supplicant_filter_bssid_match(wpa_s,
1724 						      res->res[i]->bssid)) {
1725 			res->res[j++] = res->res[i];
1726 		} else {
1727 			os_free(res->res[i]);
1728 			res->res[i] = NULL;
1729 		}
1730 	}
1731 
1732 	if (res->num != j) {
1733 		wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
1734 			   (int) (res->num - j));
1735 		res->num = j;
1736 	}
1737 }
1738 
1739 
1740 /**
1741  * wpa_supplicant_get_scan_results - Get scan results
1742  * @wpa_s: Pointer to wpa_supplicant data
1743  * @info: Information about what was scanned or %NULL if not available
1744  * @new_scan: Whether a new scan was performed
1745  * Returns: Scan results, %NULL on failure
1746  *
1747  * This function request the current scan results from the driver and updates
1748  * the local BSS list wpa_s->bss. The caller is responsible for freeing the
1749  * results with wpa_scan_results_free().
1750  */
1751 struct wpa_scan_results *
wpa_supplicant_get_scan_results(struct wpa_supplicant * wpa_s,struct scan_info * info,int new_scan)1752 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
1753 				struct scan_info *info, int new_scan)
1754 {
1755 	struct wpa_scan_results *scan_res;
1756 	size_t i;
1757 	int (*compar)(const void *, const void *) = wpa_scan_result_compar;
1758 
1759 	scan_res = wpa_drv_get_scan_results2(wpa_s);
1760 	if (scan_res == NULL) {
1761 		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
1762 		return NULL;
1763 	}
1764 	if (scan_res->fetch_time.sec == 0) {
1765 		/*
1766 		 * Make sure we have a valid timestamp if the driver wrapper
1767 		 * does not set this.
1768 		 */
1769 		os_get_reltime(&scan_res->fetch_time);
1770 	}
1771 	filter_scan_res(wpa_s, scan_res);
1772 
1773 #ifdef CONFIG_WPS
1774 	if (wpas_wps_searching(wpa_s)) {
1775 		wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
1776 			"provisioning rules");
1777 		compar = wpa_scan_result_wps_compar;
1778 	}
1779 #endif /* CONFIG_WPS */
1780 
1781 	qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *),
1782 	      compar);
1783 	dump_scan_res(scan_res);
1784 
1785 	wpa_bss_update_start(wpa_s);
1786 	for (i = 0; i < scan_res->num; i++)
1787 		wpa_bss_update_scan_res(wpa_s, scan_res->res[i],
1788 					&scan_res->fetch_time);
1789 	wpa_bss_update_end(wpa_s, info, new_scan);
1790 
1791 	return scan_res;
1792 }
1793 
1794 
1795 /**
1796  * wpa_supplicant_update_scan_results - Update scan results from the driver
1797  * @wpa_s: Pointer to wpa_supplicant data
1798  * Returns: 0 on success, -1 on failure
1799  *
1800  * This function updates the BSS table within wpa_supplicant based on the
1801  * currently available scan results from the driver without requesting a new
1802  * scan. This is used in cases where the driver indicates an association
1803  * (including roaming within ESS) and wpa_supplicant does not yet have the
1804  * needed information to complete the connection (e.g., to perform validation
1805  * steps in 4-way handshake).
1806  */
wpa_supplicant_update_scan_results(struct wpa_supplicant * wpa_s)1807 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
1808 {
1809 	struct wpa_scan_results *scan_res;
1810 	scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1811 	if (scan_res == NULL)
1812 		return -1;
1813 	wpa_scan_results_free(scan_res);
1814 
1815 	return 0;
1816 }
1817 
1818 
1819 /**
1820  * scan_only_handler - Reports scan results
1821  */
scan_only_handler(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)1822 void scan_only_handler(struct wpa_supplicant *wpa_s,
1823 		       struct wpa_scan_results *scan_res)
1824 {
1825 	wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received");
1826 	if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1827 	    wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
1828 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
1829 			     wpa_s->manual_scan_id);
1830 		wpa_s->manual_scan_use_id = 0;
1831 	} else {
1832 		wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
1833 	}
1834 	wpas_notify_scan_results(wpa_s);
1835 	wpas_notify_scan_done(wpa_s, 1);
1836 	if (wpa_s->scan_work) {
1837 		struct wpa_radio_work *work = wpa_s->scan_work;
1838 		wpa_s->scan_work = NULL;
1839 		radio_work_done(work);
1840 	}
1841 }
1842 
1843 
wpas_scan_scheduled(struct wpa_supplicant * wpa_s)1844 int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
1845 {
1846 	return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
1847 }
1848 
1849 
1850 struct wpa_driver_scan_params *
wpa_scan_clone_params(const struct wpa_driver_scan_params * src)1851 wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
1852 {
1853 	struct wpa_driver_scan_params *params;
1854 	size_t i;
1855 	u8 *n;
1856 
1857 	params = os_zalloc(sizeof(*params));
1858 	if (params == NULL)
1859 		return NULL;
1860 
1861 	for (i = 0; i < src->num_ssids; i++) {
1862 		if (src->ssids[i].ssid) {
1863 			n = os_malloc(src->ssids[i].ssid_len);
1864 			if (n == NULL)
1865 				goto failed;
1866 			os_memcpy(n, src->ssids[i].ssid,
1867 				  src->ssids[i].ssid_len);
1868 			params->ssids[i].ssid = n;
1869 			params->ssids[i].ssid_len = src->ssids[i].ssid_len;
1870 		}
1871 	}
1872 	params->num_ssids = src->num_ssids;
1873 
1874 	if (src->extra_ies) {
1875 		n = os_malloc(src->extra_ies_len);
1876 		if (n == NULL)
1877 			goto failed;
1878 		os_memcpy(n, src->extra_ies, src->extra_ies_len);
1879 		params->extra_ies = n;
1880 		params->extra_ies_len = src->extra_ies_len;
1881 	}
1882 
1883 	if (src->freqs) {
1884 		int len = int_array_len(src->freqs);
1885 		params->freqs = os_malloc((len + 1) * sizeof(int));
1886 		if (params->freqs == NULL)
1887 			goto failed;
1888 		os_memcpy(params->freqs, src->freqs, (len + 1) * sizeof(int));
1889 	}
1890 
1891 	if (src->filter_ssids) {
1892 		params->filter_ssids = os_malloc(sizeof(*params->filter_ssids) *
1893 						 src->num_filter_ssids);
1894 		if (params->filter_ssids == NULL)
1895 			goto failed;
1896 		os_memcpy(params->filter_ssids, src->filter_ssids,
1897 			  sizeof(*params->filter_ssids) *
1898 			  src->num_filter_ssids);
1899 		params->num_filter_ssids = src->num_filter_ssids;
1900 	}
1901 
1902 	params->filter_rssi = src->filter_rssi;
1903 	params->p2p_probe = src->p2p_probe;
1904 	params->only_new_results = src->only_new_results;
1905 	params->low_priority = src->low_priority;
1906 
1907 	return params;
1908 
1909 failed:
1910 	wpa_scan_free_params(params);
1911 	return NULL;
1912 }
1913 
1914 
wpa_scan_free_params(struct wpa_driver_scan_params * params)1915 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
1916 {
1917 	size_t i;
1918 
1919 	if (params == NULL)
1920 		return;
1921 
1922 	for (i = 0; i < params->num_ssids; i++)
1923 		os_free((u8 *) params->ssids[i].ssid);
1924 	os_free((u8 *) params->extra_ies);
1925 	os_free(params->freqs);
1926 	os_free(params->filter_ssids);
1927 	os_free(params);
1928 }
1929 
1930 
wpas_start_pno(struct wpa_supplicant * wpa_s)1931 int wpas_start_pno(struct wpa_supplicant *wpa_s)
1932 {
1933 	int ret, interval;
1934 	size_t i, num_ssid, num_match_ssid;
1935 	struct wpa_ssid *ssid;
1936 	struct wpa_driver_scan_params params;
1937 
1938 	if (!wpa_s->sched_scan_supported)
1939 		return -1;
1940 
1941 	if (wpa_s->pno || wpa_s->pno_sched_pending)
1942 		return 0;
1943 
1944 	if ((wpa_s->wpa_state > WPA_SCANNING) &&
1945 	    (wpa_s->wpa_state <= WPA_COMPLETED)) {
1946 		wpa_printf(MSG_ERROR, "PNO: In assoc process");
1947 		return -EAGAIN;
1948 	}
1949 
1950 	if (wpa_s->wpa_state == WPA_SCANNING) {
1951 		wpa_supplicant_cancel_scan(wpa_s);
1952 		if (wpa_s->sched_scanning) {
1953 			wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
1954 				   "ongoing sched scan");
1955 			wpa_supplicant_cancel_sched_scan(wpa_s);
1956 			wpa_s->pno_sched_pending = 1;
1957 			return 0;
1958 		}
1959 	}
1960 
1961 	os_memset(&params, 0, sizeof(params));
1962 
1963 	num_ssid = num_match_ssid = 0;
1964 	ssid = wpa_s->conf->ssid;
1965 	while (ssid) {
1966 		if (!wpas_network_disabled(wpa_s, ssid)) {
1967 			num_match_ssid++;
1968 			if (ssid->scan_ssid)
1969 				num_ssid++;
1970 		}
1971 		ssid = ssid->next;
1972 	}
1973 
1974 	if (num_match_ssid == 0) {
1975 		wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
1976 		return -1;
1977 	}
1978 
1979 	if (num_match_ssid > num_ssid) {
1980 		params.num_ssids++; /* wildcard */
1981 		num_ssid++;
1982 	}
1983 
1984 	if (num_ssid > WPAS_MAX_SCAN_SSIDS) {
1985 		wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
1986 			   "%u", WPAS_MAX_SCAN_SSIDS, (unsigned int) num_ssid);
1987 		num_ssid = WPAS_MAX_SCAN_SSIDS;
1988 	}
1989 
1990 	if (num_match_ssid > wpa_s->max_match_sets) {
1991 		num_match_ssid = wpa_s->max_match_sets;
1992 		wpa_dbg(wpa_s, MSG_DEBUG, "PNO: Too many SSIDs to match");
1993 	}
1994 	params.filter_ssids = os_calloc(num_match_ssid,
1995 					sizeof(struct wpa_driver_scan_filter));
1996 	if (params.filter_ssids == NULL)
1997 		return -1;
1998 	i = 0;
1999 	ssid = wpa_s->conf->ssid;
2000 	while (ssid) {
2001 		if (!wpas_network_disabled(wpa_s, ssid)) {
2002 			if (ssid->scan_ssid && params.num_ssids < num_ssid) {
2003 				params.ssids[params.num_ssids].ssid =
2004 					ssid->ssid;
2005 				params.ssids[params.num_ssids].ssid_len =
2006 					 ssid->ssid_len;
2007 				params.num_ssids++;
2008 			}
2009 			os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
2010 				  ssid->ssid_len);
2011 			params.filter_ssids[i].ssid_len = ssid->ssid_len;
2012 			params.num_filter_ssids++;
2013 			i++;
2014 			if (i == num_match_ssid)
2015 				break;
2016 		}
2017 		ssid = ssid->next;
2018 	}
2019 
2020 	if (wpa_s->conf->filter_rssi)
2021 		params.filter_rssi = wpa_s->conf->filter_rssi;
2022 
2023 	interval = wpa_s->conf->sched_scan_interval ?
2024 		wpa_s->conf->sched_scan_interval : 10;
2025 
2026 	if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) {
2027 		wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels");
2028 		params.freqs = wpa_s->manual_sched_scan_freqs;
2029 	}
2030 
2031 	ret = wpa_supplicant_start_sched_scan(wpa_s, &params, interval);
2032 	os_free(params.filter_ssids);
2033 	if (ret == 0)
2034 		wpa_s->pno = 1;
2035 	else
2036 		wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
2037 	return ret;
2038 }
2039 
2040 
wpas_stop_pno(struct wpa_supplicant * wpa_s)2041 int wpas_stop_pno(struct wpa_supplicant *wpa_s)
2042 {
2043 	int ret = 0;
2044 
2045 	if (!wpa_s->pno)
2046 		return 0;
2047 
2048 	ret = wpa_supplicant_stop_sched_scan(wpa_s);
2049 
2050 	wpa_s->pno = 0;
2051 	wpa_s->pno_sched_pending = 0;
2052 
2053 	if (wpa_s->wpa_state == WPA_SCANNING)
2054 		wpa_supplicant_req_scan(wpa_s, 0, 0);
2055 
2056 	return ret;
2057 }
2058