xref: /dragonfly/contrib/wpa_supplicant/wpa_supplicant/scan.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
1 /*
2  * WPA Supplicant - Scanning
3  * Copyright (c) 2003-2019, 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 #include "mesh.h"
26 
27 
wpa_supplicant_gen_assoc_event(struct wpa_supplicant * wpa_s)28 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
29 {
30           struct wpa_ssid *ssid;
31           union wpa_event_data data;
32 
33           ssid = wpa_supplicant_get_ssid(wpa_s);
34           if (ssid == NULL)
35                     return;
36 
37           if (wpa_s->current_ssid == NULL) {
38                     wpa_s->current_ssid = ssid;
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 && os_strstr(ssid->eap.phase1, "pbc=1"))
63                               return 2;
64           }
65 
66 #ifdef CONFIG_P2P
67           if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p &&
68               !wpa_s->conf->p2p_disabled) {
69                     wpa_s->wps->dev.p2p = 1;
70                     if (!wps) {
71                               wps = 1;
72                               *req_type = WPS_REQ_ENROLLEE_INFO;
73                     }
74           }
75 #endif /* CONFIG_P2P */
76 
77           return wps;
78 }
79 #endif /* CONFIG_WPS */
80 
81 
82 /**
83  * wpa_supplicant_enabled_networks - Check whether there are enabled networks
84  * @wpa_s: Pointer to wpa_supplicant data
85  * Returns: 0 if no networks are enabled, >0 if networks are enabled
86  *
87  * This function is used to figure out whether any networks (or Interworking
88  * with enabled credentials and auto_interworking) are present in the current
89  * configuration.
90  */
wpa_supplicant_enabled_networks(struct wpa_supplicant * wpa_s)91 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
92 {
93           struct wpa_ssid *ssid = wpa_s->conf->ssid;
94           int count = 0, disabled = 0;
95 
96           if (wpa_s->p2p_mgmt)
97                     return 0; /* no normal network profiles on p2p_mgmt interface */
98 
99           while (ssid) {
100                     if (!wpas_network_disabled(wpa_s, ssid))
101                               count++;
102                     else
103                               disabled++;
104                     ssid = ssid->next;
105           }
106           if (wpa_s->conf->cred && wpa_s->conf->interworking &&
107               wpa_s->conf->auto_interworking)
108                     count++;
109           if (count == 0 && disabled > 0) {
110                     wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled "
111                               "networks)", disabled);
112           }
113           return count;
114 }
115 
116 
wpa_supplicant_assoc_try(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid)117 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
118                                              struct wpa_ssid *ssid)
119 {
120           int min_temp_disabled = 0;
121 
122           while (ssid) {
123                     if (!wpas_network_disabled(wpa_s, ssid)) {
124                               int temp_disabled = wpas_temp_disabled(wpa_s, ssid);
125 
126                               if (temp_disabled <= 0)
127                                         break;
128 
129                               if (!min_temp_disabled ||
130                                   temp_disabled < min_temp_disabled)
131                                         min_temp_disabled = temp_disabled;
132                     }
133                     ssid = ssid->next;
134           }
135 
136           /* ap_scan=2 mode - try to associate with each SSID. */
137           if (ssid == NULL) {
138                     wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached "
139                               "end of scan list - go back to beginning");
140                     wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
141                     wpa_supplicant_req_scan(wpa_s, min_temp_disabled, 0);
142                     return;
143           }
144           if (ssid->next) {
145                     /* Continue from the next SSID on the next attempt. */
146                     wpa_s->prev_scan_ssid = ssid;
147           } else {
148                     /* Start from the beginning of the SSID list. */
149                     wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
150           }
151           wpa_supplicant_associate(wpa_s, NULL, ssid);
152 }
153 
154 
wpas_trigger_scan_cb(struct wpa_radio_work * work,int deinit)155 static void wpas_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
156 {
157           struct wpa_supplicant *wpa_s = work->wpa_s;
158           struct wpa_driver_scan_params *params = work->ctx;
159           int ret;
160 
161           if (deinit) {
162                     if (!work->started) {
163                               wpa_scan_free_params(params);
164                               return;
165                     }
166                     wpa_supplicant_notify_scanning(wpa_s, 0);
167                     wpas_notify_scan_done(wpa_s, 0);
168                     wpa_s->scan_work = NULL;
169                     return;
170           }
171 
172           if (wpas_update_random_addr_disassoc(wpa_s) < 0) {
173                     wpa_msg(wpa_s, MSG_INFO,
174                               "Failed to assign random MAC address for a scan");
175                     wpa_scan_free_params(params);
176                     wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
177                     radio_work_done(work);
178                     return;
179           }
180 
181           wpa_supplicant_notify_scanning(wpa_s, 1);
182 
183           if (wpa_s->clear_driver_scan_cache) {
184                     wpa_printf(MSG_DEBUG,
185                                  "Request driver to clear scan cache due to local BSS flush");
186                     params->only_new_results = 1;
187           }
188           ret = wpa_drv_scan(wpa_s, params);
189           /*
190            * Store the obtained vendor scan cookie (if any) in wpa_s context.
191            * The current design is to allow only one scan request on each
192            * interface, hence having this scan cookie stored in wpa_s context is
193            * fine for now.
194            *
195            * Revisit this logic if concurrent scan operations per interface
196            * is supported.
197            */
198           if (ret == 0)
199                     wpa_s->curr_scan_cookie = params->scan_cookie;
200           wpa_scan_free_params(params);
201           work->ctx = NULL;
202           if (ret) {
203                     int retry = wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
204                               !wpa_s->beacon_rep_data.token;
205 
206                     if (wpa_s->disconnected)
207                               retry = 0;
208 
209                     wpa_supplicant_notify_scanning(wpa_s, 0);
210                     wpas_notify_scan_done(wpa_s, 0);
211                     if (wpa_s->wpa_state == WPA_SCANNING)
212                               wpa_supplicant_set_state(wpa_s,
213                                                              wpa_s->scan_prev_wpa_state);
214                     wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=%d%s",
215                               ret, retry ? " retry=1" : "");
216                     radio_work_done(work);
217 
218                     if (retry) {
219                               /* Restore scan_req since we will try to scan again */
220                               wpa_s->scan_req = wpa_s->last_scan_req;
221                               wpa_supplicant_req_scan(wpa_s, 1, 0);
222                     } else if (wpa_s->scan_res_handler) {
223                               /* Clear the scan_res_handler */
224                               wpa_s->scan_res_handler = NULL;
225                     }
226 
227                     if (wpa_s->beacon_rep_data.token)
228                               wpas_rrm_refuse_request(wpa_s);
229 
230                     return;
231           }
232 
233           os_get_reltime(&wpa_s->scan_trigger_time);
234           wpa_s->scan_runs++;
235           wpa_s->normal_scans++;
236           wpa_s->own_scan_requested = 1;
237           wpa_s->clear_driver_scan_cache = 0;
238           wpa_s->scan_work = work;
239 }
240 
241 
242 /**
243  * wpa_supplicant_trigger_scan - Request driver to start a scan
244  * @wpa_s: Pointer to wpa_supplicant data
245  * @params: Scan parameters
246  * Returns: 0 on success, -1 on failure
247  */
wpa_supplicant_trigger_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)248 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
249                                         struct wpa_driver_scan_params *params)
250 {
251           struct wpa_driver_scan_params *ctx;
252 
253           if (wpa_s->scan_work) {
254                     wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending");
255                     return -1;
256           }
257 
258           ctx = wpa_scan_clone_params(params);
259           if (!ctx ||
260               radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
261           {
262                     wpa_scan_free_params(ctx);
263                     wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_FAILED "ret=-1");
264                     return -1;
265           }
266 
267           return 0;
268 }
269 
270 
271 static void
wpa_supplicant_delayed_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)272 wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
273 {
274           struct wpa_supplicant *wpa_s = eloop_ctx;
275 
276           wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan");
277 
278           if (wpa_supplicant_req_sched_scan(wpa_s))
279                     wpa_supplicant_req_scan(wpa_s, 0, 0);
280 }
281 
282 
283 static void
wpa_supplicant_sched_scan_timeout(void * eloop_ctx,void * timeout_ctx)284 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx)
285 {
286           struct wpa_supplicant *wpa_s = eloop_ctx;
287 
288           wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it");
289 
290           wpa_s->sched_scan_timed_out = 1;
291           wpa_supplicant_cancel_sched_scan(wpa_s);
292 }
293 
294 
295 static int
wpa_supplicant_start_sched_scan(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)296 wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s,
297                                         struct wpa_driver_scan_params *params)
298 {
299           int ret;
300 
301           wpa_supplicant_notify_scanning(wpa_s, 1);
302           ret = wpa_drv_sched_scan(wpa_s, params);
303           if (ret)
304                     wpa_supplicant_notify_scanning(wpa_s, 0);
305           else
306                     wpa_s->sched_scanning = 1;
307 
308           return ret;
309 }
310 
311 
wpa_supplicant_stop_sched_scan(struct wpa_supplicant * wpa_s)312 static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s)
313 {
314           int ret;
315 
316           ret = wpa_drv_stop_sched_scan(wpa_s);
317           if (ret) {
318                     wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!");
319                     /* TODO: what to do if stopping fails? */
320                     return -1;
321           }
322 
323           return ret;
324 }
325 
326 
327 static struct wpa_driver_scan_filter *
wpa_supplicant_build_filter_ssids(struct wpa_config * conf,size_t * num_ssids)328 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
329 {
330           struct wpa_driver_scan_filter *ssids;
331           struct wpa_ssid *ssid;
332           size_t count;
333 
334           *num_ssids = 0;
335           if (!conf->filter_ssids)
336                     return NULL;
337 
338           for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
339                     if (ssid->ssid && ssid->ssid_len)
340                               count++;
341           }
342           if (count == 0)
343                     return NULL;
344           ssids = os_calloc(count, sizeof(struct wpa_driver_scan_filter));
345           if (ssids == NULL)
346                     return NULL;
347 
348           for (ssid = conf->ssid; ssid; ssid = ssid->next) {
349                     if (!ssid->ssid || !ssid->ssid_len)
350                               continue;
351                     os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
352                     ssids[*num_ssids].ssid_len = ssid->ssid_len;
353                     (*num_ssids)++;
354           }
355 
356           return ssids;
357 }
358 
359 
wpa_supplicant_optimize_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)360 static void wpa_supplicant_optimize_freqs(
361           struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params)
362 {
363 #ifdef CONFIG_P2P
364           if (params->freqs == NULL && wpa_s->p2p_in_provisioning &&
365               wpa_s->go_params) {
366                     /* Optimize provisioning state scan based on GO information */
367                     if (wpa_s->p2p_in_provisioning < 5 &&
368                         wpa_s->go_params->freq > 0) {
369                               wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO "
370                                         "preferred frequency %d MHz",
371                                         wpa_s->go_params->freq);
372                               params->freqs = os_calloc(2, sizeof(int));
373                               if (params->freqs)
374                                         params->freqs[0] = wpa_s->go_params->freq;
375                     } else if (wpa_s->p2p_in_provisioning < 8 &&
376                                  wpa_s->go_params->freq_list[0]) {
377                               wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common "
378                                         "channels");
379                               int_array_concat(&params->freqs,
380                                                    wpa_s->go_params->freq_list);
381                               if (params->freqs)
382                                         int_array_sort_unique(params->freqs);
383                     }
384                     wpa_s->p2p_in_provisioning++;
385           }
386 
387           if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
388                     /*
389                      * Optimize scan based on GO information during persistent
390                      * group reinvocation
391                      */
392                     if (wpa_s->p2p_in_invitation < 5 &&
393                         wpa_s->p2p_invite_go_freq > 0) {
394                               wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
395                                         wpa_s->p2p_invite_go_freq);
396                               params->freqs = os_calloc(2, sizeof(int));
397                               if (params->freqs)
398                                         params->freqs[0] = wpa_s->p2p_invite_go_freq;
399                     }
400                     wpa_s->p2p_in_invitation++;
401                     if (wpa_s->p2p_in_invitation > 20) {
402                               /*
403                                * This should not really happen since the variable is
404                                * cleared on group removal, but if it does happen, make
405                                * sure we do not get stuck in special invitation scan
406                                * mode.
407                                */
408                               wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
409                               wpa_s->p2p_in_invitation = 0;
410                     }
411           }
412 #endif /* CONFIG_P2P */
413 
414 #ifdef CONFIG_WPS
415           if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) {
416                     /*
417                      * Optimize post-provisioning scan based on channel used
418                      * during provisioning.
419                      */
420                     wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz "
421                               "that was used during provisioning", wpa_s->wps_freq);
422                     params->freqs = os_calloc(2, sizeof(int));
423                     if (params->freqs)
424                               params->freqs[0] = wpa_s->wps_freq;
425                     wpa_s->after_wps--;
426           } else if (wpa_s->after_wps)
427                     wpa_s->after_wps--;
428 
429           if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq)
430           {
431                     /* Optimize provisioning scan based on already known channel */
432                     wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz",
433                               wpa_s->wps_freq);
434                     params->freqs = os_calloc(2, sizeof(int));
435                     if (params->freqs)
436                               params->freqs[0] = wpa_s->wps_freq;
437                     wpa_s->known_wps_freq = 0; /* only do this once */
438           }
439 #endif /* CONFIG_WPS */
440 }
441 
442 
443 #ifdef CONFIG_INTERWORKING
wpas_add_interworking_elements(struct wpa_supplicant * wpa_s,struct wpabuf * buf)444 static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
445                                                      struct wpabuf *buf)
446 {
447           wpabuf_put_u8(buf, WLAN_EID_INTERWORKING);
448           wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 :
449                           1 + ETH_ALEN);
450           wpabuf_put_u8(buf, wpa_s->conf->access_network_type);
451           /* No Venue Info */
452           if (!is_zero_ether_addr(wpa_s->conf->hessid))
453                     wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN);
454 }
455 #endif /* CONFIG_INTERWORKING */
456 
457 
458 #ifdef CONFIG_MBO
wpas_fils_req_param_add_max_channel(struct wpa_supplicant * wpa_s,struct wpabuf ** ie)459 static void wpas_fils_req_param_add_max_channel(struct wpa_supplicant *wpa_s,
460                                                             struct wpabuf **ie)
461 {
462           if (wpabuf_resize(ie, 5)) {
463                     wpa_printf(MSG_DEBUG,
464                                  "Failed to allocate space for FILS Request Parameters element");
465                     return;
466           }
467 
468           /* FILS Request Parameters element */
469           wpabuf_put_u8(*ie, WLAN_EID_EXTENSION);
470           wpabuf_put_u8(*ie, 3); /* FILS Request attribute length */
471           wpabuf_put_u8(*ie, WLAN_EID_EXT_FILS_REQ_PARAMS);
472           /* Parameter control bitmap */
473           wpabuf_put_u8(*ie, 0);
474           /* Max Channel Time field - contains the value of MaxChannelTime
475            * parameter of the MLME-SCAN.request primitive represented in units of
476            * TUs, as an unsigned integer. A Max Channel Time field value of 255
477            * is used to indicate any duration of more than 254 TUs, or an
478            * unspecified or unknown duration. (IEEE Std 802.11ai-2016, 9.4.2.178)
479            */
480           wpabuf_put_u8(*ie, 255);
481 }
482 #endif /* CONFIG_MBO */
483 
484 
wpa_supplicant_set_default_scan_ies(struct wpa_supplicant * wpa_s)485 void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
486 {
487           struct wpabuf *default_ies = NULL;
488           u8 ext_capab[18];
489           int ext_capab_len;
490           enum wpa_driver_if_type type = WPA_IF_STATION;
491 
492 #ifdef CONFIG_P2P
493           if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
494                     type = WPA_IF_P2P_CLIENT;
495 #endif /* CONFIG_P2P */
496 
497           wpa_drv_get_ext_capa(wpa_s, type);
498 
499           ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
500                                                        sizeof(ext_capab));
501           if (ext_capab_len > 0 &&
502               wpabuf_resize(&default_ies, ext_capab_len) == 0)
503                     wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
504 
505 #ifdef CONFIG_MBO
506           if (wpa_s->enable_oce & OCE_STA)
507                     wpas_fils_req_param_add_max_channel(wpa_s, &default_ies);
508           /* Send MBO and OCE capabilities */
509           if (wpabuf_resize(&default_ies, 12) == 0)
510                     wpas_mbo_scan_ie(wpa_s, default_ies);
511 #endif /* CONFIG_MBO */
512 
513           if (default_ies)
514                     wpa_drv_set_default_scan_ies(wpa_s, wpabuf_head(default_ies),
515                                                        wpabuf_len(default_ies));
516           wpabuf_free(default_ies);
517 }
518 
519 
wpa_supplicant_extra_ies(struct wpa_supplicant * wpa_s)520 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
521 {
522           struct wpabuf *extra_ie = NULL;
523           u8 ext_capab[18];
524           int ext_capab_len;
525 #ifdef CONFIG_WPS
526           int wps = 0;
527           enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
528 #endif /* CONFIG_WPS */
529 
530 #ifdef CONFIG_P2P
531           if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
532                     wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
533           else
534 #endif /* CONFIG_P2P */
535                     wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
536 
537           ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
538                                                        sizeof(ext_capab));
539           if (ext_capab_len > 0 &&
540               wpabuf_resize(&extra_ie, ext_capab_len) == 0)
541                     wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
542 
543 #ifdef CONFIG_INTERWORKING
544           if (wpa_s->conf->interworking &&
545               wpabuf_resize(&extra_ie, 100) == 0)
546                     wpas_add_interworking_elements(wpa_s, extra_ie);
547 #endif /* CONFIG_INTERWORKING */
548 
549 #ifdef CONFIG_MBO
550           if (wpa_s->enable_oce & OCE_STA)
551                     wpas_fils_req_param_add_max_channel(wpa_s, &extra_ie);
552 #endif /* CONFIG_MBO */
553 
554 #ifdef CONFIG_WPS
555           wps = wpas_wps_in_use(wpa_s, &req_type);
556 
557           if (wps) {
558                     struct wpabuf *wps_ie;
559                     wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON :
560                                                             DEV_PW_DEFAULT,
561                                                             &wpa_s->wps->dev,
562                                                             wpa_s->wps->uuid, req_type,
563                                                             0, NULL);
564                     if (wps_ie) {
565                               if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0)
566                                         wpabuf_put_buf(extra_ie, wps_ie);
567                               wpabuf_free(wps_ie);
568                     }
569           }
570 
571 #ifdef CONFIG_P2P
572           if (wps) {
573                     size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
574                     if (wpabuf_resize(&extra_ie, ielen) == 0)
575                               wpas_p2p_scan_ie(wpa_s, extra_ie);
576           }
577 #endif /* CONFIG_P2P */
578 
579           wpa_supplicant_mesh_add_scan_ie(wpa_s, &extra_ie);
580 
581 #endif /* CONFIG_WPS */
582 
583 #ifdef CONFIG_HS20
584           if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 9) == 0)
585                     wpas_hs20_add_indication(extra_ie, -1, 0);
586 #endif /* CONFIG_HS20 */
587 
588 #ifdef CONFIG_FST
589           if (wpa_s->fst_ies &&
590               wpabuf_resize(&extra_ie, wpabuf_len(wpa_s->fst_ies)) == 0)
591                     wpabuf_put_buf(extra_ie, wpa_s->fst_ies);
592 #endif /* CONFIG_FST */
593 
594 #ifdef CONFIG_MBO
595           /* Send MBO and OCE capabilities */
596           if (wpabuf_resize(&extra_ie, 12) == 0)
597                     wpas_mbo_scan_ie(wpa_s, extra_ie);
598 #endif /* CONFIG_MBO */
599 
600           if (wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ]) {
601                     struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_PROBE_REQ];
602 
603                     if (wpabuf_resize(&extra_ie, wpabuf_len(buf)) == 0)
604                               wpabuf_put_buf(extra_ie, buf);
605           }
606 
607           return extra_ie;
608 }
609 
610 
611 #ifdef CONFIG_P2P
612 
613 /*
614  * Check whether there are any enabled networks or credentials that could be
615  * used for a non-P2P connection.
616  */
non_p2p_network_enabled(struct wpa_supplicant * wpa_s)617 static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
618 {
619           struct wpa_ssid *ssid;
620 
621           for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
622                     if (wpas_network_disabled(wpa_s, ssid))
623                               continue;
624                     if (!ssid->p2p_group)
625                               return 1;
626           }
627 
628           if (wpa_s->conf->cred && wpa_s->conf->interworking &&
629               wpa_s->conf->auto_interworking)
630                     return 1;
631 
632           return 0;
633 }
634 
635 #endif /* CONFIG_P2P */
636 
637 
wpa_setband_scan_freqs_list(struct wpa_supplicant * wpa_s,enum hostapd_hw_mode band,struct wpa_driver_scan_params * params)638 static void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s,
639                                                   enum hostapd_hw_mode band,
640                                                   struct wpa_driver_scan_params *params)
641 {
642           /* Include only supported channels for the specified band */
643           struct hostapd_hw_modes *mode;
644           int count, i;
645 
646           mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
647           if (mode == NULL) {
648                     /* No channels supported in this band - use empty list */
649                     params->freqs = os_zalloc(sizeof(int));
650                     return;
651           }
652 
653           params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
654           if (params->freqs == NULL)
655                     return;
656           for (count = 0, i = 0; i < mode->num_channels; i++) {
657                     if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
658                               continue;
659                     params->freqs[count++] = mode->channels[i].freq;
660           }
661 }
662 
663 
wpa_setband_scan_freqs(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)664 static void wpa_setband_scan_freqs(struct wpa_supplicant *wpa_s,
665                                            struct wpa_driver_scan_params *params)
666 {
667           if (wpa_s->hw.modes == NULL)
668                     return; /* unknown what channels the driver supports */
669           if (params->freqs)
670                     return; /* already using a limited channel set */
671           if (wpa_s->setband == WPA_SETBAND_5G)
672                     wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A,
673                                                       params);
674           else if (wpa_s->setband == WPA_SETBAND_2G)
675                     wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G,
676                                                       params);
677 }
678 
679 
wpa_add_scan_ssid(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids,const u8 * ssid,size_t ssid_len)680 static void wpa_add_scan_ssid(struct wpa_supplicant *wpa_s,
681                                     struct wpa_driver_scan_params *params,
682                                     size_t max_ssids, const u8 *ssid, size_t ssid_len)
683 {
684           unsigned int j;
685 
686           for (j = 0; j < params->num_ssids; j++) {
687                     if (params->ssids[j].ssid_len == ssid_len &&
688                         params->ssids[j].ssid &&
689                         os_memcmp(params->ssids[j].ssid, ssid, ssid_len) == 0)
690                               return; /* already in the list */
691           }
692 
693           if (params->num_ssids + 1 > max_ssids) {
694                     wpa_printf(MSG_DEBUG, "Over max scan SSIDs for manual request");
695                     return;
696           }
697 
698           wpa_printf(MSG_DEBUG, "Scan SSID (manual request): %s",
699                        wpa_ssid_txt(ssid, ssid_len));
700 
701           params->ssids[params->num_ssids].ssid = ssid;
702           params->ssids[params->num_ssids].ssid_len = ssid_len;
703           params->num_ssids++;
704 }
705 
706 
wpa_add_owe_scan_ssid(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,struct wpa_ssid * ssid,size_t max_ssids)707 static void wpa_add_owe_scan_ssid(struct wpa_supplicant *wpa_s,
708                                           struct wpa_driver_scan_params *params,
709                                           struct wpa_ssid *ssid, size_t max_ssids)
710 {
711 #ifdef CONFIG_OWE
712           struct wpa_bss *bss;
713 
714           if (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE))
715                     return;
716 
717           wpa_printf(MSG_DEBUG, "OWE: Look for transition mode AP. ssid=%s",
718                        wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
719 
720           dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
721                     const u8 *owe, *pos, *end;
722                     const u8 *owe_ssid;
723                     size_t owe_ssid_len;
724 
725                     if (bss->ssid_len != ssid->ssid_len ||
726                         os_memcmp(bss->ssid, ssid->ssid, ssid->ssid_len) != 0)
727                               continue;
728 
729                     owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE);
730                     if (!owe || owe[1] < 4)
731                               continue;
732 
733                     pos = owe + 6;
734                     end = owe + 2 + owe[1];
735 
736                     /* Must include BSSID and ssid_len */
737                     if (end - pos < ETH_ALEN + 1)
738                               return;
739 
740                     /* Skip BSSID */
741                     pos += ETH_ALEN;
742                     owe_ssid_len = *pos++;
743                     owe_ssid = pos;
744 
745                     if ((size_t) (end - pos) < owe_ssid_len ||
746                         owe_ssid_len > SSID_MAX_LEN)
747                               return;
748 
749                     wpa_printf(MSG_DEBUG,
750                                  "OWE: scan_ssids: transition mode OWE ssid=%s",
751                                  wpa_ssid_txt(owe_ssid, owe_ssid_len));
752 
753                     wpa_add_scan_ssid(wpa_s, params, max_ssids,
754                                           owe_ssid, owe_ssid_len);
755                     return;
756           }
757 #endif /* CONFIG_OWE */
758 }
759 
760 
wpa_set_scan_ssids(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids)761 static void wpa_set_scan_ssids(struct wpa_supplicant *wpa_s,
762                                      struct wpa_driver_scan_params *params,
763                                      size_t max_ssids)
764 {
765           unsigned int i;
766           struct wpa_ssid *ssid;
767 
768           /*
769            * For devices with max_ssids greater than 1, leave the last slot empty
770            * for adding the wildcard scan entry.
771            */
772           max_ssids = max_ssids > 1 ? max_ssids - 1 : max_ssids;
773 
774           for (i = 0; i < wpa_s->scan_id_count; i++) {
775                     ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
776                     if (!ssid)
777                               continue;
778                     if (ssid->scan_ssid)
779                               wpa_add_scan_ssid(wpa_s, params, max_ssids,
780                                                     ssid->ssid, ssid->ssid_len);
781                     /*
782                      * Also add the SSID of the OWE BSS, to allow discovery of
783                      * transition mode APs more quickly.
784                      */
785                     wpa_add_owe_scan_ssid(wpa_s, params, ssid, max_ssids);
786           }
787 
788           wpa_s->scan_id_count = 0;
789 }
790 
791 
wpa_set_ssids_from_scan_req(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params,size_t max_ssids)792 static int wpa_set_ssids_from_scan_req(struct wpa_supplicant *wpa_s,
793                                                struct wpa_driver_scan_params *params,
794                                                size_t max_ssids)
795 {
796           unsigned int i;
797 
798           if (wpa_s->ssids_from_scan_req == NULL ||
799               wpa_s->num_ssids_from_scan_req == 0)
800                     return 0;
801 
802           if (wpa_s->num_ssids_from_scan_req > max_ssids) {
803                     wpa_s->num_ssids_from_scan_req = max_ssids;
804                     wpa_printf(MSG_DEBUG, "Over max scan SSIDs from scan req: %u",
805                                  (unsigned int) max_ssids);
806           }
807 
808           for (i = 0; i < wpa_s->num_ssids_from_scan_req; i++) {
809                     params->ssids[i].ssid = wpa_s->ssids_from_scan_req[i].ssid;
810                     params->ssids[i].ssid_len =
811                               wpa_s->ssids_from_scan_req[i].ssid_len;
812                     wpa_hexdump_ascii(MSG_DEBUG, "specific SSID",
813                                           params->ssids[i].ssid,
814                                           params->ssids[i].ssid_len);
815           }
816 
817           params->num_ssids = wpa_s->num_ssids_from_scan_req;
818           wpa_s->num_ssids_from_scan_req = 0;
819           return 1;
820 }
821 
822 
wpa_supplicant_scan(void * eloop_ctx,void * timeout_ctx)823 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
824 {
825           struct wpa_supplicant *wpa_s = eloop_ctx;
826           struct wpa_ssid *ssid;
827           int ret, p2p_in_prog;
828           struct wpabuf *extra_ie = NULL;
829           struct wpa_driver_scan_params params;
830           struct wpa_driver_scan_params *scan_params;
831           size_t max_ssids;
832           int connect_without_scan = 0;
833 
834           wpa_s->ignore_post_flush_scan_res = 0;
835 
836           if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
837                     wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled");
838                     return;
839           }
840 
841           if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) {
842                     wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan");
843                     wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
844                     return;
845           }
846 
847           if (wpa_s->scanning) {
848                     /*
849                      * If we are already in scanning state, we shall reschedule the
850                      * the incoming scan request.
851                      */
852                     wpa_dbg(wpa_s, MSG_DEBUG, "Already scanning - Reschedule the incoming scan req");
853                     wpa_supplicant_req_scan(wpa_s, 1, 0);
854                     return;
855           }
856 
857           if (!wpa_supplicant_enabled_networks(wpa_s) &&
858               wpa_s->scan_req == NORMAL_SCAN_REQ) {
859                     wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
860                     wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
861                     return;
862           }
863 
864           if (wpa_s->conf->ap_scan != 0 &&
865               (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) {
866                     wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - "
867                               "overriding ap_scan configuration");
868                     wpa_s->conf->ap_scan = 0;
869                     wpas_notify_ap_scan_changed(wpa_s);
870           }
871 
872           if (wpa_s->conf->ap_scan == 0) {
873                     wpa_supplicant_gen_assoc_event(wpa_s);
874                     return;
875           }
876 
877           ssid = NULL;
878           if (wpa_s->scan_req != MANUAL_SCAN_REQ &&
879               wpa_s->connect_without_scan) {
880                     connect_without_scan = 1;
881                     for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
882                               if (ssid == wpa_s->connect_without_scan)
883                                         break;
884                     }
885           }
886 
887           p2p_in_prog = wpas_p2p_in_progress(wpa_s);
888           if (p2p_in_prog && p2p_in_prog != 2 &&
889               (!ssid ||
890                (ssid->mode != WPAS_MODE_AP && ssid->mode != WPAS_MODE_P2P_GO))) {
891                     wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan while P2P operation is in progress");
892                     wpa_supplicant_req_scan(wpa_s, 5, 0);
893                     return;
894           }
895 
896           /*
897            * Don't cancel the scan based on ongoing PNO; defer it. Some scans are
898            * used for changing modes inside wpa_supplicant (roaming,
899            * auto-reconnect, etc). Discarding the scan might hurt these processes.
900            * The normal use case for PNO is to suspend the host immediately after
901            * starting PNO, so the periodic 100 ms attempts to run the scan do not
902            * normally happen in practice multiple times, i.e., this is simply
903            * restarting scanning once the host is woken up and PNO stopped.
904            */
905           if (wpa_s->pno || wpa_s->pno_sched_pending) {
906                     wpa_dbg(wpa_s, MSG_DEBUG, "Defer scan - PNO is in progress");
907                     wpa_supplicant_req_scan(wpa_s, 0, 100000);
908                     return;
909           }
910 
911           if (wpa_s->conf->ap_scan == 2)
912                     max_ssids = 1;
913           else {
914                     max_ssids = wpa_s->max_scan_ssids;
915                     if (max_ssids > WPAS_MAX_SCAN_SSIDS)
916                               max_ssids = WPAS_MAX_SCAN_SSIDS;
917           }
918 
919           wpa_s->last_scan_req = wpa_s->scan_req;
920           wpa_s->scan_req = NORMAL_SCAN_REQ;
921 
922           if (connect_without_scan) {
923                     wpa_s->connect_without_scan = NULL;
924                     if (ssid) {
925                               wpa_printf(MSG_DEBUG, "Start a pre-selected network "
926                                            "without scan step");
927                               wpa_supplicant_associate(wpa_s, NULL, ssid);
928                               return;
929                     }
930           }
931 
932           os_memset(&params, 0, sizeof(params));
933 
934           wpa_s->scan_prev_wpa_state = wpa_s->wpa_state;
935           if (wpa_s->wpa_state == WPA_DISCONNECTED ||
936               wpa_s->wpa_state == WPA_INACTIVE)
937                     wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
938 
939           /*
940            * If autoscan has set its own scanning parameters
941            */
942           if (wpa_s->autoscan_params != NULL) {
943                     scan_params = wpa_s->autoscan_params;
944                     goto scan;
945           }
946 
947           if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
948               wpa_set_ssids_from_scan_req(wpa_s, &params, max_ssids)) {
949                     wpa_printf(MSG_DEBUG, "Use specific SSIDs from SCAN command");
950                     goto ssid_list_set;
951           }
952 
953 #ifdef CONFIG_P2P
954           if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) &&
955               wpa_s->go_params && !wpa_s->conf->passive_scan) {
956                     wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during P2P group formation (p2p_in_provisioning=%d show_group_started=%d)",
957                                  wpa_s->p2p_in_provisioning,
958                                  wpa_s->show_group_started);
959                     params.ssids[0].ssid = wpa_s->go_params->ssid;
960                     params.ssids[0].ssid_len = wpa_s->go_params->ssid_len;
961                     params.num_ssids = 1;
962                     goto ssid_list_set;
963           }
964 
965           if (wpa_s->p2p_in_invitation) {
966                     if (wpa_s->current_ssid) {
967                               wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
968                               params.ssids[0].ssid = wpa_s->current_ssid->ssid;
969                               params.ssids[0].ssid_len =
970                                         wpa_s->current_ssid->ssid_len;
971                               params.num_ssids = 1;
972                     } else {
973                               wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
974                     }
975                     goto ssid_list_set;
976           }
977 #endif /* CONFIG_P2P */
978 
979           /* Find the starting point from which to continue scanning */
980           ssid = wpa_s->conf->ssid;
981           if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) {
982                     while (ssid) {
983                               if (ssid == wpa_s->prev_scan_ssid) {
984                                         ssid = ssid->next;
985                                         break;
986                               }
987                               ssid = ssid->next;
988                     }
989           }
990 
991           if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
992 #ifdef CONFIG_AP
993               !wpa_s->ap_iface &&
994 #endif /* CONFIG_AP */
995               wpa_s->conf->ap_scan == 2) {
996                     wpa_s->connect_without_scan = NULL;
997                     wpa_s->prev_scan_wildcard = 0;
998                     wpa_supplicant_assoc_try(wpa_s, ssid);
999                     return;
1000           } else if (wpa_s->conf->ap_scan == 2) {
1001                     /*
1002                      * User-initiated scan request in ap_scan == 2; scan with
1003                      * wildcard SSID.
1004                      */
1005                     ssid = NULL;
1006           } else if (wpa_s->reattach && wpa_s->current_ssid != NULL) {
1007                     /*
1008                      * Perform single-channel single-SSID scan for
1009                      * reassociate-to-same-BSS operation.
1010                      */
1011                     /* Setup SSID */
1012                     ssid = wpa_s->current_ssid;
1013                     wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
1014                                           ssid->ssid, ssid->ssid_len);
1015                     params.ssids[0].ssid = ssid->ssid;
1016                     params.ssids[0].ssid_len = ssid->ssid_len;
1017                     params.num_ssids = 1;
1018 
1019                     /*
1020                      * Allocate memory for frequency array, allocate one extra
1021                      * slot for the zero-terminator.
1022                      */
1023                     params.freqs = os_malloc(sizeof(int) * 2);
1024                     if (params.freqs) {
1025                               params.freqs[0] = wpa_s->assoc_freq;
1026                               params.freqs[1] = 0;
1027                     }
1028 
1029                     /*
1030                      * Reset the reattach flag so that we fall back to full scan if
1031                      * this scan fails.
1032                      */
1033                     wpa_s->reattach = 0;
1034           } else {
1035                     struct wpa_ssid *start = ssid, *tssid;
1036                     int freqs_set = 0;
1037                     if (ssid == NULL && max_ssids > 1)
1038                               ssid = wpa_s->conf->ssid;
1039                     while (ssid) {
1040                               if (!wpas_network_disabled(wpa_s, ssid) &&
1041                                   ssid->scan_ssid) {
1042                                         wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
1043                                                               ssid->ssid, ssid->ssid_len);
1044                                         params.ssids[params.num_ssids].ssid =
1045                                                   ssid->ssid;
1046                                         params.ssids[params.num_ssids].ssid_len =
1047                                                   ssid->ssid_len;
1048                                         params.num_ssids++;
1049                                         if (params.num_ssids + 1 >= max_ssids)
1050                                                   break;
1051                               }
1052 
1053                               if (!wpas_network_disabled(wpa_s, ssid)) {
1054                                         /*
1055                                          * Also add the SSID of the OWE BSS, to allow
1056                                          * discovery of transition mode APs more
1057                                          * quickly.
1058                                          */
1059                                         wpa_add_owe_scan_ssid(wpa_s, &params, ssid,
1060                                                                   max_ssids);
1061                               }
1062 
1063                               ssid = ssid->next;
1064                               if (ssid == start)
1065                                         break;
1066                               if (ssid == NULL && max_ssids > 1 &&
1067                                   start != wpa_s->conf->ssid)
1068                                         ssid = wpa_s->conf->ssid;
1069                     }
1070 
1071                     if (wpa_s->scan_id_count &&
1072                         wpa_s->last_scan_req == MANUAL_SCAN_REQ)
1073                               wpa_set_scan_ssids(wpa_s, &params, max_ssids);
1074 
1075                     for (tssid = wpa_s->conf->ssid;
1076                          wpa_s->last_scan_req != MANUAL_SCAN_REQ && tssid;
1077                          tssid = tssid->next) {
1078                               if (wpas_network_disabled(wpa_s, tssid))
1079                                         continue;
1080                               if ((params.freqs || !freqs_set) && tssid->scan_freq) {
1081                                         int_array_concat(&params.freqs,
1082                                                              tssid->scan_freq);
1083                               } else {
1084                                         os_free(params.freqs);
1085                                         params.freqs = NULL;
1086                               }
1087                               freqs_set = 1;
1088                     }
1089                     int_array_sort_unique(params.freqs);
1090           }
1091 
1092           if (ssid && max_ssids == 1) {
1093                     /*
1094                      * If the driver is limited to 1 SSID at a time interleave
1095                      * wildcard SSID scans with specific SSID scans to avoid
1096                      * waiting a long time for a wildcard scan.
1097                      */
1098                     if (!wpa_s->prev_scan_wildcard) {
1099                               params.ssids[0].ssid = NULL;
1100                               params.ssids[0].ssid_len = 0;
1101                               wpa_s->prev_scan_wildcard = 1;
1102                               wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for "
1103                                         "wildcard SSID (Interleave with specific)");
1104                     } else {
1105                               wpa_s->prev_scan_ssid = ssid;
1106                               wpa_s->prev_scan_wildcard = 0;
1107                               wpa_dbg(wpa_s, MSG_DEBUG,
1108                                         "Starting AP scan for specific SSID: %s",
1109                                         wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1110                     }
1111           } else if (ssid) {
1112                     /* max_ssids > 1 */
1113 
1114                     wpa_s->prev_scan_ssid = ssid;
1115                     wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in "
1116                               "the scan request");
1117                     params.num_ssids++;
1118           } else if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1119                        wpa_s->manual_scan_passive && params.num_ssids == 0) {
1120                     wpa_dbg(wpa_s, MSG_DEBUG, "Use passive scan based on manual request");
1121           } else if (wpa_s->conf->passive_scan) {
1122                     wpa_dbg(wpa_s, MSG_DEBUG,
1123                               "Use passive scan based on configuration");
1124           } else {
1125                     wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
1126                     params.num_ssids++;
1127                     wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard "
1128                               "SSID");
1129           }
1130 
1131 ssid_list_set:
1132           wpa_supplicant_optimize_freqs(wpa_s, &params);
1133           extra_ie = wpa_supplicant_extra_ies(wpa_s);
1134 
1135           if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
1136               wpa_s->manual_scan_only_new) {
1137                     wpa_printf(MSG_DEBUG,
1138                                  "Request driver to clear scan cache due to manual only_new=1 scan");
1139                     params.only_new_results = 1;
1140           }
1141 
1142           if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL &&
1143               wpa_s->manual_scan_freqs) {
1144                     wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels");
1145                     params.freqs = wpa_s->manual_scan_freqs;
1146                     wpa_s->manual_scan_freqs = NULL;
1147           }
1148 
1149           if (params.freqs == NULL && wpa_s->select_network_scan_freqs) {
1150                     wpa_dbg(wpa_s, MSG_DEBUG,
1151                               "Limit select_network scan to specified channels");
1152                     params.freqs = wpa_s->select_network_scan_freqs;
1153                     wpa_s->select_network_scan_freqs = NULL;
1154           }
1155 
1156           if (params.freqs == NULL && wpa_s->next_scan_freqs) {
1157                     wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously "
1158                               "generated frequency list");
1159                     params.freqs = wpa_s->next_scan_freqs;
1160           } else
1161                     os_free(wpa_s->next_scan_freqs);
1162           wpa_s->next_scan_freqs = NULL;
1163           wpa_setband_scan_freqs(wpa_s, &params);
1164 
1165           /* See if user specified frequencies. If so, scan only those. */
1166           if (wpa_s->conf->freq_list && !params.freqs) {
1167                     wpa_dbg(wpa_s, MSG_DEBUG,
1168                               "Optimize scan based on conf->freq_list");
1169                     int_array_concat(&params.freqs, wpa_s->conf->freq_list);
1170           }
1171 
1172           /* Use current associated channel? */
1173           if (wpa_s->conf->scan_cur_freq && !params.freqs) {
1174                     unsigned int num = wpa_s->num_multichan_concurrent;
1175 
1176                     params.freqs = os_calloc(num + 1, sizeof(int));
1177                     if (params.freqs) {
1178                               num = get_shared_radio_freqs(wpa_s, params.freqs, num);
1179                               if (num > 0) {
1180                                         wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
1181                                                   "current operating channels since "
1182                                                   "scan_cur_freq is enabled");
1183                               } else {
1184                                         os_free(params.freqs);
1185                                         params.freqs = NULL;
1186                               }
1187                     }
1188           }
1189 
1190 #ifdef CONFIG_MBO
1191           if (wpa_s->enable_oce & OCE_STA)
1192                     params.oce_scan = 1;
1193 #endif /* CONFIG_MBO */
1194 
1195           params.filter_ssids = wpa_supplicant_build_filter_ssids(
1196                     wpa_s->conf, &params.num_filter_ssids);
1197           if (extra_ie) {
1198                     params.extra_ies = wpabuf_head(extra_ie);
1199                     params.extra_ies_len = wpabuf_len(extra_ie);
1200           }
1201 
1202 #ifdef CONFIG_P2P
1203           if (wpa_s->p2p_in_provisioning || wpa_s->p2p_in_invitation ||
1204               (wpa_s->show_group_started && wpa_s->go_params)) {
1205                     /*
1206                      * The interface may not yet be in P2P mode, so we have to
1207                      * explicitly request P2P probe to disable CCK rates.
1208                      */
1209                     params.p2p_probe = 1;
1210           }
1211 #endif /* CONFIG_P2P */
1212 
1213           if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) &&
1214               wpa_s->wpa_state <= WPA_SCANNING) {
1215                     params.mac_addr_rand = 1;
1216                     if (wpa_s->mac_addr_scan) {
1217                               params.mac_addr = wpa_s->mac_addr_scan;
1218                               params.mac_addr_mask = wpa_s->mac_addr_scan + ETH_ALEN;
1219                     }
1220           }
1221 
1222           if (!is_zero_ether_addr(wpa_s->next_scan_bssid)) {
1223                     struct wpa_bss *bss;
1224 
1225                     params.bssid = wpa_s->next_scan_bssid;
1226                     bss = wpa_bss_get_bssid_latest(wpa_s, params.bssid);
1227                     if (bss && bss->ssid_len && params.num_ssids == 1 &&
1228                         params.ssids[0].ssid_len == 0) {
1229                               params.ssids[0].ssid = bss->ssid;
1230                               params.ssids[0].ssid_len = bss->ssid_len;
1231                               wpa_dbg(wpa_s, MSG_DEBUG,
1232                                         "Scan a previously specified BSSID " MACSTR
1233                                         " and SSID %s",
1234                                         MAC2STR(params.bssid),
1235                                         wpa_ssid_txt(bss->ssid, bss->ssid_len));
1236                     } else {
1237                               wpa_dbg(wpa_s, MSG_DEBUG,
1238                                         "Scan a previously specified BSSID " MACSTR,
1239                                         MAC2STR(params.bssid));
1240                     }
1241           }
1242 
1243           scan_params = &params;
1244 
1245 scan:
1246 #ifdef CONFIG_P2P
1247           /*
1248            * If the driver does not support multi-channel concurrency and a
1249            * virtual interface that shares the same radio with the wpa_s interface
1250            * is operating there may not be need to scan other channels apart from
1251            * the current operating channel on the other virtual interface. Filter
1252            * out other channels in case we are trying to find a connection for a
1253            * station interface when we are not configured to prefer station
1254            * connection and a concurrent operation is already in process.
1255            */
1256           if (wpa_s->scan_for_connection &&
1257               wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
1258               !scan_params->freqs && !params.freqs &&
1259               wpas_is_p2p_prioritized(wpa_s) &&
1260               wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
1261               non_p2p_network_enabled(wpa_s)) {
1262                     unsigned int num = wpa_s->num_multichan_concurrent;
1263 
1264                     params.freqs = os_calloc(num + 1, sizeof(int));
1265                     if (params.freqs) {
1266                               num = get_shared_radio_freqs(wpa_s, params.freqs, num);
1267                               if (num > 0 && num == wpa_s->num_multichan_concurrent) {
1268                                         wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used");
1269                               } else {
1270                                         os_free(params.freqs);
1271                                         params.freqs = NULL;
1272                               }
1273                     }
1274           }
1275 #endif /* CONFIG_P2P */
1276 
1277           ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
1278 
1279           if (ret && wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs &&
1280               !wpa_s->manual_scan_freqs) {
1281                     /* Restore manual_scan_freqs for the next attempt */
1282                     wpa_s->manual_scan_freqs = params.freqs;
1283                     params.freqs = NULL;
1284           }
1285 
1286           wpabuf_free(extra_ie);
1287           os_free(params.freqs);
1288           os_free(params.filter_ssids);
1289 
1290           if (ret) {
1291                     wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan");
1292                     if (wpa_s->scan_prev_wpa_state != wpa_s->wpa_state)
1293                               wpa_supplicant_set_state(wpa_s,
1294                                                              wpa_s->scan_prev_wpa_state);
1295                     /* Restore scan_req since we will try to scan again */
1296                     wpa_s->scan_req = wpa_s->last_scan_req;
1297                     wpa_supplicant_req_scan(wpa_s, 1, 0);
1298           } else {
1299                     wpa_s->scan_for_connection = 0;
1300 #ifdef CONFIG_INTERWORKING
1301                     wpa_s->interworking_fast_assoc_tried = 0;
1302 #endif /* CONFIG_INTERWORKING */
1303                     if (params.bssid)
1304                               os_memset(wpa_s->next_scan_bssid, 0, ETH_ALEN);
1305           }
1306 }
1307 
1308 
wpa_supplicant_update_scan_int(struct wpa_supplicant * wpa_s,int sec)1309 void wpa_supplicant_update_scan_int(struct wpa_supplicant *wpa_s, int sec)
1310 {
1311           struct os_reltime remaining, new_int;
1312           int cancelled;
1313 
1314           cancelled = eloop_cancel_timeout_one(wpa_supplicant_scan, wpa_s, NULL,
1315                                                        &remaining);
1316 
1317           new_int.sec = sec;
1318           new_int.usec = 0;
1319           if (cancelled && os_reltime_before(&remaining, &new_int)) {
1320                     new_int.sec = remaining.sec;
1321                     new_int.usec = remaining.usec;
1322           }
1323 
1324           if (cancelled) {
1325                     eloop_register_timeout(new_int.sec, new_int.usec,
1326                                                wpa_supplicant_scan, wpa_s, NULL);
1327           }
1328           wpa_s->scan_interval = sec;
1329 }
1330 
1331 
1332 /**
1333  * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
1334  * @wpa_s: Pointer to wpa_supplicant data
1335  * @sec: Number of seconds after which to scan
1336  * @usec: Number of microseconds after which to scan
1337  *
1338  * This function is used to schedule a scan for neighboring access points after
1339  * the specified time.
1340  */
wpa_supplicant_req_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1341 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
1342 {
1343           int res;
1344 
1345           if (wpa_s->p2p_mgmt) {
1346                     wpa_dbg(wpa_s, MSG_DEBUG,
1347                               "Ignore scan request (%d.%06d sec) on p2p_mgmt interface",
1348                               sec, usec);
1349                     return;
1350           }
1351 
1352           res = eloop_deplete_timeout(sec, usec, wpa_supplicant_scan, wpa_s,
1353                                             NULL);
1354           if (res == 1) {
1355                     wpa_dbg(wpa_s, MSG_DEBUG, "Rescheduling scan request: %d.%06d sec",
1356                               sec, usec);
1357           } else if (res == 0) {
1358                     wpa_dbg(wpa_s, MSG_DEBUG, "Ignore new scan request for %d.%06d sec since an earlier request is scheduled to trigger sooner",
1359                               sec, usec);
1360           } else {
1361                     wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d.%06d sec",
1362                               sec, usec);
1363                     eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
1364           }
1365 }
1366 
1367 
1368 /**
1369  * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan
1370  * @wpa_s: Pointer to wpa_supplicant data
1371  * @sec: Number of seconds after which to scan
1372  * @usec: Number of microseconds after which to scan
1373  * Returns: 0 on success or -1 otherwise
1374  *
1375  * This function is used to schedule periodic scans for neighboring
1376  * access points after the specified time.
1377  */
wpa_supplicant_delayed_sched_scan(struct wpa_supplicant * wpa_s,int sec,int usec)1378 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
1379                                               int sec, int usec)
1380 {
1381           if (!wpa_s->sched_scan_supported)
1382                     return -1;
1383 
1384           eloop_register_timeout(sec, usec,
1385                                      wpa_supplicant_delayed_sched_scan_timeout,
1386                                      wpa_s, NULL);
1387 
1388           return 0;
1389 }
1390 
1391 
1392 static void
wpa_scan_set_relative_rssi_params(struct wpa_supplicant * wpa_s,struct wpa_driver_scan_params * params)1393 wpa_scan_set_relative_rssi_params(struct wpa_supplicant *wpa_s,
1394                                           struct wpa_driver_scan_params *params)
1395 {
1396           if (wpa_s->wpa_state != WPA_COMPLETED ||
1397               !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI) ||
1398               wpa_s->srp.relative_rssi_set == 0)
1399                     return;
1400 
1401           params->relative_rssi_set = 1;
1402           params->relative_rssi = wpa_s->srp.relative_rssi;
1403 
1404           if (wpa_s->srp.relative_adjust_rssi == 0)
1405                     return;
1406 
1407           params->relative_adjust_band = wpa_s->srp.relative_adjust_band;
1408           params->relative_adjust_rssi = wpa_s->srp.relative_adjust_rssi;
1409 }
1410 
1411 
1412 /**
1413  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
1414  * @wpa_s: Pointer to wpa_supplicant data
1415  * Returns: 0 is sched_scan was started or -1 otherwise
1416  *
1417  * This function is used to schedule periodic scans for neighboring
1418  * access points repeating the scan continuously.
1419  */
wpa_supplicant_req_sched_scan(struct wpa_supplicant * wpa_s)1420 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
1421 {
1422           struct wpa_driver_scan_params params;
1423           struct wpa_driver_scan_params *scan_params;
1424           enum wpa_states prev_state;
1425           struct wpa_ssid *ssid = NULL;
1426           struct wpabuf *extra_ie = NULL;
1427           int ret;
1428           unsigned int max_sched_scan_ssids;
1429           int wildcard = 0;
1430           int need_ssids;
1431           struct sched_scan_plan scan_plan;
1432 
1433           if (!wpa_s->sched_scan_supported)
1434                     return -1;
1435 
1436           if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
1437                     max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
1438           else
1439                     max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
1440           if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload)
1441                     return -1;
1442 
1443           wpa_s->sched_scan_stop_req = 0;
1444 
1445           if (wpa_s->sched_scanning) {
1446                     wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning");
1447                     return 0;
1448           }
1449 
1450           need_ssids = 0;
1451           for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1452                     if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
1453                               /* Use wildcard SSID to find this network */
1454                               wildcard = 1;
1455                     } else if (!wpas_network_disabled(wpa_s, ssid) &&
1456                                  ssid->ssid_len)
1457                               need_ssids++;
1458 
1459 #ifdef CONFIG_WPS
1460                     if (!wpas_network_disabled(wpa_s, ssid) &&
1461                         ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
1462                               /*
1463                                * Normal scan is more reliable and faster for WPS
1464                                * operations and since these are for short periods of
1465                                * time, the benefit of trying to use sched_scan would
1466                                * be limited.
1467                                */
1468                               wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1469                                         "sched_scan for WPS");
1470                               return -1;
1471                     }
1472 #endif /* CONFIG_WPS */
1473           }
1474           if (wildcard)
1475                     need_ssids++;
1476 
1477           if (wpa_s->normal_scans < 3 &&
1478               (need_ssids <= wpa_s->max_scan_ssids ||
1479                wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) {
1480                     /*
1481                      * When normal scan can speed up operations, use that for the
1482                      * first operations before starting the sched_scan to allow
1483                      * user space sleep more. We do this only if the normal scan
1484                      * has functionality that is suitable for this or if the
1485                      * sched_scan does not have better support for multiple SSIDs.
1486                      */
1487                     wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of "
1488                               "sched_scan for initial scans (normal_scans=%d)",
1489                               wpa_s->normal_scans);
1490                     return -1;
1491           }
1492 
1493           os_memset(&params, 0, sizeof(params));
1494 
1495           /* If we can't allocate space for the filters, we just don't filter */
1496           params.filter_ssids = os_calloc(wpa_s->max_match_sets,
1497                                                   sizeof(struct wpa_driver_scan_filter));
1498 
1499           prev_state = wpa_s->wpa_state;
1500           if (wpa_s->wpa_state == WPA_DISCONNECTED ||
1501               wpa_s->wpa_state == WPA_INACTIVE)
1502                     wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
1503 
1504           if (wpa_s->autoscan_params != NULL) {
1505                     scan_params = wpa_s->autoscan_params;
1506                     goto scan;
1507           }
1508 
1509           /* Find the starting point from which to continue scanning */
1510           ssid = wpa_s->conf->ssid;
1511           if (wpa_s->prev_sched_ssid) {
1512                     while (ssid) {
1513                               if (ssid == wpa_s->prev_sched_ssid) {
1514                                         ssid = ssid->next;
1515                                         break;
1516                               }
1517                               ssid = ssid->next;
1518                     }
1519           }
1520 
1521           if (!ssid || !wpa_s->prev_sched_ssid) {
1522                     wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list");
1523                     wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1524                     wpa_s->first_sched_scan = 1;
1525                     ssid = wpa_s->conf->ssid;
1526                     wpa_s->prev_sched_ssid = ssid;
1527           }
1528 
1529           if (wildcard) {
1530                     wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan");
1531                     params.num_ssids++;
1532           }
1533 
1534           while (ssid) {
1535                     if (wpas_network_disabled(wpa_s, ssid))
1536                               goto next;
1537 
1538                     if (params.num_filter_ssids < wpa_s->max_match_sets &&
1539                         params.filter_ssids && ssid->ssid && ssid->ssid_len) {
1540                               wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s",
1541                                         wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1542                               os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid,
1543                                           ssid->ssid, ssid->ssid_len);
1544                               params.filter_ssids[params.num_filter_ssids].ssid_len =
1545                                         ssid->ssid_len;
1546                               params.num_filter_ssids++;
1547                     } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len)
1548                     {
1549                               wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID "
1550                                         "filter for sched_scan - drop filter");
1551                               os_free(params.filter_ssids);
1552                               params.filter_ssids = NULL;
1553                               params.num_filter_ssids = 0;
1554                     }
1555 
1556                     if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) {
1557                               if (params.num_ssids == max_sched_scan_ssids)
1558                                         break; /* only room for broadcast SSID */
1559                               wpa_dbg(wpa_s, MSG_DEBUG,
1560                                         "add to active scan ssid: %s",
1561                                         wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1562                               params.ssids[params.num_ssids].ssid =
1563                                         ssid->ssid;
1564                               params.ssids[params.num_ssids].ssid_len =
1565                                         ssid->ssid_len;
1566                               params.num_ssids++;
1567                               if (params.num_ssids >= max_sched_scan_ssids) {
1568                                         wpa_s->prev_sched_ssid = ssid;
1569                                         do {
1570                                                   ssid = ssid->next;
1571                                         } while (ssid &&
1572                                                    (wpas_network_disabled(wpa_s, ssid) ||
1573                                                     !ssid->scan_ssid));
1574                                         break;
1575                               }
1576                     }
1577 
1578           next:
1579                     wpa_s->prev_sched_ssid = ssid;
1580                     ssid = ssid->next;
1581           }
1582 
1583           if (params.num_filter_ssids == 0) {
1584                     os_free(params.filter_ssids);
1585                     params.filter_ssids = NULL;
1586           }
1587 
1588           extra_ie = wpa_supplicant_extra_ies(wpa_s);
1589           if (extra_ie) {
1590                     params.extra_ies = wpabuf_head(extra_ie);
1591                     params.extra_ies_len = wpabuf_len(extra_ie);
1592           }
1593 
1594           if (wpa_s->conf->filter_rssi)
1595                     params.filter_rssi = wpa_s->conf->filter_rssi;
1596 
1597           /* See if user specified frequencies. If so, scan only those. */
1598           if (wpa_s->conf->freq_list && !params.freqs) {
1599                     wpa_dbg(wpa_s, MSG_DEBUG,
1600                               "Optimize scan based on conf->freq_list");
1601                     int_array_concat(&params.freqs, wpa_s->conf->freq_list);
1602           }
1603 
1604 #ifdef CONFIG_MBO
1605           if (wpa_s->enable_oce & OCE_STA)
1606                     params.oce_scan = 1;
1607 #endif /* CONFIG_MBO */
1608 
1609           scan_params = &params;
1610 
1611 scan:
1612           wpa_s->sched_scan_timed_out = 0;
1613 
1614           /*
1615            * We cannot support multiple scan plans if the scan request includes
1616            * too many SSID's, so in this case use only the last scan plan and make
1617            * it run infinitely. It will be stopped by the timeout.
1618            */
1619           if (wpa_s->sched_scan_plans_num == 1 ||
1620               (wpa_s->sched_scan_plans_num && !ssid && wpa_s->first_sched_scan)) {
1621                     params.sched_scan_plans = wpa_s->sched_scan_plans;
1622                     params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
1623           } else if (wpa_s->sched_scan_plans_num > 1) {
1624                     wpa_dbg(wpa_s, MSG_DEBUG,
1625                               "Too many SSIDs. Default to using single scheduled_scan plan");
1626                     params.sched_scan_plans =
1627                               &wpa_s->sched_scan_plans[wpa_s->sched_scan_plans_num -
1628                                                              1];
1629                     params.sched_scan_plans_num = 1;
1630           } else {
1631                     if (wpa_s->conf->sched_scan_interval)
1632                               scan_plan.interval = wpa_s->conf->sched_scan_interval;
1633                     else
1634                               scan_plan.interval = 10;
1635 
1636                     if (scan_plan.interval > wpa_s->max_sched_scan_plan_interval) {
1637                               wpa_printf(MSG_WARNING,
1638                                            "Scan interval too long(%u), use the maximum allowed(%u)",
1639                                            scan_plan.interval,
1640                                            wpa_s->max_sched_scan_plan_interval);
1641                               scan_plan.interval =
1642                                         wpa_s->max_sched_scan_plan_interval;
1643                     }
1644 
1645                     scan_plan.iterations = 0;
1646                     params.sched_scan_plans = &scan_plan;
1647                     params.sched_scan_plans_num = 1;
1648           }
1649 
1650           params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
1651 
1652           if (ssid || !wpa_s->first_sched_scan) {
1653                     wpa_dbg(wpa_s, MSG_DEBUG,
1654                               "Starting sched scan after %u seconds: interval %u timeout %d",
1655                               params.sched_scan_start_delay,
1656                               params.sched_scan_plans[0].interval,
1657                               wpa_s->sched_scan_timeout);
1658           } else {
1659                     wpa_dbg(wpa_s, MSG_DEBUG,
1660                               "Starting sched scan after %u seconds (no timeout)",
1661                               params.sched_scan_start_delay);
1662           }
1663 
1664           wpa_setband_scan_freqs(wpa_s, scan_params);
1665 
1666           if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) &&
1667               wpa_s->wpa_state <= WPA_SCANNING) {
1668                     params.mac_addr_rand = 1;
1669                     if (wpa_s->mac_addr_sched_scan) {
1670                               params.mac_addr = wpa_s->mac_addr_sched_scan;
1671                               params.mac_addr_mask = wpa_s->mac_addr_sched_scan +
1672                                         ETH_ALEN;
1673                     }
1674           }
1675 
1676           wpa_scan_set_relative_rssi_params(wpa_s, scan_params);
1677 
1678           ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params);
1679           wpabuf_free(extra_ie);
1680           os_free(params.filter_ssids);
1681           if (ret) {
1682                     wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan");
1683                     if (prev_state != wpa_s->wpa_state)
1684                               wpa_supplicant_set_state(wpa_s, prev_state);
1685                     return ret;
1686           }
1687 
1688           /* If we have more SSIDs to scan, add a timeout so we scan them too */
1689           if (ssid || !wpa_s->first_sched_scan) {
1690                     wpa_s->sched_scan_timed_out = 0;
1691                     eloop_register_timeout(wpa_s->sched_scan_timeout, 0,
1692                                                wpa_supplicant_sched_scan_timeout,
1693                                                wpa_s, NULL);
1694                     wpa_s->first_sched_scan = 0;
1695                     wpa_s->sched_scan_timeout /= 2;
1696                     params.sched_scan_plans[0].interval *= 2;
1697                     if ((unsigned int) wpa_s->sched_scan_timeout <
1698                         params.sched_scan_plans[0].interval ||
1699                         params.sched_scan_plans[0].interval >
1700                         wpa_s->max_sched_scan_plan_interval) {
1701                               params.sched_scan_plans[0].interval = 10;
1702                               wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2;
1703                     }
1704           }
1705 
1706           /* If there is no more ssids, start next time from the beginning */
1707           if (!ssid)
1708                     wpa_s->prev_sched_ssid = NULL;
1709 
1710           return 0;
1711 }
1712 
1713 
1714 /**
1715  * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
1716  * @wpa_s: Pointer to wpa_supplicant data
1717  *
1718  * This function is used to cancel a scan request scheduled with
1719  * wpa_supplicant_req_scan().
1720  */
wpa_supplicant_cancel_scan(struct wpa_supplicant * wpa_s)1721 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
1722 {
1723           wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
1724           eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
1725 }
1726 
1727 
1728 /**
1729  * wpa_supplicant_cancel_delayed_sched_scan - Stop a delayed scheduled scan
1730  * @wpa_s: Pointer to wpa_supplicant data
1731  *
1732  * This function is used to stop a delayed scheduled scan.
1733  */
wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant * wpa_s)1734 void wpa_supplicant_cancel_delayed_sched_scan(struct wpa_supplicant *wpa_s)
1735 {
1736           if (!wpa_s->sched_scan_supported)
1737                     return;
1738 
1739           wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling delayed sched scan");
1740           eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout,
1741                                    wpa_s, NULL);
1742 }
1743 
1744 
1745 /**
1746  * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans
1747  * @wpa_s: Pointer to wpa_supplicant data
1748  *
1749  * This function is used to stop a periodic scheduled scan.
1750  */
wpa_supplicant_cancel_sched_scan(struct wpa_supplicant * wpa_s)1751 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s)
1752 {
1753           if (!wpa_s->sched_scanning)
1754                     return;
1755 
1756           if (wpa_s->sched_scanning)
1757                     wpa_s->sched_scan_stop_req = 1;
1758 
1759           wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan");
1760           eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL);
1761           wpa_supplicant_stop_sched_scan(wpa_s);
1762 }
1763 
1764 
1765 /**
1766  * wpa_supplicant_notify_scanning - Indicate possible scan state change
1767  * @wpa_s: Pointer to wpa_supplicant data
1768  * @scanning: Whether scanning is currently in progress
1769  *
1770  * This function is to generate scanning notifycations. It is called whenever
1771  * there may have been a change in scanning (scan started, completed, stopped).
1772  * wpas_notify_scanning() is called whenever the scanning state changed from the
1773  * previously notified state.
1774  */
wpa_supplicant_notify_scanning(struct wpa_supplicant * wpa_s,int scanning)1775 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
1776                                             int scanning)
1777 {
1778           if (wpa_s->scanning != scanning) {
1779                     wpa_s->scanning = scanning;
1780                     wpas_notify_scanning(wpa_s);
1781           }
1782 }
1783 
1784 
wpa_scan_get_max_rate(const struct wpa_scan_res * res)1785 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res)
1786 {
1787           int rate = 0;
1788           const u8 *ie;
1789           int i;
1790 
1791           ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES);
1792           for (i = 0; ie && i < ie[1]; i++) {
1793                     if ((ie[i + 2] & 0x7f) > rate)
1794                               rate = ie[i + 2] & 0x7f;
1795           }
1796 
1797           ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES);
1798           for (i = 0; ie && i < ie[1]; i++) {
1799                     if ((ie[i + 2] & 0x7f) > rate)
1800                               rate = ie[i + 2] & 0x7f;
1801           }
1802 
1803           return rate;
1804 }
1805 
1806 
1807 /**
1808  * wpa_scan_get_ie - Fetch a specified information element from a scan result
1809  * @res: Scan result entry
1810  * @ie: Information element identitifier (WLAN_EID_*)
1811  * Returns: Pointer to the information element (id field) or %NULL if not found
1812  *
1813  * This function returns the first matching information element in the scan
1814  * result.
1815  */
wpa_scan_get_ie(const struct wpa_scan_res * res,u8 ie)1816 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie)
1817 {
1818           size_t ie_len = res->ie_len;
1819 
1820           /* Use the Beacon frame IEs if res->ie_len is not available */
1821           if (!ie_len)
1822                     ie_len = res->beacon_ie_len;
1823 
1824           return get_ie((const u8 *) (res + 1), ie_len, ie);
1825 }
1826 
1827 
1828 /**
1829  * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result
1830  * @res: Scan result entry
1831  * @vendor_type: Vendor type (four octets starting the IE payload)
1832  * Returns: Pointer to the information element (id field) or %NULL if not found
1833  *
1834  * This function returns the first matching information element in the scan
1835  * result.
1836  */
wpa_scan_get_vendor_ie(const struct wpa_scan_res * res,u32 vendor_type)1837 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
1838                                           u32 vendor_type)
1839 {
1840           const u8 *end, *pos;
1841 
1842           pos = (const u8 *) (res + 1);
1843           end = pos + res->ie_len;
1844 
1845           while (end - pos > 1) {
1846                     if (2 + pos[1] > end - pos)
1847                               break;
1848                     if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1849                         vendor_type == WPA_GET_BE32(&pos[2]))
1850                               return pos;
1851                     pos += 2 + pos[1];
1852           }
1853 
1854           return NULL;
1855 }
1856 
1857 
1858 /**
1859  * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
1860  * @res: Scan result entry
1861  * @vendor_type: Vendor type (four octets starting the IE payload)
1862  * Returns: Pointer to the information element (id field) or %NULL if not found
1863  *
1864  * This function returns the first matching information element in the scan
1865  * result.
1866  *
1867  * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
1868  * from Beacon frames instead of either Beacon or Probe Response frames.
1869  */
wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res * res,u32 vendor_type)1870 const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
1871                                                    u32 vendor_type)
1872 {
1873           const u8 *end, *pos;
1874 
1875           if (res->beacon_ie_len == 0)
1876                     return NULL;
1877 
1878           pos = (const u8 *) (res + 1);
1879           pos += res->ie_len;
1880           end = pos + res->beacon_ie_len;
1881 
1882           while (end - pos > 1) {
1883                     if (2 + pos[1] > end - pos)
1884                               break;
1885                     if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1886                         vendor_type == WPA_GET_BE32(&pos[2]))
1887                               return pos;
1888                     pos += 2 + pos[1];
1889           }
1890 
1891           return NULL;
1892 }
1893 
1894 
1895 /**
1896  * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
1897  * @res: Scan result entry
1898  * @vendor_type: Vendor type (four octets starting the IE payload)
1899  * Returns: Pointer to the information element payload or %NULL if not found
1900  *
1901  * This function returns concatenated payload of possibly fragmented vendor
1902  * specific information elements in the scan result. The caller is responsible
1903  * for freeing the returned buffer.
1904  */
wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res * res,u32 vendor_type)1905 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
1906                                                        u32 vendor_type)
1907 {
1908           struct wpabuf *buf;
1909           const u8 *end, *pos;
1910 
1911           buf = wpabuf_alloc(res->ie_len);
1912           if (buf == NULL)
1913                     return NULL;
1914 
1915           pos = (const u8 *) (res + 1);
1916           end = pos + res->ie_len;
1917 
1918           while (end - pos > 1) {
1919                     if (2 + pos[1] > end - pos)
1920                               break;
1921                     if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1922                         vendor_type == WPA_GET_BE32(&pos[2]))
1923                               wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
1924                     pos += 2 + pos[1];
1925           }
1926 
1927           if (wpabuf_len(buf) == 0) {
1928                     wpabuf_free(buf);
1929                     buf = NULL;
1930           }
1931 
1932           return buf;
1933 }
1934 
1935 
1936 /*
1937  * Channels with a great SNR can operate at full rate. What is a great SNR?
1938  * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
1939  * rule of thumb is that any SNR above 20 is good." This one
1940  * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
1941  * recommends 25 as a minimum SNR for 54 Mbps data rate. The estimates used in
1942  * scan_est_throughput() allow even smaller SNR values for the maximum rates
1943  * (21 for 54 Mbps, 22 for VHT80 MCS9, 24 for HT40 and HT20 MCS7). Use 25 as a
1944  * somewhat conservative value here.
1945  */
1946 #define GREAT_SNR 25
1947 
1948 #define IS_5GHZ(n) (n > 4000)
1949 
1950 /* Compare function for sorting scan results. Return >0 if @b is considered
1951  * better. */
wpa_scan_result_compar(const void * a,const void * b)1952 static int wpa_scan_result_compar(const void *a, const void *b)
1953 {
1954 #define MIN(a,b) a < b ? a : b
1955           struct wpa_scan_res **_wa = (void *) a;
1956           struct wpa_scan_res **_wb = (void *) b;
1957           struct wpa_scan_res *wa = *_wa;
1958           struct wpa_scan_res *wb = *_wb;
1959           int wpa_a, wpa_b;
1960           int snr_a, snr_b, snr_a_full, snr_b_full;
1961 
1962           /* WPA/WPA2 support preferred */
1963           wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL ||
1964                     wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL;
1965           wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL ||
1966                     wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL;
1967 
1968           if (wpa_b && !wpa_a)
1969                     return 1;
1970           if (!wpa_b && wpa_a)
1971                     return -1;
1972 
1973           /* privacy support preferred */
1974           if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 &&
1975               (wb->caps & IEEE80211_CAP_PRIVACY))
1976                     return 1;
1977           if ((wa->caps & IEEE80211_CAP_PRIVACY) &&
1978               (wb->caps & IEEE80211_CAP_PRIVACY) == 0)
1979                     return -1;
1980 
1981           if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) {
1982                     snr_a_full = wa->snr;
1983                     snr_a = MIN(wa->snr, GREAT_SNR);
1984                     snr_b_full = wb->snr;
1985                     snr_b = MIN(wb->snr, GREAT_SNR);
1986           } else {
1987                     /* Level is not in dBm, so we can't calculate
1988                      * SNR. Just use raw level (units unknown). */
1989                     snr_a = snr_a_full = wa->level;
1990                     snr_b = snr_b_full = wb->level;
1991           }
1992 
1993           /* if SNR is close, decide by max rate or frequency band */
1994           if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
1995                     if (wa->est_throughput != wb->est_throughput)
1996                               return (int) wb->est_throughput -
1997                                         (int) wa->est_throughput;
1998           }
1999           if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
2000               (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
2001                     if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
2002                               return IS_5GHZ(wa->freq) ? -1 : 1;
2003           }
2004 
2005           /* all things being equal, use SNR; if SNRs are
2006            * identical, use quality values since some drivers may only report
2007            * that value and leave the signal level zero */
2008           if (snr_b_full == snr_a_full)
2009                     return wb->qual - wa->qual;
2010           return snr_b_full - snr_a_full;
2011 #undef MIN
2012 }
2013 
2014 
2015 #ifdef CONFIG_WPS
2016 /* Compare function for sorting scan results when searching a WPS AP for
2017  * provisioning. Return >0 if @b is considered better. */
wpa_scan_result_wps_compar(const void * a,const void * b)2018 static int wpa_scan_result_wps_compar(const void *a, const void *b)
2019 {
2020           struct wpa_scan_res **_wa = (void *) a;
2021           struct wpa_scan_res **_wb = (void *) b;
2022           struct wpa_scan_res *wa = *_wa;
2023           struct wpa_scan_res *wb = *_wb;
2024           int uses_wps_a, uses_wps_b;
2025           struct wpabuf *wps_a, *wps_b;
2026           int res;
2027 
2028           /* Optimization - check WPS IE existence before allocated memory and
2029            * doing full reassembly. */
2030           uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL;
2031           uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL;
2032           if (uses_wps_a && !uses_wps_b)
2033                     return -1;
2034           if (!uses_wps_a && uses_wps_b)
2035                     return 1;
2036 
2037           if (uses_wps_a && uses_wps_b) {
2038                     wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE);
2039                     wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE);
2040                     res = wps_ap_priority_compar(wps_a, wps_b);
2041                     wpabuf_free(wps_a);
2042                     wpabuf_free(wps_b);
2043                     if (res)
2044                               return res;
2045           }
2046 
2047           /*
2048            * Do not use current AP security policy as a sorting criteria during
2049            * WPS provisioning step since the AP may get reconfigured at the
2050            * completion of provisioning.
2051            */
2052 
2053           /* all things being equal, use signal level; if signal levels are
2054            * identical, use quality values since some drivers may only report
2055            * that value and leave the signal level zero */
2056           if (wb->level == wa->level)
2057                     return wb->qual - wa->qual;
2058           return wb->level - wa->level;
2059 }
2060 #endif /* CONFIG_WPS */
2061 
2062 
dump_scan_res(struct wpa_scan_results * scan_res)2063 static void dump_scan_res(struct wpa_scan_results *scan_res)
2064 {
2065 #ifndef CONFIG_NO_STDOUT_DEBUG
2066           size_t i;
2067 
2068           if (scan_res->res == NULL || scan_res->num == 0)
2069                     return;
2070 
2071           wpa_printf(MSG_EXCESSIVE, "Sorted scan results");
2072 
2073           for (i = 0; i < scan_res->num; i++) {
2074                     struct wpa_scan_res *r = scan_res->res[i];
2075                     u8 *pos;
2076                     if (r->flags & WPA_SCAN_LEVEL_DBM) {
2077                               int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID);
2078 
2079                               wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
2080                                            "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u",
2081                                            MAC2STR(r->bssid), r->freq, r->qual,
2082                                            r->noise, noise_valid ? "" : "~", r->level,
2083                                            r->snr, r->snr >= GREAT_SNR ? "*" : "",
2084                                            r->flags,
2085                                            r->age, r->est_throughput);
2086                     } else {
2087                               wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d "
2088                                            "noise=%d level=%d flags=0x%x age=%u est=%u",
2089                                            MAC2STR(r->bssid), r->freq, r->qual,
2090                                            r->noise, r->level, r->flags, r->age,
2091                                            r->est_throughput);
2092                     }
2093                     pos = (u8 *) (r + 1);
2094                     if (r->ie_len)
2095                               wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len);
2096                     pos += r->ie_len;
2097                     if (r->beacon_ie_len)
2098                               wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs",
2099                                             pos, r->beacon_ie_len);
2100           }
2101 #endif /* CONFIG_NO_STDOUT_DEBUG */
2102 }
2103 
2104 
2105 /**
2106  * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed
2107  * @wpa_s: Pointer to wpa_supplicant data
2108  * @bssid: BSSID to check
2109  * Returns: 0 if the BSSID is filtered or 1 if not
2110  *
2111  * This function is used to filter out specific BSSIDs from scan reslts mainly
2112  * for testing purposes (SET bssid_filter ctrl_iface command).
2113  */
wpa_supplicant_filter_bssid_match(struct wpa_supplicant * wpa_s,const u8 * bssid)2114 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
2115                                               const u8 *bssid)
2116 {
2117           size_t i;
2118 
2119           if (wpa_s->bssid_filter == NULL)
2120                     return 1;
2121 
2122           for (i = 0; i < wpa_s->bssid_filter_count; i++) {
2123                     if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
2124                                     ETH_ALEN) == 0)
2125                               return 1;
2126           }
2127 
2128           return 0;
2129 }
2130 
2131 
filter_scan_res(struct wpa_supplicant * wpa_s,struct wpa_scan_results * res)2132 void filter_scan_res(struct wpa_supplicant *wpa_s,
2133                          struct wpa_scan_results *res)
2134 {
2135           size_t i, j;
2136 
2137           if (wpa_s->bssid_filter == NULL)
2138                     return;
2139 
2140           for (i = 0, j = 0; i < res->num; i++) {
2141                     if (wpa_supplicant_filter_bssid_match(wpa_s,
2142                                                                   res->res[i]->bssid)) {
2143                               res->res[j++] = res->res[i];
2144                     } else {
2145                               os_free(res->res[i]);
2146                               res->res[i] = NULL;
2147                     }
2148           }
2149 
2150           if (res->num != j) {
2151                     wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
2152                                  (int) (res->num - j));
2153                     res->num = j;
2154           }
2155 }
2156 
2157 
2158 /*
2159  * Noise floor values to use when we have signal strength
2160  * measurements, but no noise floor measurements. These values were
2161  * measured in an office environment with many APs.
2162  */
2163 #define DEFAULT_NOISE_FLOOR_2GHZ (-89)
2164 #define DEFAULT_NOISE_FLOOR_5GHZ (-92)
2165 
scan_snr(struct wpa_scan_res * res)2166 void scan_snr(struct wpa_scan_res *res)
2167 {
2168           if (res->flags & WPA_SCAN_NOISE_INVALID) {
2169                     res->noise = IS_5GHZ(res->freq) ?
2170                               DEFAULT_NOISE_FLOOR_5GHZ :
2171                               DEFAULT_NOISE_FLOOR_2GHZ;
2172           }
2173 
2174           if (res->flags & WPA_SCAN_LEVEL_DBM) {
2175                     res->snr = res->level - res->noise;
2176           } else {
2177                     /* Level is not in dBm, so we can't calculate
2178                      * SNR. Just use raw level (units unknown). */
2179                     res->snr = res->level;
2180           }
2181 }
2182 
2183 
max_ht20_rate(int snr)2184 static unsigned int max_ht20_rate(int snr)
2185 {
2186           if (snr < 6)
2187                     return 6500; /* HT20 MCS0 */
2188           if (snr < 8)
2189                     return 13000; /* HT20 MCS1 */
2190           if (snr < 13)
2191                     return 19500; /* HT20 MCS2 */
2192           if (snr < 17)
2193                     return 26000; /* HT20 MCS3 */
2194           if (snr < 20)
2195                     return 39000; /* HT20 MCS4 */
2196           if (snr < 23)
2197                     return 52000; /* HT20 MCS5 */
2198           if (snr < 24)
2199                     return 58500; /* HT20 MCS6 */
2200           return 65000; /* HT20 MCS7 */
2201 }
2202 
2203 
max_ht40_rate(int snr)2204 static unsigned int max_ht40_rate(int snr)
2205 {
2206           if (snr < 3)
2207                     return 13500; /* HT40 MCS0 */
2208           if (snr < 6)
2209                     return 27000; /* HT40 MCS1 */
2210           if (snr < 10)
2211                     return 40500; /* HT40 MCS2 */
2212           if (snr < 15)
2213                     return 54000; /* HT40 MCS3 */
2214           if (snr < 17)
2215                     return 81000; /* HT40 MCS4 */
2216           if (snr < 22)
2217                     return 108000; /* HT40 MCS5 */
2218           if (snr < 24)
2219                     return 121500; /* HT40 MCS6 */
2220           return 135000; /* HT40 MCS7 */
2221 }
2222 
2223 
max_vht80_rate(int snr)2224 static unsigned int max_vht80_rate(int snr)
2225 {
2226           if (snr < 1)
2227                     return 0;
2228           if (snr < 2)
2229                     return 29300; /* VHT80 MCS0 */
2230           if (snr < 5)
2231                     return 58500; /* VHT80 MCS1 */
2232           if (snr < 9)
2233                     return 87800; /* VHT80 MCS2 */
2234           if (snr < 11)
2235                     return 117000; /* VHT80 MCS3 */
2236           if (snr < 15)
2237                     return 175500; /* VHT80 MCS4 */
2238           if (snr < 16)
2239                     return 234000; /* VHT80 MCS5 */
2240           if (snr < 18)
2241                     return 263300; /* VHT80 MCS6 */
2242           if (snr < 20)
2243                     return 292500; /* VHT80 MCS7 */
2244           if (snr < 22)
2245                     return 351000; /* VHT80 MCS8 */
2246           return 390000; /* VHT80 MCS9 */
2247 }
2248 
2249 
scan_est_throughput(struct wpa_supplicant * wpa_s,struct wpa_scan_res * res)2250 void scan_est_throughput(struct wpa_supplicant *wpa_s,
2251                                struct wpa_scan_res *res)
2252 {
2253           enum local_hw_capab capab = wpa_s->hw_capab;
2254           int rate; /* max legacy rate in 500 kb/s units */
2255           const u8 *ie;
2256           unsigned int est, tmp;
2257           int snr = res->snr;
2258 
2259           if (res->est_throughput)
2260                     return;
2261 
2262           /* Get maximum legacy rate */
2263           rate = wpa_scan_get_max_rate(res);
2264 
2265           /* Limit based on estimated SNR */
2266           if (rate > 1 * 2 && snr < 1)
2267                     rate = 1 * 2;
2268           else if (rate > 2 * 2 && snr < 4)
2269                     rate = 2 * 2;
2270           else if (rate > 6 * 2 && snr < 5)
2271                     rate = 6 * 2;
2272           else if (rate > 9 * 2 && snr < 6)
2273                     rate = 9 * 2;
2274           else if (rate > 12 * 2 && snr < 7)
2275                     rate = 12 * 2;
2276           else if (rate > 18 * 2 && snr < 10)
2277                     rate = 18 * 2;
2278           else if (rate > 24 * 2 && snr < 11)
2279                     rate = 24 * 2;
2280           else if (rate > 36 * 2 && snr < 15)
2281                     rate = 36 * 2;
2282           else if (rate > 48 * 2 && snr < 19)
2283                     rate = 48 * 2;
2284           else if (rate > 54 * 2 && snr < 21)
2285                     rate = 54 * 2;
2286           est = rate * 500;
2287 
2288           if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) {
2289                     ie = wpa_scan_get_ie(res, WLAN_EID_HT_CAP);
2290                     if (ie) {
2291                               tmp = max_ht20_rate(snr);
2292                               if (tmp > est)
2293                                         est = tmp;
2294                     }
2295           }
2296 
2297           if (capab == CAPAB_HT40 || capab == CAPAB_VHT) {
2298                     ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
2299                     if (ie && ie[1] >= 2 &&
2300                         (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
2301                               tmp = max_ht40_rate(snr);
2302                               if (tmp > est)
2303                                         est = tmp;
2304                     }
2305           }
2306 
2307           if (capab == CAPAB_VHT) {
2308                     /* Use +1 to assume VHT is always faster than HT */
2309                     ie = wpa_scan_get_ie(res, WLAN_EID_VHT_CAP);
2310                     if (ie) {
2311                               tmp = max_ht20_rate(snr) + 1;
2312                               if (tmp > est)
2313                                         est = tmp;
2314 
2315                               ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION);
2316                               if (ie && ie[1] >= 2 &&
2317                                   (ie[3] &
2318                                    HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
2319                                         tmp = max_ht40_rate(snr) + 1;
2320                                         if (tmp > est)
2321                                                   est = tmp;
2322                               }
2323 
2324                               ie = wpa_scan_get_ie(res, WLAN_EID_VHT_OPERATION);
2325                               if (ie && ie[1] >= 1 &&
2326                                   (ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) {
2327                                         tmp = max_vht80_rate(snr) + 1;
2328                                         if (tmp > est)
2329                                                   est = tmp;
2330                               }
2331                     }
2332           }
2333 
2334           /* TODO: channel utilization and AP load (e.g., from AP Beacon) */
2335 
2336           res->est_throughput = est;
2337 }
2338 
2339 
2340 /**
2341  * wpa_supplicant_get_scan_results - Get scan results
2342  * @wpa_s: Pointer to wpa_supplicant data
2343  * @info: Information about what was scanned or %NULL if not available
2344  * @new_scan: Whether a new scan was performed
2345  * Returns: Scan results, %NULL on failure
2346  *
2347  * This function request the current scan results from the driver and updates
2348  * the local BSS list wpa_s->bss. The caller is responsible for freeing the
2349  * results with wpa_scan_results_free().
2350  */
2351 struct wpa_scan_results *
wpa_supplicant_get_scan_results(struct wpa_supplicant * wpa_s,struct scan_info * info,int new_scan)2352 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
2353                                         struct scan_info *info, int new_scan)
2354 {
2355           struct wpa_scan_results *scan_res;
2356           size_t i;
2357           int (*compar)(const void *, const void *) = wpa_scan_result_compar;
2358 
2359           scan_res = wpa_drv_get_scan_results2(wpa_s);
2360           if (scan_res == NULL) {
2361                     wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
2362                     return NULL;
2363           }
2364           if (scan_res->fetch_time.sec == 0) {
2365                     /*
2366                      * Make sure we have a valid timestamp if the driver wrapper
2367                      * does not set this.
2368                      */
2369                     os_get_reltime(&scan_res->fetch_time);
2370           }
2371           filter_scan_res(wpa_s, scan_res);
2372 
2373           for (i = 0; i < scan_res->num; i++) {
2374                     struct wpa_scan_res *scan_res_item = scan_res->res[i];
2375 
2376                     scan_snr(scan_res_item);
2377                     scan_est_throughput(wpa_s, scan_res_item);
2378           }
2379 
2380 #ifdef CONFIG_WPS
2381           if (wpas_wps_searching(wpa_s)) {
2382                     wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS "
2383                               "provisioning rules");
2384                     compar = wpa_scan_result_wps_compar;
2385           }
2386 #endif /* CONFIG_WPS */
2387 
2388           if (scan_res->res) {
2389                     qsort(scan_res->res, scan_res->num,
2390                           sizeof(struct wpa_scan_res *), compar);
2391           }
2392           dump_scan_res(scan_res);
2393 
2394           if (wpa_s->ignore_post_flush_scan_res) {
2395                     /* FLUSH command aborted an ongoing scan and these are the
2396                      * results from the aborted scan. Do not process the results to
2397                      * maintain flushed state. */
2398                     wpa_dbg(wpa_s, MSG_DEBUG,
2399                               "Do not update BSS table based on pending post-FLUSH scan results");
2400                     wpa_s->ignore_post_flush_scan_res = 0;
2401                     return scan_res;
2402           }
2403 
2404           wpa_bss_update_start(wpa_s);
2405           for (i = 0; i < scan_res->num; i++)
2406                     wpa_bss_update_scan_res(wpa_s, scan_res->res[i],
2407                                                   &scan_res->fetch_time);
2408           wpa_bss_update_end(wpa_s, info, new_scan);
2409 
2410           return scan_res;
2411 }
2412 
2413 
2414 /**
2415  * wpa_supplicant_update_scan_results - Update scan results from the driver
2416  * @wpa_s: Pointer to wpa_supplicant data
2417  * Returns: 0 on success, -1 on failure
2418  *
2419  * This function updates the BSS table within wpa_supplicant based on the
2420  * currently available scan results from the driver without requesting a new
2421  * scan. This is used in cases where the driver indicates an association
2422  * (including roaming within ESS) and wpa_supplicant does not yet have the
2423  * needed information to complete the connection (e.g., to perform validation
2424  * steps in 4-way handshake).
2425  */
wpa_supplicant_update_scan_results(struct wpa_supplicant * wpa_s)2426 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s)
2427 {
2428           struct wpa_scan_results *scan_res;
2429           scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
2430           if (scan_res == NULL)
2431                     return -1;
2432           wpa_scan_results_free(scan_res);
2433 
2434           return 0;
2435 }
2436 
2437 
2438 /**
2439  * scan_only_handler - Reports scan results
2440  */
scan_only_handler(struct wpa_supplicant * wpa_s,struct wpa_scan_results * scan_res)2441 void scan_only_handler(struct wpa_supplicant *wpa_s,
2442                            struct wpa_scan_results *scan_res)
2443 {
2444           wpa_dbg(wpa_s, MSG_DEBUG, "Scan-only results received");
2445           if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
2446               wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
2447                     wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
2448                                    wpa_s->manual_scan_id);
2449                     wpa_s->manual_scan_use_id = 0;
2450           } else {
2451                     wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
2452           }
2453           wpas_notify_scan_results(wpa_s);
2454           wpas_notify_scan_done(wpa_s, 1);
2455           if (wpa_s->scan_work) {
2456                     struct wpa_radio_work *work = wpa_s->scan_work;
2457                     wpa_s->scan_work = NULL;
2458                     radio_work_done(work);
2459           }
2460 
2461           if (wpa_s->wpa_state == WPA_SCANNING)
2462                     wpa_supplicant_set_state(wpa_s, wpa_s->scan_prev_wpa_state);
2463 }
2464 
2465 
wpas_scan_scheduled(struct wpa_supplicant * wpa_s)2466 int wpas_scan_scheduled(struct wpa_supplicant *wpa_s)
2467 {
2468           return eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL);
2469 }
2470 
2471 
2472 struct wpa_driver_scan_params *
wpa_scan_clone_params(const struct wpa_driver_scan_params * src)2473 wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
2474 {
2475           struct wpa_driver_scan_params *params;
2476           size_t i;
2477           u8 *n;
2478 
2479           params = os_zalloc(sizeof(*params));
2480           if (params == NULL)
2481                     return NULL;
2482 
2483           for (i = 0; i < src->num_ssids; i++) {
2484                     if (src->ssids[i].ssid) {
2485                               n = os_memdup(src->ssids[i].ssid,
2486                                               src->ssids[i].ssid_len);
2487                               if (n == NULL)
2488                                         goto failed;
2489                               params->ssids[i].ssid = n;
2490                               params->ssids[i].ssid_len = src->ssids[i].ssid_len;
2491                     }
2492           }
2493           params->num_ssids = src->num_ssids;
2494 
2495           if (src->extra_ies) {
2496                     n = os_memdup(src->extra_ies, src->extra_ies_len);
2497                     if (n == NULL)
2498                               goto failed;
2499                     params->extra_ies = n;
2500                     params->extra_ies_len = src->extra_ies_len;
2501           }
2502 
2503           if (src->freqs) {
2504                     int len = int_array_len(src->freqs);
2505                     params->freqs = os_memdup(src->freqs, (len + 1) * sizeof(int));
2506                     if (params->freqs == NULL)
2507                               goto failed;
2508           }
2509 
2510           if (src->filter_ssids) {
2511                     params->filter_ssids = os_memdup(src->filter_ssids,
2512                                                              sizeof(*params->filter_ssids) *
2513                                                              src->num_filter_ssids);
2514                     if (params->filter_ssids == NULL)
2515                               goto failed;
2516                     params->num_filter_ssids = src->num_filter_ssids;
2517           }
2518 
2519           params->filter_rssi = src->filter_rssi;
2520           params->p2p_probe = src->p2p_probe;
2521           params->only_new_results = src->only_new_results;
2522           params->low_priority = src->low_priority;
2523           params->duration = src->duration;
2524           params->duration_mandatory = src->duration_mandatory;
2525           params->oce_scan = src->oce_scan;
2526 
2527           if (src->sched_scan_plans_num > 0) {
2528                     params->sched_scan_plans =
2529                               os_memdup(src->sched_scan_plans,
2530                                           sizeof(*src->sched_scan_plans) *
2531                                           src->sched_scan_plans_num);
2532                     if (!params->sched_scan_plans)
2533                               goto failed;
2534 
2535                     params->sched_scan_plans_num = src->sched_scan_plans_num;
2536           }
2537 
2538           if (src->mac_addr_rand) {
2539                     params->mac_addr_rand = src->mac_addr_rand;
2540 
2541                     if (src->mac_addr && src->mac_addr_mask) {
2542                               u8 *mac_addr;
2543 
2544                               mac_addr = os_malloc(2 * ETH_ALEN);
2545                               if (!mac_addr)
2546                                         goto failed;
2547 
2548                               os_memcpy(mac_addr, src->mac_addr, ETH_ALEN);
2549                               os_memcpy(mac_addr + ETH_ALEN, src->mac_addr_mask,
2550                                           ETH_ALEN);
2551                               params->mac_addr = mac_addr;
2552                               params->mac_addr_mask = mac_addr + ETH_ALEN;
2553                     }
2554           }
2555 
2556           if (src->bssid) {
2557                     u8 *bssid;
2558 
2559                     bssid = os_memdup(src->bssid, ETH_ALEN);
2560                     if (!bssid)
2561                               goto failed;
2562                     params->bssid = bssid;
2563           }
2564 
2565           params->relative_rssi_set = src->relative_rssi_set;
2566           params->relative_rssi = src->relative_rssi;
2567           params->relative_adjust_band = src->relative_adjust_band;
2568           params->relative_adjust_rssi = src->relative_adjust_rssi;
2569           return params;
2570 
2571 failed:
2572           wpa_scan_free_params(params);
2573           return NULL;
2574 }
2575 
2576 
wpa_scan_free_params(struct wpa_driver_scan_params * params)2577 void wpa_scan_free_params(struct wpa_driver_scan_params *params)
2578 {
2579           size_t i;
2580 
2581           if (params == NULL)
2582                     return;
2583 
2584           for (i = 0; i < params->num_ssids; i++)
2585                     os_free((u8 *) params->ssids[i].ssid);
2586           os_free((u8 *) params->extra_ies);
2587           os_free(params->freqs);
2588           os_free(params->filter_ssids);
2589           os_free(params->sched_scan_plans);
2590 
2591           /*
2592            * Note: params->mac_addr_mask points to same memory allocation and
2593            * must not be freed separately.
2594            */
2595           os_free((u8 *) params->mac_addr);
2596 
2597           os_free((u8 *) params->bssid);
2598 
2599           os_free(params);
2600 }
2601 
2602 
wpas_start_pno(struct wpa_supplicant * wpa_s)2603 int wpas_start_pno(struct wpa_supplicant *wpa_s)
2604 {
2605           int ret, prio;
2606           size_t i, num_ssid, num_match_ssid;
2607           struct wpa_ssid *ssid;
2608           struct wpa_driver_scan_params params;
2609           struct sched_scan_plan scan_plan;
2610           unsigned int max_sched_scan_ssids;
2611 
2612           if (!wpa_s->sched_scan_supported)
2613                     return -1;
2614 
2615           if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS)
2616                     max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS;
2617           else
2618                     max_sched_scan_ssids = wpa_s->max_sched_scan_ssids;
2619           if (max_sched_scan_ssids < 1)
2620                     return -1;
2621 
2622           if (wpa_s->pno || wpa_s->pno_sched_pending)
2623                     return 0;
2624 
2625           if ((wpa_s->wpa_state > WPA_SCANNING) &&
2626               (wpa_s->wpa_state < WPA_COMPLETED)) {
2627                     wpa_printf(MSG_ERROR, "PNO: In assoc process");
2628                     return -EAGAIN;
2629           }
2630 
2631           if (wpa_s->wpa_state == WPA_SCANNING) {
2632                     wpa_supplicant_cancel_scan(wpa_s);
2633                     if (wpa_s->sched_scanning) {
2634                               wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
2635                                            "ongoing sched scan");
2636                               wpa_supplicant_cancel_sched_scan(wpa_s);
2637                               wpa_s->pno_sched_pending = 1;
2638                               return 0;
2639                     }
2640           }
2641 
2642           if (wpa_s->sched_scan_stop_req) {
2643                     wpa_printf(MSG_DEBUG,
2644                                  "Schedule PNO after previous sched scan has stopped");
2645                     wpa_s->pno_sched_pending = 1;
2646                     return 0;
2647           }
2648 
2649           os_memset(&params, 0, sizeof(params));
2650 
2651           num_ssid = num_match_ssid = 0;
2652           ssid = wpa_s->conf->ssid;
2653           while (ssid) {
2654                     if (!wpas_network_disabled(wpa_s, ssid)) {
2655                               num_match_ssid++;
2656                               if (ssid->scan_ssid)
2657                                         num_ssid++;
2658                     }
2659                     ssid = ssid->next;
2660           }
2661 
2662           if (num_match_ssid == 0) {
2663                     wpa_printf(MSG_DEBUG, "PNO: No configured SSIDs");
2664                     return -1;
2665           }
2666 
2667           if (num_match_ssid > num_ssid) {
2668                     params.num_ssids++; /* wildcard */
2669                     num_ssid++;
2670           }
2671 
2672           if (num_ssid > max_sched_scan_ssids) {
2673                     wpa_printf(MSG_DEBUG, "PNO: Use only the first %u SSIDs from "
2674                                  "%u", max_sched_scan_ssids, (unsigned int) num_ssid);
2675                     num_ssid = max_sched_scan_ssids;
2676           }
2677 
2678           if (num_match_ssid > wpa_s->max_match_sets) {
2679                     num_match_ssid = wpa_s->max_match_sets;
2680                     wpa_dbg(wpa_s, MSG_DEBUG, "PNO: Too many SSIDs to match");
2681           }
2682           params.filter_ssids = os_calloc(num_match_ssid,
2683                                                   sizeof(struct wpa_driver_scan_filter));
2684           if (params.filter_ssids == NULL)
2685                     return -1;
2686 
2687           i = 0;
2688           prio = 0;
2689           ssid = wpa_s->conf->pssid[prio];
2690           while (ssid) {
2691                     if (!wpas_network_disabled(wpa_s, ssid)) {
2692                               if (ssid->scan_ssid && params.num_ssids < num_ssid) {
2693                                         params.ssids[params.num_ssids].ssid =
2694                                                   ssid->ssid;
2695                                         params.ssids[params.num_ssids].ssid_len =
2696                                                    ssid->ssid_len;
2697                                         params.num_ssids++;
2698                               }
2699                               os_memcpy(params.filter_ssids[i].ssid, ssid->ssid,
2700                                           ssid->ssid_len);
2701                               params.filter_ssids[i].ssid_len = ssid->ssid_len;
2702                               params.num_filter_ssids++;
2703                               i++;
2704                               if (i == num_match_ssid)
2705                                         break;
2706                     }
2707                     if (ssid->pnext)
2708                               ssid = ssid->pnext;
2709                     else if (prio + 1 == wpa_s->conf->num_prio)
2710                               break;
2711                     else
2712                               ssid = wpa_s->conf->pssid[++prio];
2713           }
2714 
2715           if (wpa_s->conf->filter_rssi)
2716                     params.filter_rssi = wpa_s->conf->filter_rssi;
2717 
2718           if (wpa_s->sched_scan_plans_num) {
2719                     params.sched_scan_plans = wpa_s->sched_scan_plans;
2720                     params.sched_scan_plans_num = wpa_s->sched_scan_plans_num;
2721           } else {
2722                     /* Set one scan plan that will run infinitely */
2723                     if (wpa_s->conf->sched_scan_interval)
2724                               scan_plan.interval = wpa_s->conf->sched_scan_interval;
2725                     else
2726                               scan_plan.interval = 10;
2727 
2728                     scan_plan.iterations = 0;
2729                     params.sched_scan_plans = &scan_plan;
2730                     params.sched_scan_plans_num = 1;
2731           }
2732 
2733           params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay;
2734 
2735           if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) {
2736                     wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels");
2737                     params.freqs = wpa_s->manual_sched_scan_freqs;
2738           }
2739 
2740           if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) &&
2741               wpa_s->wpa_state <= WPA_SCANNING) {
2742                     params.mac_addr_rand = 1;
2743                     if (wpa_s->mac_addr_pno) {
2744                               params.mac_addr = wpa_s->mac_addr_pno;
2745                               params.mac_addr_mask = wpa_s->mac_addr_pno + ETH_ALEN;
2746                     }
2747           }
2748 
2749           wpa_scan_set_relative_rssi_params(wpa_s, &params);
2750 
2751           ret = wpa_supplicant_start_sched_scan(wpa_s, &params);
2752           os_free(params.filter_ssids);
2753           if (ret == 0)
2754                     wpa_s->pno = 1;
2755           else
2756                     wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
2757           return ret;
2758 }
2759 
2760 
wpas_stop_pno(struct wpa_supplicant * wpa_s)2761 int wpas_stop_pno(struct wpa_supplicant *wpa_s)
2762 {
2763           int ret = 0;
2764 
2765           if (!wpa_s->pno)
2766                     return 0;
2767 
2768           ret = wpa_supplicant_stop_sched_scan(wpa_s);
2769           wpa_s->sched_scan_stop_req = 1;
2770 
2771           wpa_s->pno = 0;
2772           wpa_s->pno_sched_pending = 0;
2773 
2774           if (wpa_s->wpa_state == WPA_SCANNING)
2775                     wpa_supplicant_req_scan(wpa_s, 0, 0);
2776 
2777           return ret;
2778 }
2779 
2780 
wpas_mac_addr_rand_scan_clear(struct wpa_supplicant * wpa_s,unsigned int type)2781 void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
2782                                             unsigned int type)
2783 {
2784           type &= MAC_ADDR_RAND_ALL;
2785           wpa_s->mac_addr_rand_enable &= ~type;
2786 
2787           if (type & MAC_ADDR_RAND_SCAN) {
2788                     os_free(wpa_s->mac_addr_scan);
2789                     wpa_s->mac_addr_scan = NULL;
2790           }
2791 
2792           if (type & MAC_ADDR_RAND_SCHED_SCAN) {
2793                     os_free(wpa_s->mac_addr_sched_scan);
2794                     wpa_s->mac_addr_sched_scan = NULL;
2795           }
2796 
2797           if (type & MAC_ADDR_RAND_PNO) {
2798                     os_free(wpa_s->mac_addr_pno);
2799                     wpa_s->mac_addr_pno = NULL;
2800           }
2801 }
2802 
2803 
wpas_mac_addr_rand_scan_set(struct wpa_supplicant * wpa_s,unsigned int type,const u8 * addr,const u8 * mask)2804 int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
2805                                         unsigned int type, const u8 *addr,
2806                                         const u8 *mask)
2807 {
2808           u8 *tmp = NULL;
2809 
2810           if ((wpa_s->mac_addr_rand_supported & type) != type ) {
2811                     wpa_printf(MSG_INFO,
2812                                  "scan: MAC randomization type %u != supported=%u",
2813                                  type, wpa_s->mac_addr_rand_supported);
2814                     return -1;
2815           }
2816 
2817           wpas_mac_addr_rand_scan_clear(wpa_s, type);
2818 
2819           if (addr) {
2820                     tmp = os_malloc(2 * ETH_ALEN);
2821                     if (!tmp)
2822                               return -1;
2823                     os_memcpy(tmp, addr, ETH_ALEN);
2824                     os_memcpy(tmp + ETH_ALEN, mask, ETH_ALEN);
2825           }
2826 
2827           if (type == MAC_ADDR_RAND_SCAN) {
2828                     wpa_s->mac_addr_scan = tmp;
2829           } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
2830                     wpa_s->mac_addr_sched_scan = tmp;
2831           } else if (type == MAC_ADDR_RAND_PNO) {
2832                     wpa_s->mac_addr_pno = tmp;
2833           } else {
2834                     wpa_printf(MSG_INFO,
2835                                  "scan: Invalid MAC randomization type=0x%x",
2836                                  type);
2837                     os_free(tmp);
2838                     return -1;
2839           }
2840 
2841           wpa_s->mac_addr_rand_enable |= type;
2842           return 0;
2843 }
2844 
2845 
wpas_abort_ongoing_scan(struct wpa_supplicant * wpa_s)2846 int wpas_abort_ongoing_scan(struct wpa_supplicant *wpa_s)
2847 {
2848           struct wpa_radio_work *work;
2849           struct wpa_radio *radio = wpa_s->radio;
2850 
2851           dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
2852                     if (work->wpa_s != wpa_s || !work->started ||
2853                         (os_strcmp(work->type, "scan") != 0 &&
2854                          os_strcmp(work->type, "p2p-scan") != 0))
2855                               continue;
2856                     wpa_dbg(wpa_s, MSG_DEBUG, "Abort an ongoing scan");
2857                     return wpa_drv_abort_scan(wpa_s, wpa_s->curr_scan_cookie);
2858           }
2859 
2860           wpa_dbg(wpa_s, MSG_DEBUG, "No ongoing scan/p2p-scan found to abort");
2861           return -1;
2862 }
2863 
2864 
wpas_sched_scan_plans_set(struct wpa_supplicant * wpa_s,const char * cmd)2865 int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd)
2866 {
2867           struct sched_scan_plan *scan_plans = NULL;
2868           const char *token, *context = NULL;
2869           unsigned int num = 0;
2870 
2871           if (!cmd)
2872                     return -1;
2873 
2874           if (!cmd[0]) {
2875                     wpa_printf(MSG_DEBUG, "Clear sched scan plans");
2876                     os_free(wpa_s->sched_scan_plans);
2877                     wpa_s->sched_scan_plans = NULL;
2878                     wpa_s->sched_scan_plans_num = 0;
2879                     return 0;
2880           }
2881 
2882           while ((token = cstr_token(cmd, " ", &context))) {
2883                     int ret;
2884                     struct sched_scan_plan *scan_plan, *n;
2885 
2886                     n = os_realloc_array(scan_plans, num + 1, sizeof(*scan_plans));
2887                     if (!n)
2888                               goto fail;
2889 
2890                     scan_plans = n;
2891                     scan_plan = &scan_plans[num];
2892                     num++;
2893 
2894                     ret = sscanf(token, "%u:%u", &scan_plan->interval,
2895                                    &scan_plan->iterations);
2896                     if (ret <= 0 || ret > 2 || !scan_plan->interval) {
2897                               wpa_printf(MSG_ERROR,
2898                                            "Invalid sched scan plan input: %s", token);
2899                               goto fail;
2900                     }
2901 
2902                     if (scan_plan->interval > wpa_s->max_sched_scan_plan_interval) {
2903                               wpa_printf(MSG_WARNING,
2904                                            "scan plan %u: Scan interval too long(%u), use the maximum allowed(%u)",
2905                                            num, scan_plan->interval,
2906                                            wpa_s->max_sched_scan_plan_interval);
2907                               scan_plan->interval =
2908                                         wpa_s->max_sched_scan_plan_interval;
2909                     }
2910 
2911                     if (ret == 1) {
2912                               scan_plan->iterations = 0;
2913                               break;
2914                     }
2915 
2916                     if (!scan_plan->iterations) {
2917                               wpa_printf(MSG_ERROR,
2918                                            "scan plan %u: Number of iterations cannot be zero",
2919                                            num);
2920                               goto fail;
2921                     }
2922 
2923                     if (scan_plan->iterations >
2924                         wpa_s->max_sched_scan_plan_iterations) {
2925                               wpa_printf(MSG_WARNING,
2926                                            "scan plan %u: Too many iterations(%u), use the maximum allowed(%u)",
2927                                            num, scan_plan->iterations,
2928                                            wpa_s->max_sched_scan_plan_iterations);
2929                               scan_plan->iterations =
2930                                         wpa_s->max_sched_scan_plan_iterations;
2931                     }
2932 
2933                     wpa_printf(MSG_DEBUG,
2934                                  "scan plan %u: interval=%u iterations=%u",
2935                                  num, scan_plan->interval, scan_plan->iterations);
2936           }
2937 
2938           if (!scan_plans) {
2939                     wpa_printf(MSG_ERROR, "Invalid scan plans entry");
2940                     goto fail;
2941           }
2942 
2943           if (cstr_token(cmd, " ", &context) || scan_plans[num - 1].iterations) {
2944                     wpa_printf(MSG_ERROR,
2945                                  "All scan plans but the last must specify a number of iterations");
2946                     goto fail;
2947           }
2948 
2949           wpa_printf(MSG_DEBUG, "scan plan %u (last plan): interval=%u",
2950                        num, scan_plans[num - 1].interval);
2951 
2952           if (num > wpa_s->max_sched_scan_plans) {
2953                     wpa_printf(MSG_WARNING,
2954                                  "Too many scheduled scan plans (only %u supported)",
2955                                  wpa_s->max_sched_scan_plans);
2956                     wpa_printf(MSG_WARNING,
2957                                  "Use only the first %u scan plans, and the last one (in infinite loop)",
2958                                  wpa_s->max_sched_scan_plans - 1);
2959                     os_memcpy(&scan_plans[wpa_s->max_sched_scan_plans - 1],
2960                                 &scan_plans[num - 1], sizeof(*scan_plans));
2961                     num = wpa_s->max_sched_scan_plans;
2962           }
2963 
2964           os_free(wpa_s->sched_scan_plans);
2965           wpa_s->sched_scan_plans = scan_plans;
2966           wpa_s->sched_scan_plans_num = num;
2967 
2968           return 0;
2969 
2970 fail:
2971           os_free(scan_plans);
2972           wpa_printf(MSG_ERROR, "invalid scan plans list");
2973           return -1;
2974 }
2975 
2976 
2977 /**
2978  * wpas_scan_reset_sched_scan - Reset sched_scan state
2979  * @wpa_s: Pointer to wpa_supplicant data
2980  *
2981  * This function is used to cancel a running scheduled scan and to reset an
2982  * internal scan state to continue with a regular scan on the following
2983  * wpa_supplicant_req_scan() calls.
2984  */
wpas_scan_reset_sched_scan(struct wpa_supplicant * wpa_s)2985 void wpas_scan_reset_sched_scan(struct wpa_supplicant *wpa_s)
2986 {
2987           wpa_s->normal_scans = 0;
2988           if (wpa_s->sched_scanning) {
2989                     wpa_s->sched_scan_timed_out = 0;
2990                     wpa_s->prev_sched_ssid = NULL;
2991                     wpa_supplicant_cancel_sched_scan(wpa_s);
2992           }
2993 }
2994 
2995 
wpas_scan_restart_sched_scan(struct wpa_supplicant * wpa_s)2996 void wpas_scan_restart_sched_scan(struct wpa_supplicant *wpa_s)
2997 {
2998           /* simulate timeout to restart the sched scan */
2999           wpa_s->sched_scan_timed_out = 1;
3000           wpa_s->prev_sched_ssid = NULL;
3001           wpa_supplicant_cancel_sched_scan(wpa_s);
3002 }
3003