1 /* 2 * WPA Supplicant - Scanning 3 * Copyright (c) 2003-2012, 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 "config.h" 15 #include "wpa_supplicant_i.h" 16 #include "driver_i.h" 17 #include "wps_supplicant.h" 18 #include "p2p_supplicant.h" 19 #include "p2p/p2p.h" 20 #include "hs20_supplicant.h" 21 #include "notify.h" 22 #include "bss.h" 23 #include "scan.h" 24 25 26 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s) 27 { 28 struct wpa_ssid *ssid; 29 union wpa_event_data data; 30 31 ssid = wpa_supplicant_get_ssid(wpa_s); 32 if (ssid == NULL) 33 return; 34 35 if (wpa_s->current_ssid == NULL) { 36 wpa_s->current_ssid = ssid; 37 if (wpa_s->current_ssid != NULL) 38 wpas_notify_network_changed(wpa_s); 39 } 40 wpa_supplicant_initiate_eapol(wpa_s); 41 wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with a configured " 42 "network - generating associated event"); 43 os_memset(&data, 0, sizeof(data)); 44 wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data); 45 } 46 47 48 #ifdef CONFIG_WPS 49 static int wpas_wps_in_use(struct wpa_supplicant *wpa_s, 50 enum wps_request_type *req_type) 51 { 52 struct wpa_ssid *ssid; 53 int wps = 0; 54 55 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 56 if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS)) 57 continue; 58 59 wps = 1; 60 *req_type = wpas_wps_get_req_type(ssid); 61 if (!ssid->eap.phase1) 62 continue; 63 64 if (os_strstr(ssid->eap.phase1, "pbc=1")) 65 return 2; 66 } 67 68 #ifdef CONFIG_P2P 69 if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p && 70 !wpa_s->conf->p2p_disabled) { 71 wpa_s->wps->dev.p2p = 1; 72 if (!wps) { 73 wps = 1; 74 *req_type = WPS_REQ_ENROLLEE_INFO; 75 } 76 } 77 #endif /* CONFIG_P2P */ 78 79 return wps; 80 } 81 #endif /* CONFIG_WPS */ 82 83 84 /** 85 * wpa_supplicant_enabled_networks - Check whether there are enabled networks 86 * @wpa_s: Pointer to wpa_supplicant data 87 * Returns: 0 if no networks are enabled, >0 if networks are enabled 88 * 89 * This function is used to figure out whether any networks (or Interworking 90 * with enabled credentials and auto_interworking) are present in the current 91 * configuration. 92 */ 93 int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s) 94 { 95 struct wpa_ssid *ssid = wpa_s->conf->ssid; 96 int count = 0, disabled = 0; 97 while (ssid) { 98 if (!wpas_network_disabled(wpa_s, ssid)) 99 count++; 100 else 101 disabled++; 102 ssid = ssid->next; 103 } 104 if (wpa_s->conf->cred && wpa_s->conf->interworking && 105 wpa_s->conf->auto_interworking) 106 count++; 107 if (count == 0 && disabled > 0) { 108 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks (%d disabled " 109 "networks)", disabled); 110 } 111 return count; 112 } 113 114 115 static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s, 116 struct wpa_ssid *ssid) 117 { 118 while (ssid) { 119 if (!wpas_network_disabled(wpa_s, ssid)) 120 break; 121 ssid = ssid->next; 122 } 123 124 /* ap_scan=2 mode - try to associate with each SSID. */ 125 if (ssid == NULL) { 126 wpa_dbg(wpa_s, MSG_DEBUG, "wpa_supplicant_assoc_try: Reached " 127 "end of scan list - go back to beginning"); 128 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 129 wpa_supplicant_req_scan(wpa_s, 0, 0); 130 return; 131 } 132 if (ssid->next) { 133 /* Continue from the next SSID on the next attempt. */ 134 wpa_s->prev_scan_ssid = ssid; 135 } else { 136 /* Start from the beginning of the SSID list. */ 137 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 138 } 139 wpa_supplicant_associate(wpa_s, NULL, ssid); 140 } 141 142 143 static int int_array_len(const int *a) 144 { 145 int i; 146 for (i = 0; a && a[i]; i++) 147 ; 148 return i; 149 } 150 151 152 static void int_array_concat(int **res, const int *a) 153 { 154 int reslen, alen, i; 155 int *n; 156 157 reslen = int_array_len(*res); 158 alen = int_array_len(a); 159 160 n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); 161 if (n == NULL) { 162 os_free(*res); 163 *res = NULL; 164 return; 165 } 166 for (i = 0; i <= alen; i++) 167 n[reslen + i] = a[i]; 168 *res = n; 169 } 170 171 172 static int freq_cmp(const void *a, const void *b) 173 { 174 int _a = *(int *) a; 175 int _b = *(int *) b; 176 177 if (_a == 0) 178 return 1; 179 if (_b == 0) 180 return -1; 181 return _a - _b; 182 } 183 184 185 static void int_array_sort_unique(int *a) 186 { 187 int alen; 188 int i, j; 189 190 if (a == NULL) 191 return; 192 193 alen = int_array_len(a); 194 qsort(a, alen, sizeof(int), freq_cmp); 195 196 i = 0; 197 j = 1; 198 while (a[i] && a[j]) { 199 if (a[i] == a[j]) { 200 j++; 201 continue; 202 } 203 a[++i] = a[j++]; 204 } 205 if (a[i]) 206 i++; 207 a[i] = 0; 208 } 209 210 211 /** 212 * wpa_supplicant_trigger_scan - Request driver to start a scan 213 * @wpa_s: Pointer to wpa_supplicant data 214 * @params: Scan parameters 215 * Returns: 0 on success, -1 on failure 216 */ 217 int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, 218 struct wpa_driver_scan_params *params) 219 { 220 int ret; 221 222 wpa_supplicant_notify_scanning(wpa_s, 1); 223 224 ret = wpa_drv_scan(wpa_s, params); 225 if (ret) { 226 wpa_supplicant_notify_scanning(wpa_s, 0); 227 wpas_notify_scan_done(wpa_s, 0); 228 } else { 229 wpa_s->scan_runs++; 230 wpa_s->normal_scans++; 231 } 232 233 return ret; 234 } 235 236 237 static void 238 wpa_supplicant_delayed_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 239 { 240 struct wpa_supplicant *wpa_s = eloop_ctx; 241 242 wpa_dbg(wpa_s, MSG_DEBUG, "Starting delayed sched scan"); 243 244 if (wpa_supplicant_req_sched_scan(wpa_s)) 245 wpa_supplicant_req_scan(wpa_s, 0, 0); 246 } 247 248 249 static void 250 wpa_supplicant_sched_scan_timeout(void *eloop_ctx, void *timeout_ctx) 251 { 252 struct wpa_supplicant *wpa_s = eloop_ctx; 253 254 wpa_dbg(wpa_s, MSG_DEBUG, "Sched scan timeout - stopping it"); 255 256 wpa_s->sched_scan_timed_out = 1; 257 wpa_supplicant_cancel_sched_scan(wpa_s); 258 } 259 260 261 static int 262 wpa_supplicant_start_sched_scan(struct wpa_supplicant *wpa_s, 263 struct wpa_driver_scan_params *params, 264 int interval) 265 { 266 int ret; 267 268 wpa_supplicant_notify_scanning(wpa_s, 1); 269 ret = wpa_drv_sched_scan(wpa_s, params, interval * 1000); 270 if (ret) 271 wpa_supplicant_notify_scanning(wpa_s, 0); 272 else 273 wpa_s->sched_scanning = 1; 274 275 return ret; 276 } 277 278 279 static int wpa_supplicant_stop_sched_scan(struct wpa_supplicant *wpa_s) 280 { 281 int ret; 282 283 ret = wpa_drv_stop_sched_scan(wpa_s); 284 if (ret) { 285 wpa_dbg(wpa_s, MSG_DEBUG, "stopping sched_scan failed!"); 286 /* TODO: what to do if stopping fails? */ 287 return -1; 288 } 289 290 return ret; 291 } 292 293 294 static struct wpa_driver_scan_filter * 295 wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids) 296 { 297 struct wpa_driver_scan_filter *ssids; 298 struct wpa_ssid *ssid; 299 size_t count; 300 301 *num_ssids = 0; 302 if (!conf->filter_ssids) 303 return NULL; 304 305 for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) { 306 if (ssid->ssid && ssid->ssid_len) 307 count++; 308 } 309 if (count == 0) 310 return NULL; 311 ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter)); 312 if (ssids == NULL) 313 return NULL; 314 315 for (ssid = conf->ssid; ssid; ssid = ssid->next) { 316 if (!ssid->ssid || !ssid->ssid_len) 317 continue; 318 os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len); 319 ssids[*num_ssids].ssid_len = ssid->ssid_len; 320 (*num_ssids)++; 321 } 322 323 return ssids; 324 } 325 326 327 static void wpa_supplicant_optimize_freqs( 328 struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params) 329 { 330 #ifdef CONFIG_P2P 331 if (params->freqs == NULL && wpa_s->p2p_in_provisioning && 332 wpa_s->go_params) { 333 /* Optimize provisioning state scan based on GO information */ 334 if (wpa_s->p2p_in_provisioning < 5 && 335 wpa_s->go_params->freq > 0) { 336 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO " 337 "preferred frequency %d MHz", 338 wpa_s->go_params->freq); 339 params->freqs = os_zalloc(2 * sizeof(int)); 340 if (params->freqs) 341 params->freqs[0] = wpa_s->go_params->freq; 342 } else if (wpa_s->p2p_in_provisioning < 8 && 343 wpa_s->go_params->freq_list[0]) { 344 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only common " 345 "channels"); 346 int_array_concat(¶ms->freqs, 347 wpa_s->go_params->freq_list); 348 if (params->freqs) 349 int_array_sort_unique(params->freqs); 350 } 351 wpa_s->p2p_in_provisioning++; 352 } 353 #endif /* CONFIG_P2P */ 354 355 #ifdef CONFIG_WPS 356 if (params->freqs == NULL && wpa_s->after_wps && wpa_s->wps_freq) { 357 /* 358 * Optimize post-provisioning scan based on channel used 359 * during provisioning. 360 */ 361 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz " 362 "that was used during provisioning", wpa_s->wps_freq); 363 params->freqs = os_zalloc(2 * sizeof(int)); 364 if (params->freqs) 365 params->freqs[0] = wpa_s->wps_freq; 366 wpa_s->after_wps--; 367 } 368 369 if (params->freqs == NULL && wpa_s->known_wps_freq && wpa_s->wps_freq) 370 { 371 /* Optimize provisioning scan based on already known channel */ 372 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Scan only frequency %u MHz", 373 wpa_s->wps_freq); 374 params->freqs = os_zalloc(2 * sizeof(int)); 375 if (params->freqs) 376 params->freqs[0] = wpa_s->wps_freq; 377 wpa_s->known_wps_freq = 0; /* only do this once */ 378 } 379 #endif /* CONFIG_WPS */ 380 } 381 382 383 #ifdef CONFIG_INTERWORKING 384 static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s, 385 struct wpabuf *buf) 386 { 387 if (wpa_s->conf->interworking == 0) 388 return; 389 390 wpabuf_put_u8(buf, WLAN_EID_EXT_CAPAB); 391 wpabuf_put_u8(buf, 4); 392 wpabuf_put_u8(buf, 0x00); 393 wpabuf_put_u8(buf, 0x00); 394 wpabuf_put_u8(buf, 0x00); 395 wpabuf_put_u8(buf, 0x80); /* Bit 31 - Interworking */ 396 397 wpabuf_put_u8(buf, WLAN_EID_INTERWORKING); 398 wpabuf_put_u8(buf, is_zero_ether_addr(wpa_s->conf->hessid) ? 1 : 399 1 + ETH_ALEN); 400 wpabuf_put_u8(buf, wpa_s->conf->access_network_type); 401 /* No Venue Info */ 402 if (!is_zero_ether_addr(wpa_s->conf->hessid)) 403 wpabuf_put_data(buf, wpa_s->conf->hessid, ETH_ALEN); 404 } 405 #endif /* CONFIG_INTERWORKING */ 406 407 408 static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s) 409 { 410 struct wpabuf *extra_ie = NULL; 411 #ifdef CONFIG_WPS 412 int wps = 0; 413 enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO; 414 #endif /* CONFIG_WPS */ 415 416 #ifdef CONFIG_INTERWORKING 417 if (wpa_s->conf->interworking && 418 wpabuf_resize(&extra_ie, 100) == 0) 419 wpas_add_interworking_elements(wpa_s, extra_ie); 420 #endif /* CONFIG_INTERWORKING */ 421 422 #ifdef CONFIG_WPS 423 wps = wpas_wps_in_use(wpa_s, &req_type); 424 425 if (wps) { 426 struct wpabuf *wps_ie; 427 wps_ie = wps_build_probe_req_ie(wps == 2 ? DEV_PW_PUSHBUTTON : 428 DEV_PW_DEFAULT, 429 &wpa_s->wps->dev, 430 wpa_s->wps->uuid, req_type, 431 0, NULL); 432 if (wps_ie) { 433 if (wpabuf_resize(&extra_ie, wpabuf_len(wps_ie)) == 0) 434 wpabuf_put_buf(extra_ie, wps_ie); 435 wpabuf_free(wps_ie); 436 } 437 } 438 439 #ifdef CONFIG_P2P 440 if (wps) { 441 size_t ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); 442 if (wpabuf_resize(&extra_ie, ielen) == 0) 443 wpas_p2p_scan_ie(wpa_s, extra_ie); 444 } 445 #endif /* CONFIG_P2P */ 446 447 #endif /* CONFIG_WPS */ 448 449 return extra_ie; 450 } 451 452 453 #ifdef CONFIG_P2P 454 455 /* 456 * Check whether there are any enabled networks or credentials that could be 457 * used for a non-P2P connection. 458 */ 459 static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s) 460 { 461 struct wpa_ssid *ssid; 462 463 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 464 if (wpas_network_disabled(wpa_s, ssid)) 465 continue; 466 if (!ssid->p2p_group) 467 return 1; 468 } 469 470 if (wpa_s->conf->cred && wpa_s->conf->interworking && 471 wpa_s->conf->auto_interworking) 472 return 1; 473 474 return 0; 475 } 476 477 478 /* 479 * Find the operating frequency of any other virtual interface that is using 480 * the same radio concurrently. 481 */ 482 static int shared_vif_oper_freq(struct wpa_supplicant *wpa_s) 483 { 484 const char *rn, *rn2; 485 struct wpa_supplicant *ifs; 486 u8 bssid[ETH_ALEN]; 487 488 if (!wpa_s->driver->get_radio_name) 489 return -1; 490 491 rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv); 492 if (rn == NULL || rn[0] == '\0') 493 return -1; 494 495 for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) { 496 if (ifs == wpa_s || !ifs->driver->get_radio_name) 497 continue; 498 499 rn2 = ifs->driver->get_radio_name(ifs->drv_priv); 500 if (!rn2 || os_strcmp(rn, rn2) != 0) 501 continue; 502 503 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0) 504 continue; 505 506 if (ifs->current_ssid->mode == WPAS_MODE_AP || 507 ifs->current_ssid->mode == WPAS_MODE_P2P_GO) 508 return ifs->current_ssid->frequency; 509 if (wpa_drv_get_bssid(ifs, bssid) == 0) 510 return ifs->assoc_freq; 511 } 512 513 return 0; 514 } 515 516 #endif /* CONFIG_P2P */ 517 518 519 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx) 520 { 521 struct wpa_supplicant *wpa_s = eloop_ctx; 522 struct wpa_ssid *ssid; 523 enum scan_req_type scan_req = NORMAL_SCAN_REQ; 524 int ret; 525 struct wpabuf *extra_ie = NULL; 526 struct wpa_driver_scan_params params; 527 struct wpa_driver_scan_params *scan_params; 528 size_t max_ssids; 529 enum wpa_states prev_state; 530 531 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 532 wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - interface disabled"); 533 return; 534 } 535 536 if (wpa_s->disconnected && wpa_s->scan_req == NORMAL_SCAN_REQ) { 537 wpa_dbg(wpa_s, MSG_DEBUG, "Disconnected - do not scan"); 538 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 539 return; 540 } 541 542 if (!wpa_supplicant_enabled_networks(wpa_s) && 543 wpa_s->scan_req == NORMAL_SCAN_REQ) { 544 wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan"); 545 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 546 #ifdef CONFIG_P2P 547 wpa_s->sta_scan_pending = 0; 548 #endif /* CONFIG_P2P */ 549 return; 550 } 551 552 if (wpa_s->conf->ap_scan != 0 && 553 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)) { 554 wpa_dbg(wpa_s, MSG_DEBUG, "Using wired authentication - " 555 "overriding ap_scan configuration"); 556 wpa_s->conf->ap_scan = 0; 557 wpas_notify_ap_scan_changed(wpa_s); 558 } 559 560 if (wpa_s->conf->ap_scan == 0) { 561 wpa_supplicant_gen_assoc_event(wpa_s); 562 return; 563 } 564 565 #ifdef CONFIG_P2P 566 if (wpas_p2p_in_progress(wpa_s)) { 567 if (wpa_s->sta_scan_pending && 568 wpas_p2p_in_progress(wpa_s) == 2 && 569 wpa_s->global->p2p_cb_on_scan_complete) { 570 wpa_dbg(wpa_s, MSG_DEBUG, "Process pending station " 571 "mode scan during P2P search"); 572 } else { 573 wpa_dbg(wpa_s, MSG_DEBUG, "Delay station mode scan " 574 "while P2P operation is in progress"); 575 wpa_s->sta_scan_pending = 1; 576 wpa_supplicant_req_scan(wpa_s, 5, 0); 577 return; 578 } 579 } 580 #endif /* CONFIG_P2P */ 581 582 if (wpa_s->conf->ap_scan == 2) 583 max_ssids = 1; 584 else { 585 max_ssids = wpa_s->max_scan_ssids; 586 if (max_ssids > WPAS_MAX_SCAN_SSIDS) 587 max_ssids = WPAS_MAX_SCAN_SSIDS; 588 } 589 590 scan_req = wpa_s->scan_req; 591 wpa_s->scan_req = NORMAL_SCAN_REQ; 592 593 os_memset(¶ms, 0, sizeof(params)); 594 595 prev_state = wpa_s->wpa_state; 596 if (wpa_s->wpa_state == WPA_DISCONNECTED || 597 wpa_s->wpa_state == WPA_INACTIVE) 598 wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 599 600 /* 601 * If autoscan has set its own scanning parameters 602 */ 603 if (wpa_s->autoscan_params != NULL) { 604 scan_params = wpa_s->autoscan_params; 605 goto scan; 606 } 607 608 if (scan_req != MANUAL_SCAN_REQ && wpa_s->connect_without_scan) { 609 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 610 if (ssid == wpa_s->connect_without_scan) 611 break; 612 } 613 wpa_s->connect_without_scan = NULL; 614 if (ssid) { 615 wpa_printf(MSG_DEBUG, "Start a pre-selected network " 616 "without scan step"); 617 wpa_supplicant_associate(wpa_s, NULL, ssid); 618 return; 619 } 620 } 621 622 #ifdef CONFIG_P2P 623 if ((wpa_s->p2p_in_provisioning || wpa_s->show_group_started) && 624 wpa_s->go_params) { 625 wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during " 626 "P2P group formation"); 627 params.ssids[0].ssid = wpa_s->go_params->ssid; 628 params.ssids[0].ssid_len = wpa_s->go_params->ssid_len; 629 params.num_ssids = 1; 630 goto ssid_list_set; 631 } 632 #endif /* CONFIG_P2P */ 633 634 /* Find the starting point from which to continue scanning */ 635 ssid = wpa_s->conf->ssid; 636 if (wpa_s->prev_scan_ssid != WILDCARD_SSID_SCAN) { 637 while (ssid) { 638 if (ssid == wpa_s->prev_scan_ssid) { 639 ssid = ssid->next; 640 break; 641 } 642 ssid = ssid->next; 643 } 644 } 645 646 if (scan_req != MANUAL_SCAN_REQ && wpa_s->conf->ap_scan == 2) { 647 wpa_s->connect_without_scan = NULL; 648 wpa_s->prev_scan_wildcard = 0; 649 wpa_supplicant_assoc_try(wpa_s, ssid); 650 return; 651 } else if (wpa_s->conf->ap_scan == 2) { 652 /* 653 * User-initiated scan request in ap_scan == 2; scan with 654 * wildcard SSID. 655 */ 656 ssid = NULL; 657 } else { 658 struct wpa_ssid *start = ssid, *tssid; 659 int freqs_set = 0; 660 if (ssid == NULL && max_ssids > 1) 661 ssid = wpa_s->conf->ssid; 662 while (ssid) { 663 if (!wpas_network_disabled(wpa_s, ssid) && 664 ssid->scan_ssid) { 665 wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID", 666 ssid->ssid, ssid->ssid_len); 667 params.ssids[params.num_ssids].ssid = 668 ssid->ssid; 669 params.ssids[params.num_ssids].ssid_len = 670 ssid->ssid_len; 671 params.num_ssids++; 672 if (params.num_ssids + 1 >= max_ssids) 673 break; 674 } 675 ssid = ssid->next; 676 if (ssid == start) 677 break; 678 if (ssid == NULL && max_ssids > 1 && 679 start != wpa_s->conf->ssid) 680 ssid = wpa_s->conf->ssid; 681 } 682 683 for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) { 684 if (wpas_network_disabled(wpa_s, tssid)) 685 continue; 686 if ((params.freqs || !freqs_set) && tssid->scan_freq) { 687 int_array_concat(¶ms.freqs, 688 tssid->scan_freq); 689 } else { 690 os_free(params.freqs); 691 params.freqs = NULL; 692 } 693 freqs_set = 1; 694 } 695 int_array_sort_unique(params.freqs); 696 } 697 698 if (ssid && max_ssids == 1) { 699 /* 700 * If the driver is limited to 1 SSID at a time interleave 701 * wildcard SSID scans with specific SSID scans to avoid 702 * waiting a long time for a wildcard scan. 703 */ 704 if (!wpa_s->prev_scan_wildcard) { 705 params.ssids[0].ssid = NULL; 706 params.ssids[0].ssid_len = 0; 707 wpa_s->prev_scan_wildcard = 1; 708 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for " 709 "wildcard SSID (Interleave with specific)"); 710 } else { 711 wpa_s->prev_scan_ssid = ssid; 712 wpa_s->prev_scan_wildcard = 0; 713 wpa_dbg(wpa_s, MSG_DEBUG, 714 "Starting AP scan for specific SSID: %s", 715 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 716 } 717 } else if (ssid) { 718 /* max_ssids > 1 */ 719 720 wpa_s->prev_scan_ssid = ssid; 721 wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in " 722 "the scan request"); 723 params.num_ssids++; 724 } else { 725 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN; 726 params.num_ssids++; 727 wpa_dbg(wpa_s, MSG_DEBUG, "Starting AP scan for wildcard " 728 "SSID"); 729 } 730 #ifdef CONFIG_P2P 731 ssid_list_set: 732 #endif /* CONFIG_P2P */ 733 734 wpa_supplicant_optimize_freqs(wpa_s, ¶ms); 735 extra_ie = wpa_supplicant_extra_ies(wpa_s); 736 737 #ifdef CONFIG_HS20 738 if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 6) == 0) 739 wpas_hs20_add_indication(extra_ie); 740 #endif /* CONFIG_HS20 */ 741 742 if (params.freqs == NULL && wpa_s->next_scan_freqs) { 743 wpa_dbg(wpa_s, MSG_DEBUG, "Optimize scan based on previously " 744 "generated frequency list"); 745 params.freqs = wpa_s->next_scan_freqs; 746 } else 747 os_free(wpa_s->next_scan_freqs); 748 wpa_s->next_scan_freqs = NULL; 749 750 params.filter_ssids = wpa_supplicant_build_filter_ssids( 751 wpa_s->conf, ¶ms.num_filter_ssids); 752 if (extra_ie) { 753 params.extra_ies = wpabuf_head(extra_ie); 754 params.extra_ies_len = wpabuf_len(extra_ie); 755 } 756 757 #ifdef CONFIG_P2P 758 if (wpa_s->p2p_in_provisioning || 759 (wpa_s->show_group_started && wpa_s->go_params)) { 760 /* 761 * The interface may not yet be in P2P mode, so we have to 762 * explicitly request P2P probe to disable CCK rates. 763 */ 764 params.p2p_probe = 1; 765 } 766 #endif /* CONFIG_P2P */ 767 768 scan_params = ¶ms; 769 770 scan: 771 #ifdef CONFIG_P2P 772 /* 773 * If the driver does not support multi-channel concurrency and a 774 * virtual interface that shares the same radio with the wpa_s interface 775 * is operating there may not be need to scan other channels apart from 776 * the current operating channel on the other virtual interface. Filter 777 * out other channels in case we are trying to find a connection for a 778 * station interface when we are not configured to prefer station 779 * connection and a concurrent operation is already in process. 780 */ 781 if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ && 782 !scan_params->freqs && !params.freqs && 783 wpas_is_p2p_prioritized(wpa_s) && 784 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) && 785 wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE && 786 non_p2p_network_enabled(wpa_s)) { 787 int freq = shared_vif_oper_freq(wpa_s); 788 if (freq > 0) { 789 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only the current " 790 "operating channel (%d MHz) since driver does " 791 "not support multi-channel concurrency", freq); 792 params.freqs = os_zalloc(sizeof(int) * 2); 793 if (params.freqs) 794 params.freqs[0] = freq; 795 scan_params->freqs = params.freqs; 796 } 797 } 798 #endif /* CONFIG_P2P */ 799 800 ret = wpa_supplicant_trigger_scan(wpa_s, scan_params); 801 802 wpabuf_free(extra_ie); 803 os_free(params.freqs); 804 os_free(params.filter_ssids); 805 806 if (ret) { 807 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate AP scan"); 808 if (prev_state != wpa_s->wpa_state) 809 wpa_supplicant_set_state(wpa_s, prev_state); 810 /* Restore scan_req since we will try to scan again */ 811 wpa_s->scan_req = scan_req; 812 wpa_supplicant_req_scan(wpa_s, 1, 0); 813 } else { 814 wpa_s->scan_for_connection = 0; 815 } 816 } 817 818 819 /** 820 * wpa_supplicant_req_scan - Schedule a scan for neighboring access points 821 * @wpa_s: Pointer to wpa_supplicant data 822 * @sec: Number of seconds after which to scan 823 * @usec: Number of microseconds after which to scan 824 * 825 * This function is used to schedule a scan for neighboring access points after 826 * the specified time. 827 */ 828 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec) 829 { 830 /* If there's at least one network that should be specifically scanned 831 * then don't cancel the scan and reschedule. Some drivers do 832 * background scanning which generates frequent scan results, and that 833 * causes the specific SSID scan to get continually pushed back and 834 * never happen, which causes hidden APs to never get probe-scanned. 835 */ 836 if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) && 837 wpa_s->conf->ap_scan == 1) { 838 struct wpa_ssid *ssid = wpa_s->conf->ssid; 839 840 while (ssid) { 841 if (!wpas_network_disabled(wpa_s, ssid) && 842 ssid->scan_ssid) 843 break; 844 ssid = ssid->next; 845 } 846 if (ssid) { 847 wpa_dbg(wpa_s, MSG_DEBUG, "Not rescheduling scan to " 848 "ensure that specific SSID scans occur"); 849 return; 850 } 851 } 852 853 wpa_dbg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec", 854 sec, usec); 855 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 856 eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL); 857 } 858 859 860 /** 861 * wpa_supplicant_delayed_sched_scan - Request a delayed scheduled scan 862 * @wpa_s: Pointer to wpa_supplicant data 863 * @sec: Number of seconds after which to scan 864 * @usec: Number of microseconds after which to scan 865 * Returns: 0 on success or -1 otherwise 866 * 867 * This function is used to schedule periodic scans for neighboring 868 * access points after the specified time. 869 */ 870 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s, 871 int sec, int usec) 872 { 873 if (!wpa_s->sched_scan_supported) 874 return -1; 875 876 eloop_register_timeout(sec, usec, 877 wpa_supplicant_delayed_sched_scan_timeout, 878 wpa_s, NULL); 879 880 return 0; 881 } 882 883 884 /** 885 * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan 886 * @wpa_s: Pointer to wpa_supplicant data 887 * Returns: 0 is sched_scan was started or -1 otherwise 888 * 889 * This function is used to schedule periodic scans for neighboring 890 * access points repeating the scan continuously. 891 */ 892 int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) 893 { 894 struct wpa_driver_scan_params params; 895 struct wpa_driver_scan_params *scan_params; 896 enum wpa_states prev_state; 897 struct wpa_ssid *ssid = NULL; 898 struct wpabuf *extra_ie = NULL; 899 int ret; 900 unsigned int max_sched_scan_ssids; 901 int wildcard = 0; 902 int need_ssids; 903 904 if (!wpa_s->sched_scan_supported) 905 return -1; 906 907 if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS) 908 max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS; 909 else 910 max_sched_scan_ssids = wpa_s->max_sched_scan_ssids; 911 if (max_sched_scan_ssids < 1 || wpa_s->conf->disable_scan_offload) 912 return -1; 913 914 if (wpa_s->sched_scanning) { 915 wpa_dbg(wpa_s, MSG_DEBUG, "Already sched scanning"); 916 return 0; 917 } 918 919 need_ssids = 0; 920 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 921 if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) { 922 /* Use wildcard SSID to find this network */ 923 wildcard = 1; 924 } else if (!wpas_network_disabled(wpa_s, ssid) && 925 ssid->ssid_len) 926 need_ssids++; 927 928 #ifdef CONFIG_WPS 929 if (!wpas_network_disabled(wpa_s, ssid) && 930 ssid->key_mgmt == WPA_KEY_MGMT_WPS) { 931 /* 932 * Normal scan is more reliable and faster for WPS 933 * operations and since these are for short periods of 934 * time, the benefit of trying to use sched_scan would 935 * be limited. 936 */ 937 wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 938 "sched_scan for WPS"); 939 return -1; 940 } 941 #endif /* CONFIG_WPS */ 942 } 943 if (wildcard) 944 need_ssids++; 945 946 if (wpa_s->normal_scans < 3 && 947 (need_ssids <= wpa_s->max_scan_ssids || 948 wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) { 949 /* 950 * When normal scan can speed up operations, use that for the 951 * first operations before starting the sched_scan to allow 952 * user space sleep more. We do this only if the normal scan 953 * has functionality that is suitable for this or if the 954 * sched_scan does not have better support for multiple SSIDs. 955 */ 956 wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " 957 "sched_scan for initial scans (normal_scans=%d)", 958 wpa_s->normal_scans); 959 return -1; 960 } 961 962 os_memset(¶ms, 0, sizeof(params)); 963 964 /* If we can't allocate space for the filters, we just don't filter */ 965 params.filter_ssids = os_zalloc(wpa_s->max_match_sets * 966 sizeof(struct wpa_driver_scan_filter)); 967 968 prev_state = wpa_s->wpa_state; 969 if (wpa_s->wpa_state == WPA_DISCONNECTED || 970 wpa_s->wpa_state == WPA_INACTIVE) 971 wpa_supplicant_set_state(wpa_s, WPA_SCANNING); 972 973 if (wpa_s->autoscan_params != NULL) { 974 scan_params = wpa_s->autoscan_params; 975 goto scan; 976 } 977 978 /* Find the starting point from which to continue scanning */ 979 ssid = wpa_s->conf->ssid; 980 if (wpa_s->prev_sched_ssid) { 981 while (ssid) { 982 if (ssid == wpa_s->prev_sched_ssid) { 983 ssid = ssid->next; 984 break; 985 } 986 ssid = ssid->next; 987 } 988 } 989 990 if (!ssid || !wpa_s->prev_sched_ssid) { 991 wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list"); 992 993 if (wpa_s->sched_scan_interval == 0) 994 wpa_s->sched_scan_interval = 10; 995 wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; 996 wpa_s->first_sched_scan = 1; 997 ssid = wpa_s->conf->ssid; 998 wpa_s->prev_sched_ssid = ssid; 999 } 1000 1001 if (wildcard) { 1002 wpa_dbg(wpa_s, MSG_DEBUG, "Add wildcard SSID to sched_scan"); 1003 params.num_ssids++; 1004 } 1005 1006 while (ssid) { 1007 if (wpas_network_disabled(wpa_s, ssid)) 1008 goto next; 1009 1010 if (params.num_filter_ssids < wpa_s->max_match_sets && 1011 params.filter_ssids && ssid->ssid && ssid->ssid_len) { 1012 wpa_dbg(wpa_s, MSG_DEBUG, "add to filter ssid: %s", 1013 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1014 os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, 1015 ssid->ssid, ssid->ssid_len); 1016 params.filter_ssids[params.num_filter_ssids].ssid_len = 1017 ssid->ssid_len; 1018 params.num_filter_ssids++; 1019 } else if (params.filter_ssids && ssid->ssid && ssid->ssid_len) 1020 { 1021 wpa_dbg(wpa_s, MSG_DEBUG, "Not enough room for SSID " 1022 "filter for sched_scan - drop filter"); 1023 os_free(params.filter_ssids); 1024 params.filter_ssids = NULL; 1025 params.num_filter_ssids = 0; 1026 } 1027 1028 if (ssid->scan_ssid && ssid->ssid && ssid->ssid_len) { 1029 if (params.num_ssids == max_sched_scan_ssids) 1030 break; /* only room for broadcast SSID */ 1031 wpa_dbg(wpa_s, MSG_DEBUG, 1032 "add to active scan ssid: %s", 1033 wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); 1034 params.ssids[params.num_ssids].ssid = 1035 ssid->ssid; 1036 params.ssids[params.num_ssids].ssid_len = 1037 ssid->ssid_len; 1038 params.num_ssids++; 1039 if (params.num_ssids >= max_sched_scan_ssids) { 1040 wpa_s->prev_sched_ssid = ssid; 1041 do { 1042 ssid = ssid->next; 1043 } while (ssid && 1044 (wpas_network_disabled(wpa_s, ssid) || 1045 !ssid->scan_ssid)); 1046 break; 1047 } 1048 } 1049 1050 next: 1051 wpa_s->prev_sched_ssid = ssid; 1052 ssid = ssid->next; 1053 } 1054 1055 if (params.num_filter_ssids == 0) { 1056 os_free(params.filter_ssids); 1057 params.filter_ssids = NULL; 1058 } 1059 1060 extra_ie = wpa_supplicant_extra_ies(wpa_s); 1061 if (extra_ie) { 1062 params.extra_ies = wpabuf_head(extra_ie); 1063 params.extra_ies_len = wpabuf_len(extra_ie); 1064 } 1065 1066 scan_params = ¶ms; 1067 1068 scan: 1069 if (ssid || !wpa_s->first_sched_scan) { 1070 wpa_dbg(wpa_s, MSG_DEBUG, 1071 "Starting sched scan: interval %d timeout %d", 1072 wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout); 1073 } else { 1074 wpa_dbg(wpa_s, MSG_DEBUG, 1075 "Starting sched scan: interval %d (no timeout)", 1076 wpa_s->sched_scan_interval); 1077 } 1078 1079 ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params, 1080 wpa_s->sched_scan_interval); 1081 wpabuf_free(extra_ie); 1082 os_free(params.filter_ssids); 1083 if (ret) { 1084 wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); 1085 if (prev_state != wpa_s->wpa_state) 1086 wpa_supplicant_set_state(wpa_s, prev_state); 1087 return ret; 1088 } 1089 1090 /* If we have more SSIDs to scan, add a timeout so we scan them too */ 1091 if (ssid || !wpa_s->first_sched_scan) { 1092 wpa_s->sched_scan_timed_out = 0; 1093 eloop_register_timeout(wpa_s->sched_scan_timeout, 0, 1094 wpa_supplicant_sched_scan_timeout, 1095 wpa_s, NULL); 1096 wpa_s->first_sched_scan = 0; 1097 wpa_s->sched_scan_timeout /= 2; 1098 wpa_s->sched_scan_interval *= 2; 1099 } 1100 1101 return 0; 1102 } 1103 1104 1105 /** 1106 * wpa_supplicant_cancel_scan - Cancel a scheduled scan request 1107 * @wpa_s: Pointer to wpa_supplicant data 1108 * 1109 * This function is used to cancel a scan request scheduled with 1110 * wpa_supplicant_req_scan(). 1111 */ 1112 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s) 1113 { 1114 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request"); 1115 eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL); 1116 } 1117 1118 1119 /** 1120 * wpa_supplicant_cancel_sched_scan - Stop running scheduled scans 1121 * @wpa_s: Pointer to wpa_supplicant data 1122 * 1123 * This function is used to stop a periodic scheduled scan. 1124 */ 1125 void wpa_supplicant_cancel_sched_scan(struct wpa_supplicant *wpa_s) 1126 { 1127 if (!wpa_s->sched_scanning) 1128 return; 1129 1130 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling sched scan"); 1131 eloop_cancel_timeout(wpa_supplicant_sched_scan_timeout, wpa_s, NULL); 1132 wpa_supplicant_stop_sched_scan(wpa_s); 1133 } 1134 1135 1136 /** 1137 * wpa_supplicant_notify_scanning - Indicate possible scan state change 1138 * @wpa_s: Pointer to wpa_supplicant data 1139 * @scanning: Whether scanning is currently in progress 1140 * 1141 * This function is to generate scanning notifycations. It is called whenever 1142 * there may have been a change in scanning (scan started, completed, stopped). 1143 * wpas_notify_scanning() is called whenever the scanning state changed from the 1144 * previously notified state. 1145 */ 1146 void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s, 1147 int scanning) 1148 { 1149 if (wpa_s->scanning != scanning) { 1150 wpa_s->scanning = scanning; 1151 wpas_notify_scanning(wpa_s); 1152 } 1153 } 1154 1155 1156 static int wpa_scan_get_max_rate(const struct wpa_scan_res *res) 1157 { 1158 int rate = 0; 1159 const u8 *ie; 1160 int i; 1161 1162 ie = wpa_scan_get_ie(res, WLAN_EID_SUPP_RATES); 1163 for (i = 0; ie && i < ie[1]; i++) { 1164 if ((ie[i + 2] & 0x7f) > rate) 1165 rate = ie[i + 2] & 0x7f; 1166 } 1167 1168 ie = wpa_scan_get_ie(res, WLAN_EID_EXT_SUPP_RATES); 1169 for (i = 0; ie && i < ie[1]; i++) { 1170 if ((ie[i + 2] & 0x7f) > rate) 1171 rate = ie[i + 2] & 0x7f; 1172 } 1173 1174 return rate; 1175 } 1176 1177 1178 /** 1179 * wpa_scan_get_ie - Fetch a specified information element from a scan result 1180 * @res: Scan result entry 1181 * @ie: Information element identitifier (WLAN_EID_*) 1182 * Returns: Pointer to the information element (id field) or %NULL if not found 1183 * 1184 * This function returns the first matching information element in the scan 1185 * result. 1186 */ 1187 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 1188 { 1189 const u8 *end, *pos; 1190 1191 pos = (const u8 *) (res + 1); 1192 end = pos + res->ie_len; 1193 1194 while (pos + 1 < end) { 1195 if (pos + 2 + pos[1] > end) 1196 break; 1197 if (pos[0] == ie) 1198 return pos; 1199 pos += 2 + pos[1]; 1200 } 1201 1202 return NULL; 1203 } 1204 1205 1206 /** 1207 * wpa_scan_get_vendor_ie - Fetch vendor information element from a scan result 1208 * @res: Scan result entry 1209 * @vendor_type: Vendor type (four octets starting the IE payload) 1210 * Returns: Pointer to the information element (id field) or %NULL if not found 1211 * 1212 * This function returns the first matching information element in the scan 1213 * result. 1214 */ 1215 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, 1216 u32 vendor_type) 1217 { 1218 const u8 *end, *pos; 1219 1220 pos = (const u8 *) (res + 1); 1221 end = pos + res->ie_len; 1222 1223 while (pos + 1 < end) { 1224 if (pos + 2 + pos[1] > end) 1225 break; 1226 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 1227 vendor_type == WPA_GET_BE32(&pos[2])) 1228 return pos; 1229 pos += 2 + pos[1]; 1230 } 1231 1232 return NULL; 1233 } 1234 1235 1236 /** 1237 * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result 1238 * @res: Scan result entry 1239 * @vendor_type: Vendor type (four octets starting the IE payload) 1240 * Returns: Pointer to the information element payload or %NULL if not found 1241 * 1242 * This function returns concatenated payload of possibly fragmented vendor 1243 * specific information elements in the scan result. The caller is responsible 1244 * for freeing the returned buffer. 1245 */ 1246 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res, 1247 u32 vendor_type) 1248 { 1249 struct wpabuf *buf; 1250 const u8 *end, *pos; 1251 1252 buf = wpabuf_alloc(res->ie_len); 1253 if (buf == NULL) 1254 return NULL; 1255 1256 pos = (const u8 *) (res + 1); 1257 end = pos + res->ie_len; 1258 1259 while (pos + 1 < end) { 1260 if (pos + 2 + pos[1] > end) 1261 break; 1262 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 1263 vendor_type == WPA_GET_BE32(&pos[2])) 1264 wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4); 1265 pos += 2 + pos[1]; 1266 } 1267 1268 if (wpabuf_len(buf) == 0) { 1269 wpabuf_free(buf); 1270 buf = NULL; 1271 } 1272 1273 return buf; 1274 } 1275 1276 1277 /* 1278 * Channels with a great SNR can operate at full rate. What is a great SNR? 1279 * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general 1280 * rule of thumb is that any SNR above 20 is good." This one 1281 * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23 1282 * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a 1283 * conservative value. 1284 */ 1285 #define GREAT_SNR 30 1286 1287 /* Compare function for sorting scan results. Return >0 if @b is considered 1288 * better. */ 1289 static int wpa_scan_result_compar(const void *a, const void *b) 1290 { 1291 #define IS_5GHZ(n) (n > 4000) 1292 #define MIN(a,b) a < b ? a : b 1293 struct wpa_scan_res **_wa = (void *) a; 1294 struct wpa_scan_res **_wb = (void *) b; 1295 struct wpa_scan_res *wa = *_wa; 1296 struct wpa_scan_res *wb = *_wb; 1297 int wpa_a, wpa_b, maxrate_a, maxrate_b; 1298 int snr_a, snr_b; 1299 1300 /* WPA/WPA2 support preferred */ 1301 wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || 1302 wpa_scan_get_ie(wa, WLAN_EID_RSN) != NULL; 1303 wpa_b = wpa_scan_get_vendor_ie(wb, WPA_IE_VENDOR_TYPE) != NULL || 1304 wpa_scan_get_ie(wb, WLAN_EID_RSN) != NULL; 1305 1306 if (wpa_b && !wpa_a) 1307 return 1; 1308 if (!wpa_b && wpa_a) 1309 return -1; 1310 1311 /* privacy support preferred */ 1312 if ((wa->caps & IEEE80211_CAP_PRIVACY) == 0 && 1313 (wb->caps & IEEE80211_CAP_PRIVACY)) 1314 return 1; 1315 if ((wa->caps & IEEE80211_CAP_PRIVACY) && 1316 (wb->caps & IEEE80211_CAP_PRIVACY) == 0) 1317 return -1; 1318 1319 if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) && 1320 !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) { 1321 snr_a = MIN(wa->level - wa->noise, GREAT_SNR); 1322 snr_b = MIN(wb->level - wb->noise, GREAT_SNR); 1323 } else { 1324 /* Not suitable information to calculate SNR, so use level */ 1325 snr_a = wa->level; 1326 snr_b = wb->level; 1327 } 1328 1329 /* best/max rate preferred if SNR close enough */ 1330 if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || 1331 (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { 1332 maxrate_a = wpa_scan_get_max_rate(wa); 1333 maxrate_b = wpa_scan_get_max_rate(wb); 1334 if (maxrate_a != maxrate_b) 1335 return maxrate_b - maxrate_a; 1336 if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq)) 1337 return IS_5GHZ(wa->freq) ? -1 : 1; 1338 } 1339 1340 /* use freq for channel preference */ 1341 1342 /* all things being equal, use SNR; if SNRs are 1343 * identical, use quality values since some drivers may only report 1344 * that value and leave the signal level zero */ 1345 if (snr_b == snr_a) 1346 return wb->qual - wa->qual; 1347 return snr_b - snr_a; 1348 #undef MIN 1349 #undef IS_5GHZ 1350 } 1351 1352 1353 #ifdef CONFIG_WPS 1354 /* Compare function for sorting scan results when searching a WPS AP for 1355 * provisioning. Return >0 if @b is considered better. */ 1356 static int wpa_scan_result_wps_compar(const void *a, const void *b) 1357 { 1358 struct wpa_scan_res **_wa = (void *) a; 1359 struct wpa_scan_res **_wb = (void *) b; 1360 struct wpa_scan_res *wa = *_wa; 1361 struct wpa_scan_res *wb = *_wb; 1362 int uses_wps_a, uses_wps_b; 1363 struct wpabuf *wps_a, *wps_b; 1364 int res; 1365 1366 /* Optimization - check WPS IE existence before allocated memory and 1367 * doing full reassembly. */ 1368 uses_wps_a = wpa_scan_get_vendor_ie(wa, WPS_IE_VENDOR_TYPE) != NULL; 1369 uses_wps_b = wpa_scan_get_vendor_ie(wb, WPS_IE_VENDOR_TYPE) != NULL; 1370 if (uses_wps_a && !uses_wps_b) 1371 return -1; 1372 if (!uses_wps_a && uses_wps_b) 1373 return 1; 1374 1375 if (uses_wps_a && uses_wps_b) { 1376 wps_a = wpa_scan_get_vendor_ie_multi(wa, WPS_IE_VENDOR_TYPE); 1377 wps_b = wpa_scan_get_vendor_ie_multi(wb, WPS_IE_VENDOR_TYPE); 1378 res = wps_ap_priority_compar(wps_a, wps_b); 1379 wpabuf_free(wps_a); 1380 wpabuf_free(wps_b); 1381 if (res) 1382 return res; 1383 } 1384 1385 /* 1386 * Do not use current AP security policy as a sorting criteria during 1387 * WPS provisioning step since the AP may get reconfigured at the 1388 * completion of provisioning. 1389 */ 1390 1391 /* all things being equal, use signal level; if signal levels are 1392 * identical, use quality values since some drivers may only report 1393 * that value and leave the signal level zero */ 1394 if (wb->level == wa->level) 1395 return wb->qual - wa->qual; 1396 return wb->level - wa->level; 1397 } 1398 #endif /* CONFIG_WPS */ 1399 1400 1401 static void dump_scan_res(struct wpa_scan_results *scan_res) 1402 { 1403 #ifndef CONFIG_NO_STDOUT_DEBUG 1404 size_t i; 1405 1406 if (scan_res->res == NULL || scan_res->num == 0) 1407 return; 1408 1409 wpa_printf(MSG_EXCESSIVE, "Sorted scan results"); 1410 1411 for (i = 0; i < scan_res->num; i++) { 1412 struct wpa_scan_res *r = scan_res->res[i]; 1413 u8 *pos; 1414 if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID)) 1415 == WPA_SCAN_LEVEL_DBM) { 1416 int snr = r->level - r->noise; 1417 wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1418 "noise=%d level=%d snr=%d%s flags=0x%x", 1419 MAC2STR(r->bssid), r->freq, r->qual, 1420 r->noise, r->level, snr, 1421 snr >= GREAT_SNR ? "*" : "", r->flags); 1422 } else { 1423 wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " 1424 "noise=%d level=%d flags=0x%x", 1425 MAC2STR(r->bssid), r->freq, r->qual, 1426 r->noise, r->level, r->flags); 1427 } 1428 pos = (u8 *) (r + 1); 1429 if (r->ie_len) 1430 wpa_hexdump(MSG_EXCESSIVE, "IEs", pos, r->ie_len); 1431 pos += r->ie_len; 1432 if (r->beacon_ie_len) 1433 wpa_hexdump(MSG_EXCESSIVE, "Beacon IEs", 1434 pos, r->beacon_ie_len); 1435 } 1436 #endif /* CONFIG_NO_STDOUT_DEBUG */ 1437 } 1438 1439 1440 /** 1441 * wpa_supplicant_filter_bssid_match - Is the specified BSSID allowed 1442 * @wpa_s: Pointer to wpa_supplicant data 1443 * @bssid: BSSID to check 1444 * Returns: 0 if the BSSID is filtered or 1 if not 1445 * 1446 * This function is used to filter out specific BSSIDs from scan reslts mainly 1447 * for testing purposes (SET bssid_filter ctrl_iface command). 1448 */ 1449 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s, 1450 const u8 *bssid) 1451 { 1452 size_t i; 1453 1454 if (wpa_s->bssid_filter == NULL) 1455 return 1; 1456 1457 for (i = 0; i < wpa_s->bssid_filter_count; i++) { 1458 if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid, 1459 ETH_ALEN) == 0) 1460 return 1; 1461 } 1462 1463 return 0; 1464 } 1465 1466 1467 static void filter_scan_res(struct wpa_supplicant *wpa_s, 1468 struct wpa_scan_results *res) 1469 { 1470 size_t i, j; 1471 1472 if (wpa_s->bssid_filter == NULL) 1473 return; 1474 1475 for (i = 0, j = 0; i < res->num; i++) { 1476 if (wpa_supplicant_filter_bssid_match(wpa_s, 1477 res->res[i]->bssid)) { 1478 res->res[j++] = res->res[i]; 1479 } else { 1480 os_free(res->res[i]); 1481 res->res[i] = NULL; 1482 } 1483 } 1484 1485 if (res->num != j) { 1486 wpa_printf(MSG_DEBUG, "Filtered out %d scan results", 1487 (int) (res->num - j)); 1488 res->num = j; 1489 } 1490 } 1491 1492 1493 /** 1494 * wpa_supplicant_get_scan_results - Get scan results 1495 * @wpa_s: Pointer to wpa_supplicant data 1496 * @info: Information about what was scanned or %NULL if not available 1497 * @new_scan: Whether a new scan was performed 1498 * Returns: Scan results, %NULL on failure 1499 * 1500 * This function request the current scan results from the driver and updates 1501 * the local BSS list wpa_s->bss. The caller is responsible for freeing the 1502 * results with wpa_scan_results_free(). 1503 */ 1504 struct wpa_scan_results * 1505 wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, 1506 struct scan_info *info, int new_scan) 1507 { 1508 struct wpa_scan_results *scan_res; 1509 size_t i; 1510 int (*compar)(const void *, const void *) = wpa_scan_result_compar; 1511 1512 scan_res = wpa_drv_get_scan_results2(wpa_s); 1513 if (scan_res == NULL) { 1514 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results"); 1515 return NULL; 1516 } 1517 filter_scan_res(wpa_s, scan_res); 1518 1519 #ifdef CONFIG_WPS 1520 if (wpas_wps_in_progress(wpa_s)) { 1521 wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " 1522 "provisioning rules"); 1523 compar = wpa_scan_result_wps_compar; 1524 } 1525 #endif /* CONFIG_WPS */ 1526 1527 qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), 1528 compar); 1529 dump_scan_res(scan_res); 1530 1531 wpa_bss_update_start(wpa_s); 1532 for (i = 0; i < scan_res->num; i++) 1533 wpa_bss_update_scan_res(wpa_s, scan_res->res[i]); 1534 wpa_bss_update_end(wpa_s, info, new_scan); 1535 1536 return scan_res; 1537 } 1538 1539 1540 /** 1541 * wpa_supplicant_update_scan_results - Update scan results from the driver 1542 * @wpa_s: Pointer to wpa_supplicant data 1543 * Returns: 0 on success, -1 on failure 1544 * 1545 * This function updates the BSS table within wpa_supplicant based on the 1546 * currently available scan results from the driver without requesting a new 1547 * scan. This is used in cases where the driver indicates an association 1548 * (including roaming within ESS) and wpa_supplicant does not yet have the 1549 * needed information to complete the connection (e.g., to perform validation 1550 * steps in 4-way handshake). 1551 */ 1552 int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s) 1553 { 1554 struct wpa_scan_results *scan_res; 1555 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0); 1556 if (scan_res == NULL) 1557 return -1; 1558 wpa_scan_results_free(scan_res); 1559 1560 return 0; 1561 } 1562