1# Scanning tests 2# Copyright (c) 2013-2016, Jouni Malinen <j@w1.fi> 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7from remotehost import remote_compatible 8import binascii 9import time 10import logging 11logger = logging.getLogger() 12import os 13import struct 14import subprocess 15 16import hostapd 17from wpasupplicant import WpaSupplicant 18from utils import * 19from tshark import run_tshark 20from test_ap_csa import switch_channel, wait_channel_switch 21 22def check_scan(dev, params, other_started=False, test_busy=False): 23 if other_started: 24 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) 25 if ev is None: 26 raise Exception("Other scan did not start") 27 if "id=" in ev: 28 raise Exception("Scan id unexpectedly included in start event") 29 30 if not other_started: 31 dev.dump_monitor() 32 id = dev.request("SCAN " + params) 33 if "FAIL" in id: 34 raise Exception("Failed to start scan") 35 id = int(id) 36 37 if test_busy: 38 if "FAIL-BUSY" not in dev.request("SCAN"): 39 raise Exception("SCAN command while already scanning not rejected") 40 41 if other_started: 42 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 43 if ev is None: 44 raise Exception("Other scan did not complete") 45 if "id=" + str(id) in ev: 46 raise Exception("Own scan id unexpectedly included in completed event") 47 48 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) 49 if ev is None: 50 raise Exception("Scan did not start") 51 if "id=" + str(id) not in ev: 52 raise Exception("Scan id not included in start event") 53 if test_busy: 54 if "FAIL-BUSY" not in dev.request("SCAN"): 55 raise Exception("SCAN command while already scanning not rejected") 56 57 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 58 if ev is None: 59 raise Exception("Scan did not complete") 60 if "id=" + str(id) not in ev: 61 raise Exception("Scan id not included in completed event") 62 63def check_scan_retry(dev, params, bssid): 64 for i in range(0, 5): 65 check_scan(dev, "freq=2412-2462,5180 use_id=1") 66 if int(dev.get_bss(bssid)['age']) <= 1: 67 return 68 raise Exception("Unexpectedly old BSS entry") 69 70@remote_compatible 71def test_scan(dev, apdev): 72 """Control interface behavior on scan parameters""" 73 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 74 bssid = apdev[0]['bssid'] 75 76 logger.info("Full scan") 77 check_scan(dev[0], "use_id=1", test_busy=True) 78 79 logger.info("Limited channel scan") 80 check_scan_retry(dev[0], "freq=2412-2462,5180 use_id=1", bssid) 81 82 # wait long enough to allow next scans to be verified not to find the AP 83 time.sleep(2) 84 85 logger.info("Passive single-channel scan") 86 check_scan(dev[0], "freq=2457 passive=1 use_id=1") 87 logger.info("Active single-channel scan") 88 check_scan(dev[0], "freq=2452 passive=0 use_id=1") 89 if int(dev[0].get_bss(bssid)['age']) < 2: 90 raise Exception("Unexpectedly updated BSS entry") 91 92 logger.info("Active single-channel scan on AP's operating channel") 93 check_scan_retry(dev[0], "freq=2412 passive=0 use_id=1", bssid) 94 95 logger.info("Disable collocated 6 GHz scanning") 96 check_scan(dev[0], "freq=2457 non_coloc_6ghz=1 use_id=1") 97 98@remote_compatible 99def test_scan_tsf(dev, apdev): 100 """Scan and TSF updates from Beacon/Probe Response frames""" 101 hostapd.add_ap(apdev[0], {"ssid": "test-scan", 102 'beacon_int': "100"}) 103 bssid = apdev[0]['bssid'] 104 105 tsf = [] 106 for passive in [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1]: 107 check_scan(dev[0], "freq=2412 passive=%d use_id=1" % passive) 108 bss = dev[0].get_bss(bssid) 109 if bss: 110 tsf.append(int(bss['tsf'])) 111 logger.info("TSF: " + bss['tsf']) 112 if tsf[-3] <= tsf[-4]: 113 # For now, only write this in the log without failing the test case 114 # since mac80211_hwsim does not yet update the Timestamp field in 115 # Probe Response frames. 116 logger.info("Probe Response did not update TSF") 117 #raise Exception("Probe Response did not update TSF") 118 if tsf[-1] <= tsf[-3]: 119 raise Exception("Beacon did not update TSF") 120 if 0 in tsf: 121 raise Exception("0 TSF reported") 122 123@remote_compatible 124def test_scan_only(dev, apdev): 125 """Control interface behavior on scan parameters with type=only""" 126 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 127 bssid = apdev[0]['bssid'] 128 129 logger.info("Full scan") 130 check_scan(dev[0], "type=only use_id=1") 131 132 logger.info("Limited channel scan") 133 check_scan_retry(dev[0], "type=only freq=2412-2462,5180 use_id=1", bssid) 134 135 # wait long enough to allow next scans to be verified not to find the AP 136 time.sleep(2) 137 138 logger.info("Passive single-channel scan") 139 check_scan(dev[0], "type=only freq=2457 passive=1 use_id=1") 140 logger.info("Active single-channel scan") 141 check_scan(dev[0], "type=only freq=2452 passive=0 use_id=1") 142 if int(dev[0].get_bss(bssid)['age']) < 2: 143 raise Exception("Unexpectedly updated BSS entry") 144 145 logger.info("Active single-channel scan on AP's operating channel") 146 check_scan_retry(dev[0], "type=only freq=2412 passive=0 use_id=1", bssid) 147 148@remote_compatible 149def test_scan_external_trigger(dev, apdev): 150 """Avoid operations during externally triggered scan""" 151 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 152 bssid = apdev[0]['bssid'] 153 dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger']) 154 check_scan(dev[0], "use_id=1", other_started=True) 155 156def test_scan_bss_expiration_count(dev, apdev): 157 """BSS entry expiration based on scan results without match""" 158 if "FAIL" not in dev[0].request("BSS_EXPIRE_COUNT 0"): 159 raise Exception("Invalid BSS_EXPIRE_COUNT accepted") 160 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"): 161 raise Exception("BSS_EXPIRE_COUNT failed") 162 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 163 bssid = apdev[0]['bssid'] 164 dev[0].scan(freq="2412", only_new=True) 165 if bssid not in dev[0].request("SCAN_RESULTS"): 166 raise Exception("BSS not found in initial scan") 167 hapd.request("DISABLE") 168 # Try to give enough time for hostapd to have stopped mac80211 from 169 # beaconing before checking a new scan. This is needed with UML time travel 170 # testing. 171 hapd.ping() 172 time.sleep(0.2) 173 dev[0].scan(freq="2412", only_new=True) 174 if bssid not in dev[0].request("SCAN_RESULTS"): 175 raise Exception("BSS not found in first scan without match") 176 dev[0].scan(freq="2412", only_new=True) 177 if bssid in dev[0].request("SCAN_RESULTS"): 178 raise Exception("BSS found after two scans without match") 179 180@remote_compatible 181def test_scan_bss_expiration_age(dev, apdev): 182 """BSS entry expiration based on age""" 183 try: 184 if "FAIL" not in dev[0].request("BSS_EXPIRE_AGE COUNT 9"): 185 raise Exception("Invalid BSS_EXPIRE_AGE accepted") 186 if "OK" not in dev[0].request("BSS_EXPIRE_AGE 10"): 187 raise Exception("BSS_EXPIRE_AGE failed") 188 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 189 bssid = apdev[0]['bssid'] 190 # Allow couple more retries to avoid reporting errors during heavy load 191 for i in range(5): 192 dev[0].scan(freq="2412") 193 if bssid in dev[0].request("SCAN_RESULTS"): 194 break 195 if bssid not in dev[0].request("SCAN_RESULTS"): 196 raise Exception("BSS not found in initial scan") 197 hapd.request("DISABLE") 198 logger.info("Waiting for BSS entry to expire") 199 time.sleep(7) 200 if bssid not in dev[0].request("SCAN_RESULTS"): 201 raise Exception("BSS expired too quickly") 202 ev = dev[0].wait_event(["CTRL-EVENT-BSS-REMOVED"], timeout=15) 203 if ev is None: 204 raise Exception("BSS entry expiration timed out") 205 if bssid in dev[0].request("SCAN_RESULTS"): 206 raise Exception("BSS not removed after expiration time") 207 finally: 208 dev[0].request("BSS_EXPIRE_AGE 180") 209 210@remote_compatible 211def test_scan_filter(dev, apdev): 212 """Filter scan results based on SSID""" 213 try: 214 if "OK" not in dev[0].request("SET filter_ssids 1"): 215 raise Exception("SET failed") 216 id = dev[0].connect("test-scan", key_mgmt="NONE", only_add_network=True) 217 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 218 bssid = apdev[0]['bssid'] 219 hostapd.add_ap(apdev[1], {"ssid": "test-scan2"}) 220 bssid2 = apdev[1]['bssid'] 221 dev[0].scan(freq="2412", only_new=True) 222 if bssid not in dev[0].request("SCAN_RESULTS"): 223 raise Exception("BSS not found in scan results") 224 if bssid2 in dev[0].request("SCAN_RESULTS"): 225 raise Exception("Unexpected BSS found in scan results") 226 dev[0].set_network_quoted(id, "ssid", "") 227 dev[0].scan(freq="2412") 228 id2 = dev[0].connect("test", key_mgmt="NONE", only_add_network=True) 229 dev[0].scan(freq="2412") 230 finally: 231 dev[0].request("SET filter_ssids 0") 232 233@remote_compatible 234def test_scan_int(dev, apdev): 235 """scan interval configuration""" 236 try: 237 if "FAIL" not in dev[0].request("SCAN_INTERVAL -1"): 238 raise Exception("Accepted invalid scan interval") 239 if "OK" not in dev[0].request("SCAN_INTERVAL 1"): 240 raise Exception("Failed to set scan interval") 241 dev[0].connect("not-used", key_mgmt="NONE", scan_freq="2412", 242 wait_connect=False) 243 times = {} 244 for i in range(0, 3): 245 logger.info("Waiting for scan to start") 246 start = os.times()[4] 247 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) 248 if ev is None: 249 raise Exception("did not start a scan") 250 stop = os.times()[4] 251 times[i] = stop - start 252 logger.info("Waiting for scan to complete") 253 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10) 254 if ev is None: 255 raise Exception("did not complete a scan") 256 logger.info("times=" + str(times)) 257 if times[0] > 1 or times[1] < 0.5 or times[1] > 1.5 or times[2] < 0.5 or times[2] > 1.5: 258 raise Exception("Unexpected scan timing: " + str(times)) 259 finally: 260 dev[0].request("SCAN_INTERVAL 5") 261 262def test_scan_bss_operations(dev, apdev): 263 """Control interface behavior on BSS parameters""" 264 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 265 bssid = apdev[0]['bssid'] 266 hostapd.add_ap(apdev[1], {"ssid": "test2-scan"}) 267 bssid2 = apdev[1]['bssid'] 268 269 dev[0].flush_scan_cache() 270 dev[0].scan(freq="2412") 271 dev[0].scan(freq="2412") 272 dev[0].scan(freq="2412") 273 274 id1 = dev[0].request("BSS FIRST MASK=0x1").splitlines()[0].split('=')[1] 275 id2 = dev[0].request("BSS LAST MASK=0x1").splitlines()[0].split('=')[1] 276 277 res = dev[0].request("BSS RANGE=ALL MASK=0x20001") 278 if "id=" + id1 not in res: 279 raise Exception("Missing BSS " + id1) 280 if "id=" + id2 not in res: 281 raise Exception("Missing BSS " + id2) 282 if "====" not in res: 283 raise Exception("Missing delim") 284 if "####" not in res: 285 raise Exception("Missing end") 286 287 res = dev[0].request("BSS RANGE=ALL MASK=0") 288 if "id=" + id1 not in res: 289 raise Exception("Missing BSS " + id1) 290 if "id=" + id2 not in res: 291 raise Exception("Missing BSS " + id2) 292 if "====" in res: 293 raise Exception("Unexpected delim") 294 if "####" in res: 295 raise Exception("Unexpected end delim") 296 297 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() 298 if len(res) != 2: 299 raise Exception("Unexpected result: " + str(res)) 300 res = dev[0].request("BSS FIRST MASK=0x1") 301 if "id=" + id1 not in res: 302 raise Exception("Unexpected result: " + res) 303 res = dev[0].request("BSS LAST MASK=0x1") 304 if "id=" + id2 not in res: 305 raise Exception("Unexpected result: " + res) 306 res = dev[0].request("BSS ID-" + id1 + " MASK=0x1") 307 if "id=" + id1 not in res: 308 raise Exception("Unexpected result: " + res) 309 res = dev[0].request("BSS NEXT-" + id1 + " MASK=0x1") 310 if "id=" + id2 not in res: 311 raise Exception("Unexpected result: " + res) 312 res = dev[0].request("BSS NEXT-" + id2 + " MASK=0x1") 313 if "id=" in res: 314 raise Exception("Unexpected result: " + res) 315 316 if len(dev[0].request("BSS RANGE=" + id2 + " MASK=0x1").splitlines()) != 0: 317 raise Exception("Unexpected RANGE=1 result") 318 if len(dev[0].request("BSS RANGE=" + id1 + "- MASK=0x1").splitlines()) != 2: 319 raise Exception("Unexpected RANGE=0- result") 320 if len(dev[0].request("BSS RANGE=-" + id2 + " MASK=0x1").splitlines()) != 2: 321 raise Exception("Unexpected RANGE=-1 result") 322 if len(dev[0].request("BSS RANGE=" + id1 + "-" + id2 + " MASK=0x1").splitlines()) != 2: 323 raise Exception("Unexpected RANGE=0-1 result") 324 if len(dev[0].request("BSS RANGE=" + id2 + "-" + id2 + " MASK=0x1").splitlines()) != 1: 325 raise Exception("Unexpected RANGE=1-1 result") 326 if len(dev[0].request("BSS RANGE=" + str(int(id2) + 1) + "-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 0: 327 raise Exception("Unexpected RANGE=2-10 result") 328 if len(dev[0].request("BSS RANGE=0-" + str(int(id2) + 10) + " MASK=0x1").splitlines()) != 2: 329 raise Exception("Unexpected RANGE=0-10 result") 330 if len(dev[0].request("BSS RANGE=" + id1 + "-" + id1 + " MASK=0x1").splitlines()) != 1: 331 raise Exception("Unexpected RANGE=0-0 result") 332 333 res = dev[0].request("BSS p2p_dev_addr=FOO") 334 if "FAIL" in res or "id=" in res: 335 raise Exception("Unexpected result: " + res) 336 res = dev[0].request("BSS p2p_dev_addr=00:11:22:33:44:55") 337 if "FAIL" in res or "id=" in res: 338 raise Exception("Unexpected result: " + res) 339 340 dev[0].request("BSS_FLUSH 1000") 341 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() 342 if len(res) != 2: 343 raise Exception("Unexpected result after BSS_FLUSH 1000") 344 dev[0].request("BSS_FLUSH 0") 345 res = dev[0].request("BSS RANGE=ALL MASK=0x1").splitlines() 346 if len(res) != 0: 347 raise Exception("Unexpected result after BSS_FLUSH 0") 348 349@remote_compatible 350def test_scan_and_interface_disabled(dev, apdev): 351 """Scan operation when interface gets disabled""" 352 try: 353 dev[0].request("SCAN") 354 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 355 if ev is None: 356 raise Exception("Scan did not start") 357 dev[0].request("DRIVER_EVENT INTERFACE_DISABLED") 358 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=7) 359 if ev is not None: 360 raise Exception("Scan completed unexpectedly") 361 362 # verify that scan is rejected 363 if "FAIL" not in dev[0].request("SCAN"): 364 raise Exception("New scan request was accepted unexpectedly") 365 366 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED") 367 dev[0].scan(freq="2412") 368 finally: 369 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED") 370 371@remote_compatible 372def test_scan_for_auth(dev, apdev): 373 """cfg80211 workaround with scan-for-auth""" 374 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 375 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 376 # Block sme-connect radio work with an external radio work item, so that 377 # SELECT_NETWORK can decide to use fast associate without a new scan while 378 # cfg80211 still has the matching BSS entry, but the actual connection is 379 # not yet started. 380 id = dev[0].request("RADIO_WORK add block-work") 381 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"]) 382 if ev is None: 383 raise Exception("Timeout while waiting radio work to start") 384 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", 385 wait_connect=False) 386 dev[0].dump_monitor() 387 # Clear cfg80211 BSS table. 388 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger', 389 'freq', '2457', 'flush']) 390 if res != 0: 391 raise HwsimSkip("iw scan trigger flush not supported") 392 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5) 393 if ev is None: 394 raise Exception("External flush scan timed out") 395 # Release blocking radio work to allow connection to go through with the 396 # cfg80211 BSS entry missing. 397 dev[0].request("RADIO_WORK done " + id) 398 399 dev[0].wait_connected(timeout=15) 400 401@remote_compatible 402def test_scan_for_auth_fail(dev, apdev): 403 """cfg80211 workaround with scan-for-auth failing""" 404 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 405 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 406 # Block sme-connect radio work with an external radio work item, so that 407 # SELECT_NETWORK can decide to use fast associate without a new scan while 408 # cfg80211 still has the matching BSS entry, but the actual connection is 409 # not yet started. 410 id = dev[0].request("RADIO_WORK add block-work") 411 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"]) 412 if ev is None: 413 raise Exception("Timeout while waiting radio work to start") 414 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", 415 wait_connect=False) 416 dev[0].dump_monitor() 417 hapd.disable() 418 # Clear cfg80211 BSS table. 419 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger', 420 'freq', '2457', 'flush']) 421 if res != 0: 422 raise HwsimSkip("iw scan trigger flush not supported") 423 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5) 424 if ev is None: 425 raise Exception("External flush scan timed out") 426 # Release blocking radio work to allow connection to go through with the 427 # cfg80211 BSS entry missing. 428 dev[0].request("RADIO_WORK done " + id) 429 430 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS", 431 "CTRL-EVENT-CONNECTED"], 15) 432 if ev is None: 433 raise Exception("Scan event missing") 434 if "CTRL-EVENT-CONNECTED" in ev: 435 raise Exception("Unexpected connection") 436 dev[0].request("DISCONNECT") 437 438@remote_compatible 439def test_scan_for_auth_wep(dev, apdev): 440 """cfg80211 scan-for-auth workaround with WEP keys""" 441 check_wep_capa(dev[0]) 442 dev[0].flush_scan_cache() 443 hapd = hostapd.add_ap(apdev[0], 444 {"ssid": "wep", "wep_key0": '"abcde"', 445 "auth_algs": "2"}) 446 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 447 # Block sme-connect radio work with an external radio work item, so that 448 # SELECT_NETWORK can decide to use fast associate without a new scan while 449 # cfg80211 still has the matching BSS entry, but the actual connection is 450 # not yet started. 451 id = dev[0].request("RADIO_WORK add block-work") 452 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"]) 453 if ev is None: 454 raise Exception("Timeout while waiting radio work to start") 455 dev[0].connect("wep", key_mgmt="NONE", wep_key0='"abcde"', 456 auth_alg="SHARED", scan_freq="2412", wait_connect=False) 457 dev[0].dump_monitor() 458 # Clear cfg80211 BSS table. 459 res, data = dev[0].cmd_execute(['iw', dev[0].ifname, 'scan', 'trigger', 460 'freq', '2457', 'flush']) 461 if res != 0: 462 raise HwsimSkip("iw scan trigger flush not supported") 463 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5) 464 if ev is None: 465 raise Exception("External flush scan timed out") 466 # Release blocking radio work to allow connection to go through with the 467 # cfg80211 BSS entry missing. 468 dev[0].request("RADIO_WORK done " + id) 469 470 dev[0].wait_connected(timeout=15) 471 472@remote_compatible 473def test_scan_hidden(dev, apdev): 474 """Control interface behavior on scan parameters""" 475 dev[0].flush_scan_cache() 476 ssid = "test-scan" 477 wrong_ssid = "wrong" 478 hapd = hostapd.add_ap(apdev[0], {"ssid": ssid, 479 "ignore_broadcast_ssid": "1"}) 480 bssid = apdev[0]['bssid'] 481 482 check_scan(dev[0], "freq=2412 use_id=1") 483 try: 484 payload = struct.pack('BB', 0, len(wrong_ssid)) + wrong_ssid.encode() 485 ssid_list = struct.pack('BB', 84, len(payload)) + payload 486 cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode() 487 if "OK" not in dev[0].request(cmd): 488 raise Exception("VENDOR_ELEM_ADD failed") 489 check_scan(dev[0], "freq=2412 use_id=1") 490 491 payload = struct.pack('<L', binascii.crc32(wrong_ssid.encode())) 492 ssid_list = struct.pack('BBB', 255, 1 + len(payload), 58) + payload 493 cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode() 494 if "OK" not in dev[0].request(cmd): 495 raise Exception("VENDOR_ELEM_ADD failed") 496 check_scan(dev[0], "freq=2412 use_id=1") 497 finally: 498 dev[0].request("VENDOR_ELEM_REMOVE 14 *") 499 if "test-scan" in dev[0].request("SCAN_RESULTS"): 500 raise Exception("BSS unexpectedly found in initial scan") 501 502 id1 = dev[0].connect("foo", key_mgmt="NONE", scan_ssid="1", 503 only_add_network=True) 504 id2 = dev[0].connect("test-scan", key_mgmt="NONE", scan_ssid="1", 505 only_add_network=True) 506 id3 = dev[0].connect("bar", key_mgmt="NONE", only_add_network=True) 507 508 check_scan(dev[0], "freq=2412 use_id=1") 509 if "test-scan" in dev[0].request("SCAN_RESULTS"): 510 raise Exception("BSS unexpectedly found in scan") 511 512 # Allow multiple attempts to be more robust under heavy CPU load that can 513 # result in Probe Response frames getting sent only after the station has 514 # already stopped waiting for the response on the channel. 515 found = False 516 for i in range(10): 517 check_scan(dev[0], "scan_id=%d,%d,%d freq=2412 use_id=1" % (id1, id2, id3)) 518 if "test-scan" in dev[0].request("SCAN_RESULTS"): 519 found = True 520 break 521 if not found: 522 raise Exception("BSS not found in scan") 523 524 if "FAIL" not in dev[0].request("SCAN scan_id=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17"): 525 raise Exception("Too many scan_id values accepted") 526 527 # Duplicate SSID removal 528 check_scan(dev[0], "scan_id=%d,%d,%d freq=2412 use_id=1" % (id1, id1, id2)) 529 530 dev[0].request("REMOVE_NETWORK all") 531 hapd.disable() 532 dev[0].flush_scan_cache(freq=2432) 533 dev[0].flush_scan_cache() 534 535def test_scan_and_bss_entry_removed(dev, apdev): 536 """Last scan result and connect work processing on BSS entry update""" 537 hapd = hostapd.add_ap(apdev[0], {"ssid": "open", 538 "eap_server": "1", 539 "wps_state": "2"}) 540 bssid = apdev[0]['bssid'] 541 542 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 543 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 544 545 # Add a BSS entry 546 dev[0].scan_for_bss(bssid, freq="2412") 547 wpas.scan_for_bss(bssid, freq="2412") 548 549 # Start a connect radio work with a blocking entry preventing this from 550 # proceeding; this stores a pointer to the selected BSS entry. 551 id = dev[0].request("RADIO_WORK add block-work") 552 w_id = wpas.request("RADIO_WORK add block-work") 553 dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1) 554 wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1) 555 nid = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", 556 wait_connect=False) 557 w_nid = wpas.connect("open", key_mgmt="NONE", scan_freq="2412", 558 wait_connect=False) 559 time.sleep(0.1) 560 561 # Remove the BSS entry 562 dev[0].request("BSS_FLUSH 0") 563 wpas.request("BSS_FLUSH 0") 564 565 # Allow the connect radio work to continue. The bss entry stored in the 566 # pending connect work is now stale. This will result in the connection 567 # attempt failing since the BSS entry does not exist. 568 dev[0].request("RADIO_WORK done " + id) 569 wpas.request("RADIO_WORK done " + w_id) 570 571 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 572 if ev is not None: 573 raise Exception("Unexpected connection") 574 dev[0].remove_network(nid) 575 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) 576 if ev is not None: 577 raise Exception("Unexpected connection") 578 wpas.remove_network(w_nid) 579 time.sleep(0.5) 580 dev[0].request("BSS_FLUSH 0") 581 wpas.request("BSS_FLUSH 0") 582 583 # Add a BSS entry 584 dev[0].scan_for_bss(bssid, freq="2412") 585 wpas.scan_for_bss(bssid, freq="2412") 586 587 # Start a connect radio work with a blocking entry preventing this from 588 # proceeding; this stores a pointer to the selected BSS entry. 589 id = dev[0].request("RADIO_WORK add block-work") 590 w_id = wpas.request("RADIO_WORK add block-work") 591 dev[0].wait_event(["EXT-RADIO-WORK-START"], timeout=1) 592 wpas.wait_event(["EXT-RADIO-WORK-START"], timeout=1) 593 594 # Schedule a connection based on the current BSS entry. 595 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", 596 wait_connect=False) 597 wpas.connect("open", key_mgmt="NONE", scan_freq="2412", 598 wait_connect=False) 599 600 # Update scan results with results that have longer set of IEs so that new 601 # memory needs to be allocated for the BSS entry. 602 hapd.request("WPS_PBC") 603 time.sleep(0.1) 604 subprocess.call(['iw', dev[0].ifname, 'scan', 'trigger', 'freq', '2412']) 605 subprocess.call(['iw', wpas.ifname, 'scan', 'trigger', 'freq', '2412']) 606 time.sleep(0.1) 607 608 # Allow the connect radio work to continue. The bss entry stored in the 609 # pending connect work becomes stale during the scan and it must have been 610 # updated for the connection to work. 611 dev[0].request("RADIO_WORK done " + id) 612 wpas.request("RADIO_WORK done " + w_id) 613 614 dev[0].wait_connected(timeout=15, error="No connection (sme-connect)") 615 wpas.wait_connected(timeout=15, error="No connection (connect)") 616 dev[0].request("DISCONNECT") 617 wpas.request("DISCONNECT") 618 dev[0].flush_scan_cache() 619 wpas.flush_scan_cache() 620 621@remote_compatible 622def test_scan_reqs_with_non_scan_radio_work(dev, apdev): 623 """SCAN commands while non-scan radio_work is in progress""" 624 id = dev[0].request("RADIO_WORK add test-work-a") 625 ev = dev[0].wait_event(["EXT-RADIO-WORK-START"]) 626 if ev is None: 627 raise Exception("Timeout while waiting radio work to start") 628 629 if "OK" not in dev[0].request("SCAN"): 630 raise Exception("SCAN failed") 631 if "FAIL-BUSY" not in dev[0].request("SCAN"): 632 raise Exception("SCAN accepted while one is already pending") 633 if "FAIL-BUSY" not in dev[0].request("SCAN"): 634 raise Exception("SCAN accepted while one is already pending") 635 636 res = dev[0].request("RADIO_WORK show").splitlines() 637 count = 0 638 for l in res: 639 if "scan" in l: 640 count += 1 641 if count != 1: 642 logger.info(res) 643 raise Exception("Unexpected number of scan radio work items") 644 645 dev[0].dump_monitor() 646 dev[0].request("RADIO_WORK done " + id) 647 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) 648 if ev is None: 649 raise Exception("Scan did not start") 650 if "FAIL-BUSY" not in dev[0].request("SCAN"): 651 raise Exception("SCAN accepted while one is already in progress") 652 653 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 654 if ev is None: 655 raise Exception("Scan did not complete") 656 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.2) 657 if ev is not None: 658 raise Exception("Unexpected scan started") 659 660def test_scan_setband(dev, apdev): 661 """Band selection for scan operations""" 662 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 663 wpas.interface_add("wlan5") 664 devs = [ dev[0], dev[1], dev[2], wpas ] 665 666 try: 667 hapd = None 668 hapd2 = None 669 params = {"ssid": "test-setband", 670 "hw_mode": "a", 671 "channel": "36", 672 "country_code": "US"} 673 hapd = hostapd.add_ap(apdev[0], params) 674 bssid = apdev[0]['bssid'] 675 676 params = {"ssid": "test-setband", 677 "hw_mode": "g", 678 "channel": "1"} 679 hapd2 = hostapd.add_ap(apdev[1], params) 680 bssid2 = apdev[1]['bssid'] 681 682 if "FAIL" not in dev[0].request("SET setband FOO"): 683 raise Exception("Invalid set setband accepted") 684 if "OK" not in dev[0].request("SET setband AUTO"): 685 raise Exception("Failed to set setband") 686 if "OK" not in dev[1].request("SET setband 5G"): 687 raise Exception("Failed to set setband") 688 if "OK" not in dev[2].request("SET setband 2G"): 689 raise Exception("Failed to set setband") 690 if "OK" not in wpas.request("SET setband 2G,5G"): 691 raise Exception("Failed to set setband") 692 693 # Allow a retry to avoid reporting errors during heavy load 694 for j in range(5): 695 for d in devs: 696 d.request("SCAN only_new=1") 697 698 for d in devs: 699 ev = d.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 30) 700 if ev is None: 701 raise Exception("Scan timed out") 702 703 res0 = dev[0].request("SCAN_RESULTS") 704 res1 = dev[1].request("SCAN_RESULTS") 705 res2 = dev[2].request("SCAN_RESULTS") 706 res3 = wpas.request("SCAN_RESULTS") 707 if bssid in res0 and bssid2 in res0 and \ 708 bssid in res1 and bssid2 in res2 and \ 709 bssid in res3 and bssid2 in res3: 710 break 711 712 res = dev[0].request("SCAN_RESULTS") 713 if bssid not in res or bssid2 not in res: 714 raise Exception("Missing scan result(0)") 715 716 res = dev[1].request("SCAN_RESULTS") 717 if bssid not in res: 718 raise Exception("Missing scan result(1)") 719 if bssid2 in res: 720 raise Exception("Unexpected scan result(1)") 721 722 res = dev[2].request("SCAN_RESULTS") 723 if bssid2 not in res: 724 raise Exception("Missing scan result(2)") 725 if bssid in res: 726 raise Exception("Unexpected scan result(2)") 727 728 res = wpas.request("SCAN_RESULTS") 729 if bssid not in res or bssid2 not in res: 730 raise Exception("Missing scan result(3)") 731 finally: 732 if hapd: 733 hapd.request("DISABLE") 734 if hapd2: 735 hapd2.request("DISABLE") 736 subprocess.call(['iw', 'reg', 'set', '00']) 737 for d in devs: 738 d.request("SET setband AUTO") 739 d.flush_scan_cache() 740 741@remote_compatible 742def test_scan_hidden_many(dev, apdev): 743 """scan_ssid=1 with large number of profile with hidden SSID""" 744 try: 745 _test_scan_hidden_many(dev, apdev) 746 finally: 747 dev[0].flush_scan_cache(freq=2432) 748 dev[0].flush_scan_cache() 749 dev[0].request("SCAN_INTERVAL 5") 750 751def _test_scan_hidden_many(dev, apdev): 752 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan-ssid", 753 "ignore_broadcast_ssid": "1"}) 754 bssid = apdev[0]['bssid'] 755 756 dev[0].request("SCAN_INTERVAL 1") 757 758 for i in range(5): 759 id = dev[0].add_network() 760 dev[0].set_network_quoted(id, "ssid", "foo") 761 dev[0].set_network(id, "key_mgmt", "NONE") 762 dev[0].set_network(id, "disabled", "0") 763 dev[0].set_network(id, "scan_freq", "2412") 764 dev[0].set_network(id, "scan_ssid", "1") 765 766 dev[0].set_network_quoted(id, "ssid", "test-scan-ssid") 767 dev[0].set_network(id, "key_mgmt", "NONE") 768 dev[0].set_network(id, "disabled", "0") 769 dev[0].set_network(id, "scan_freq", "2412") 770 dev[0].set_network(id, "scan_ssid", "1") 771 772 for i in range(5): 773 id = dev[0].add_network() 774 dev[0].set_network_quoted(id, "ssid", "foo") 775 dev[0].set_network(id, "key_mgmt", "NONE") 776 dev[0].set_network(id, "disabled", "0") 777 dev[0].set_network(id, "scan_freq", "2412") 778 dev[0].set_network(id, "scan_ssid", "1") 779 780 dev[0].request("REASSOCIATE") 781 dev[0].wait_connected(timeout=30) 782 dev[0].request("REMOVE_NETWORK all") 783 hapd.disable() 784 785def test_scan_random_mac(dev, apdev, params): 786 """Random MAC address in scans""" 787 try: 788 _test_scan_random_mac(dev, apdev, params) 789 finally: 790 dev[0].request("MAC_RAND_SCAN all enable=0") 791 792def _test_scan_random_mac(dev, apdev, params): 793 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 794 bssid = apdev[0]['bssid'] 795 796 tests = ["", 797 "addr=foo", 798 "mask=foo", 799 "enable=1", 800 "all enable=1 mask=00:11:22:33:44:55", 801 "all enable=1 addr=00:11:22:33:44:55", 802 "all enable=1 addr=01:11:22:33:44:55 mask=ff:ff:ff:ff:ff:ff", 803 "all enable=1 addr=00:11:22:33:44:55 mask=fe:ff:ff:ff:ff:ff", 804 "enable=2 scan sched pno all", 805 "pno enable=1", 806 "all enable=2", 807 "foo"] 808 for args in tests: 809 if "FAIL" not in dev[0].request("MAC_RAND_SCAN " + args): 810 raise Exception("Invalid MAC_RAND_SCAN accepted: " + args) 811 812 if dev[0].get_driver_status_field('capa.mac_addr_rand_scan_supported') != '1': 813 raise HwsimSkip("Driver does not support random MAC address for scanning") 814 815 tests = ["all enable=1", 816 "all enable=1 addr=f2:11:22:33:44:55 mask=ff:ff:ff:ff:ff:ff", 817 "all enable=1 addr=f2:11:33:00:00:00 mask=ff:ff:ff:00:00:00"] 818 for args in tests: 819 dev[0].request("MAC_RAND_SCAN " + args) 820 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 821 822 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), 823 "wlan.fc.type_subtype == 4", ["wlan.ta"]) 824 if out is not None: 825 addr = out.splitlines() 826 logger.info("Probe Request frames seen from: " + str(addr)) 827 if dev[0].own_addr() in addr: 828 raise Exception("Real address used to transmit Probe Request frame") 829 if "f2:11:22:33:44:55" not in addr: 830 raise Exception("Fully configured random address not seen") 831 found = False 832 for a in addr: 833 if a.startswith('f2:11:33'): 834 found = True 835 break 836 if not found: 837 raise Exception("Fixed OUI random address not seen") 838 839def test_scan_random_mac_connected(dev, apdev, params): 840 """Random MAC address in scans while connected""" 841 try: 842 _test_scan_random_mac_connected(dev, apdev, params) 843 finally: 844 dev[0].request("MAC_RAND_SCAN all enable=0") 845 846def _test_scan_random_mac_connected(dev, apdev, params): 847 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 848 bssid = apdev[0]['bssid'] 849 if dev[0].get_driver_status_field('capa.mac_addr_rand_scan_supported') != '1': 850 raise HwsimSkip("Driver does not support random MAC address for scanning") 851 852 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412") 853 854 hostapd.add_ap(apdev[1], {"ssid": "test-scan-2", "channel": "11"}) 855 bssid1 = apdev[1]['bssid'] 856 857 # Verify that scanning can be completed while connected even if that means 858 # disabling use of random MAC address. 859 dev[0].request("MAC_RAND_SCAN all enable=1") 860 dev[0].scan_for_bss(bssid1, freq=2462, force_scan=True) 861 862@remote_compatible 863def test_scan_trigger_failure(dev, apdev): 864 """Scan trigger to the driver failing""" 865 if dev[0].get_status_field('wpa_state') == "SCANNING": 866 raise Exception("wpa_state was already SCANNING") 867 868 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 869 bssid = apdev[0]['bssid'] 870 871 if "OK" not in dev[0].request("SET test_failure 1"): 872 raise Exception("Failed to set test_failure") 873 874 if "OK" not in dev[0].request("SCAN"): 875 raise Exception("SCAN command failed") 876 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10) 877 if ev is None: 878 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event") 879 if "retry=1" in ev: 880 raise Exception("Unexpected scan retry indicated") 881 if dev[0].get_status_field('wpa_state') == "SCANNING": 882 raise Exception("wpa_state SCANNING not cleared") 883 884 id = dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412", 885 only_add_network=True) 886 dev[0].select_network(id) 887 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10) 888 if ev is None: 889 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event") 890 if "retry=1" not in ev: 891 raise Exception("No scan retry indicated for connection") 892 if dev[0].get_status_field('wpa_state') == "SCANNING": 893 raise Exception("wpa_state SCANNING not cleared") 894 dev[0].request("SET test_failure 0") 895 dev[0].wait_connected() 896 897 dev[0].request("SET test_failure 1") 898 if "OK" not in dev[0].request("SCAN"): 899 raise Exception("SCAN command failed") 900 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=10) 901 if ev is None: 902 raise Exception("Did not receive CTRL-EVENT-SCAN-FAILED event") 903 if "retry=1" in ev: 904 raise Exception("Unexpected scan retry indicated") 905 if dev[0].get_status_field('wpa_state') != "COMPLETED": 906 raise Exception("wpa_state COMPLETED not restored") 907 dev[0].request("SET test_failure 0") 908 909@remote_compatible 910def test_scan_specify_ssid(dev, apdev): 911 """Control interface behavior on scan SSID parameter""" 912 dev[0].flush_scan_cache() 913 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-hidden", 914 "ignore_broadcast_ssid": "1"}) 915 bssid = apdev[0]['bssid'] 916 check_scan(dev[0], "freq=2412 use_id=1 ssid 414243") 917 bss = dev[0].get_bss(bssid) 918 if bss is not None and bss['ssid'] == 'test-hidden': 919 raise Exception("BSS entry for hidden AP present unexpectedly") 920 # Allow couple more retries to avoid reporting errors during heavy load 921 for i in range(5): 922 check_scan(dev[0], "freq=2412 ssid 414243 ssid 746573742d68696464656e ssid 616263313233 use_id=1") 923 bss = dev[0].get_bss(bssid) 924 if bss and 'test-hidden' in dev[0].request("SCAN_RESULTS"): 925 break 926 if bss is None: 927 raise Exception("BSS entry for hidden AP not found") 928 if 'test-hidden' not in dev[0].request("SCAN_RESULTS"): 929 raise Exception("Expected SSID not included in the scan results") 930 931 hapd.disable() 932 dev[0].flush_scan_cache(freq=2432) 933 dev[0].flush_scan_cache() 934 935 if "FAIL" not in dev[0].request("SCAN ssid foo"): 936 raise Exception("Invalid SCAN command accepted") 937 938@remote_compatible 939def test_scan_ap_scan_2_ap_mode(dev, apdev): 940 """AP_SCAN 2 AP mode and scan()""" 941 try: 942 _test_scan_ap_scan_2_ap_mode(dev, apdev) 943 finally: 944 dev[0].request("AP_SCAN 1") 945 946def _test_scan_ap_scan_2_ap_mode(dev, apdev): 947 if "OK" not in dev[0].request("AP_SCAN 2"): 948 raise Exception("Failed to set AP_SCAN 2") 949 950 id = dev[0].add_network() 951 dev[0].set_network(id, "mode", "2") 952 dev[0].set_network_quoted(id, "ssid", "wpas-ap-open") 953 dev[0].set_network(id, "key_mgmt", "NONE") 954 dev[0].set_network(id, "frequency", "2412") 955 dev[0].set_network(id, "scan_freq", "2412") 956 dev[0].set_network(id, "disabled", "0") 957 dev[0].select_network(id) 958 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=5) 959 if ev is None: 960 raise Exception("AP failed to start") 961 962 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"): 963 if "OK" not in dev[0].request("SCAN freq=2412"): 964 raise Exception("SCAN command failed unexpectedly") 965 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED", 966 "AP-DISABLED"], timeout=5) 967 if ev is None: 968 raise Exception("CTRL-EVENT-SCAN-FAILED not seen") 969 if "AP-DISABLED" in ev: 970 raise Exception("Unexpected AP-DISABLED event") 971 if "retry=1" in ev: 972 # Wait for the retry to scan happen 973 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED", 974 "AP-DISABLED"], timeout=5) 975 if ev is None: 976 raise Exception("CTRL-EVENT-SCAN-FAILED not seen - retry") 977 if "AP-DISABLED" in ev: 978 raise Exception("Unexpected AP-DISABLED event - retry") 979 980 dev[1].connect("wpas-ap-open", key_mgmt="NONE", scan_freq="2412") 981 dev[1].request("DISCONNECT") 982 dev[1].wait_disconnected() 983 dev[0].request("DISCONNECT") 984 dev[0].wait_disconnected() 985 986def test_scan_bss_expiration_on_ssid_change(dev, apdev): 987 """BSS entry expiration when AP changes SSID""" 988 dev[0].flush_scan_cache() 989 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 990 bssid = apdev[0]['bssid'] 991 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 992 993 hapd.request("DISABLE") 994 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 995 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 3"): 996 raise Exception("BSS_EXPIRE_COUNT failed") 997 dev[0].scan(freq="2412") 998 dev[0].scan(freq="2412") 999 if "OK" not in dev[0].request("BSS_EXPIRE_COUNT 2"): 1000 raise Exception("BSS_EXPIRE_COUNT failed") 1001 res = dev[0].request("SCAN_RESULTS") 1002 if "test-scan" not in res: 1003 raise Exception("The first SSID not in scan results") 1004 if "open" not in res: 1005 raise Exception("The second SSID not in scan results") 1006 dev[0].connect("open", key_mgmt="NONE") 1007 1008 dev[0].request("BSS_FLUSH 0") 1009 res = dev[0].request("SCAN_RESULTS") 1010 if "test-scan" in res: 1011 raise Exception("The BSS entry with the old SSID was not removed") 1012 dev[0].request("DISCONNECT") 1013 dev[0].wait_disconnected() 1014 1015def test_scan_dfs(dev, apdev, params): 1016 """Scan on DFS channels""" 1017 try: 1018 _test_scan_dfs(dev, apdev, params) 1019 finally: 1020 clear_regdom_dev(dev) 1021 1022def _test_scan_dfs(dev, apdev, params): 1023 subprocess.call(['iw', 'reg', 'set', 'US']) 1024 for i in range(2): 1025 for j in range(5): 1026 ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) 1027 if ev is None: 1028 raise Exception("No regdom change event") 1029 if "alpha2=US" in ev: 1030 break 1031 dev[i].dump_monitor() 1032 1033 if "OK" not in dev[0].request("SCAN"): 1034 raise Exception("SCAN command failed") 1035 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=30) 1036 if ev is None: 1037 raise Exception("Scan did not complete") 1038 1039 if "OK" not in dev[0].request("SCAN freq=2412,5180,5260,5500,5600,5745"): 1040 raise Exception("SCAN command failed") 1041 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 1042 if ev is None: 1043 raise Exception("Scan did not complete") 1044 1045 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), 1046 "wlan.fc.type_subtype == 4", ["radiotap.channel.freq"]) 1047 if out is not None: 1048 freq = out.splitlines() 1049 freq = [int(f) for f in freq] 1050 freq = list(set(freq)) 1051 freq.sort() 1052 logger.info("Active scan seen on channels: " + str(freq)) 1053 for f in freq: 1054 if (f >= 5260 and f <= 5320) or (f >= 5500 and f <= 5700): 1055 raise Exception("Active scan on DFS channel: %d" % f) 1056 if f in [2467, 2472]: 1057 raise Exception("Active scan on US-disallowed channel: %d" % f) 1058 1059@remote_compatible 1060def test_scan_abort(dev, apdev): 1061 """Aborting a full scan""" 1062 dev[0].request("SCAN") 1063 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 1064 if ev is None: 1065 raise Exception("Scan did not start") 1066 if "OK" not in dev[0].request("ABORT_SCAN"): 1067 raise Exception("ABORT_SCAN command failed") 1068 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=2) 1069 if ev is None: 1070 raise Exception("Scan did not terminate") 1071 1072@remote_compatible 1073def test_scan_abort_on_connect(dev, apdev): 1074 """Aborting a full scan on connection request""" 1075 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1076 bssid = apdev[0]['bssid'] 1077 1078 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 1079 dev[0].dump_monitor() 1080 dev[0].request("SCAN") 1081 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 1082 if ev is None: 1083 raise Exception("Scan did not start") 1084 dev[0].connect("test-scan", key_mgmt="NONE") 1085 1086@remote_compatible 1087def test_scan_ext(dev, apdev): 1088 """Custom IE in Probe Request frame""" 1089 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1090 bssid = apdev[0]['bssid'] 1091 1092 try: 1093 if "OK" not in dev[0].request("VENDOR_ELEM_ADD 14 dd050011223300"): 1094 raise Exception("VENDOR_ELEM_ADD failed") 1095 check_scan(dev[0], "freq=2412 use_id=1") 1096 finally: 1097 dev[0].request("VENDOR_ELEM_REMOVE 14 *") 1098 1099def test_scan_fail(dev, apdev): 1100 """Scan failures""" 1101 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"): 1102 dev[0].request("DISCONNECT") 1103 if "OK" not in dev[0].request("SCAN freq=2412"): 1104 raise Exception("SCAN failed") 1105 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5) 1106 if ev is None: 1107 raise Exception("Did not see scan failure event") 1108 dev[0].dump_monitor() 1109 1110 for i in range(1, 5): 1111 with alloc_fail(dev[0], i, 1112 "wpa_scan_clone_params;wpa_supplicant_trigger_scan"): 1113 if "OK" not in dev[0].request("SCAN ssid 112233 freq=2412"): 1114 raise Exception("SCAN failed") 1115 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5) 1116 if ev is None: 1117 raise Exception("Did not see scan failure event") 1118 dev[0].dump_monitor() 1119 1120 with alloc_fail(dev[0], 1, "radio_add_work;wpa_supplicant_trigger_scan"): 1121 if "OK" not in dev[0].request("SCAN freq=2412"): 1122 raise Exception("SCAN failed") 1123 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5) 1124 if ev is None: 1125 raise Exception("Did not see scan failure event") 1126 dev[0].dump_monitor() 1127 1128 try: 1129 if "OK" not in dev[0].request("SET filter_ssids 1"): 1130 raise Exception("SET failed") 1131 id = dev[0].connect("test-scan", key_mgmt="NONE", only_add_network=True) 1132 with alloc_fail(dev[0], 1, "wpa_supplicant_build_filter_ssids"): 1133 # While the filter list cannot be created due to memory allocation 1134 # failure, this scan is expected to be completed without SSID 1135 # filtering. 1136 if "OK" not in dev[0].request("SCAN freq=2412"): 1137 raise Exception("SCAN failed") 1138 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 1139 if ev is None: 1140 raise Exception("Scan did not complete") 1141 dev[0].remove_network(id) 1142 finally: 1143 dev[0].request("SET filter_ssids 0") 1144 dev[0].dump_monitor() 1145 1146 with alloc_fail(dev[0], 1, "nl80211_get_scan_results"): 1147 if "OK" not in dev[0].request("SCAN freq=2412"): 1148 raise Exception("SCAN failed") 1149 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) 1150 if ev is None: 1151 raise Exception("Did not see scan started event") 1152 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1153 dev[0].dump_monitor() 1154 1155 try: 1156 if "OK" not in dev[0].request("SET setband 2G"): 1157 raise Exception("SET setband failed") 1158 with alloc_fail(dev[0], 1, "=wpa_add_scan_freqs_list"): 1159 # While the frequency list cannot be created due to memory 1160 # allocation failure, this scan is expected to be completed without 1161 # frequency filtering. 1162 if "OK" not in dev[0].request("SCAN"): 1163 raise Exception("SCAN failed") 1164 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") 1165 dev[0].request("ABORT_SCAN") 1166 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 1167 if ev is None: 1168 raise Exception("Scan did not complete") 1169 finally: 1170 dev[0].request("SET setband AUTO") 1171 dev[0].dump_monitor() 1172 1173 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 1174 wpas.interface_add("wlan5") 1175 wpas.request("SET preassoc_mac_addr 1") 1176 with fail_test(wpas, 1, "nl80211_set_mac_addr;wpas_trigger_scan_cb"): 1177 if "OK" not in wpas.request("SCAN freq=2412"): 1178 raise Exception("SCAN failed") 1179 ev = wpas.wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5) 1180 if ev is None: 1181 raise Exception("Did not see scan failure event") 1182 wpas.request("SET preassoc_mac_addr 0") 1183 wpas.dump_monitor() 1184 1185 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 1186 with alloc_fail(dev[0], 1, "wpa_bss_add"): 1187 dev[0].flush_scan_cache() 1188 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412") 1189 1190def test_scan_fail_type_only(dev, apdev): 1191 """Scan failures for TYPE=ONLY""" 1192 with fail_test(dev[0], 1, "wpa_driver_nl80211_scan"): 1193 dev[0].request("SCAN TYPE=ONLY freq=2417") 1194 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-FAILED"], timeout=5) 1195 if ev is None: 1196 raise Exception("Scan trigger failure not reported") 1197 # Verify that scan_only_handler() does not get left set as the 1198 # wpa_s->scan_res_handler in failure case. 1199 hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) 1200 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412") 1201 1202@remote_compatible 1203def test_scan_freq_list(dev, apdev): 1204 """Scan with SET freq_list and scan_cur_freq""" 1205 try: 1206 if "OK" not in dev[0].request("SET freq_list 2412 2417"): 1207 raise Exception("SET freq_list failed") 1208 check_scan(dev[0], "use_id=1") 1209 finally: 1210 dev[0].request("SET freq_list ") 1211 1212 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1213 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412") 1214 try: 1215 if "OK" not in dev[0].request("SET scan_cur_freq 1"): 1216 raise Exception("SET scan_cur_freq failed") 1217 check_scan(dev[0], "use_id=1") 1218 finally: 1219 dev[0].request("SET scan_cur_freq 0") 1220 dev[0].request("REMOVE_NETWORK all") 1221 dev[0].wait_disconnected() 1222 1223def test_scan_bss_limit(dev, apdev): 1224 """Scan and wpa_supplicant BSS entry limit""" 1225 try: 1226 _test_scan_bss_limit(dev, apdev) 1227 finally: 1228 dev[0].request("SET bss_max_count 200") 1229 pass 1230 1231def _test_scan_bss_limit(dev, apdev): 1232 dev[0].flush_scan_cache() 1233 # Trigger 'Increasing the MAX BSS count to 2 because all BSSes are in use. 1234 # We should normally not get here!' message by limiting the maximum BSS 1235 # count to one so that the second AP would not fit in the BSS list and the 1236 # first AP cannot be removed from the list since it is still in use. 1237 dev[0].request("SET bss_max_count 1") 1238 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1239 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412") 1240 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "test-scan-2", 1241 "channel": "6"}) 1242 dev[0].scan_for_bss(apdev[1]['bssid'], freq=2437, force_scan=True) 1243 1244def run_scan(dev, bssid, exp_freq): 1245 for i in range(5): 1246 dev.request("SCAN freq=2412,2437,2462") 1247 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 1248 if ev is None: 1249 raise Exception("Scan did not complete") 1250 bss = dev.get_bss(bssid) 1251 freq = int(bss['freq']) if bss else 0 1252 if freq == exp_freq: 1253 break 1254 if freq != exp_freq: 1255 raise Exception("BSS entry shows incorrect frequency: %d != %d" % (freq, exp_freq)) 1256 1257def test_scan_chan_switch(dev, apdev): 1258 """Scanning and AP changing channels""" 1259 1260 # This test verifies that wpa_supplicant updates its local BSS table based 1261 # on the correct cfg80211 scan entry in cases where the cfg80211 BSS table 1262 # has multiple (one for each frequency) BSS entries for the same BSS. 1263 1264 csa_supported(dev[0]) 1265 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan", "channel": "1"}) 1266 csa_supported(hapd) 1267 bssid = hapd.own_addr() 1268 1269 logger.info("AP channel switch while not connected") 1270 run_scan(dev[0], bssid, 2412) 1271 dev[0].dump_monitor() 1272 switch_channel(hapd, 1, 2437) 1273 run_scan(dev[0], bssid, 2437) 1274 dev[0].dump_monitor() 1275 switch_channel(hapd, 1, 2462) 1276 run_scan(dev[0], bssid, 2462) 1277 dev[0].dump_monitor() 1278 1279 logger.info("AP channel switch while connected") 1280 dev[0].connect("test-scan", key_mgmt="NONE", scan_freq="2412 2437 2462") 1281 run_scan(dev[0], bssid, 2462) 1282 dev[0].dump_monitor() 1283 switch_channel(hapd, 2, 2437) 1284 wait_channel_switch(dev[0], 2437) 1285 dev[0].dump_monitor() 1286 run_scan(dev[0], bssid, 2437) 1287 dev[0].dump_monitor() 1288 switch_channel(hapd, 2, 2412) 1289 wait_channel_switch(dev[0], 2412) 1290 dev[0].dump_monitor() 1291 run_scan(dev[0], bssid, 2412) 1292 dev[0].dump_monitor() 1293 1294def test_scan_new_only(dev, apdev): 1295 """Scan and only_new=1 multiple times""" 1296 dev[0].flush_scan_cache() 1297 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1298 dev[0].set("ignore_old_scan_res", "1") 1299 # Get the BSS added to cfg80211 BSS list 1300 bssid = hapd.own_addr() 1301 dev[0].scan_for_bss(bssid, freq=2412) 1302 bss = dev[0].get_bss(bssid) 1303 idx1 = bss['update_idx'] 1304 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 1305 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 1306 bss = dev[0].get_bss(bssid) 1307 idx2 = bss['update_idx'] 1308 if int(idx2) <= int(idx1): 1309 raise Exception("Scan result update_idx did not increase") 1310 # Disable AP to ensure there are no new scan results after this. 1311 hapd.disable() 1312 1313 # Try to scan multiple times to verify that old scan results do not get 1314 # accepted as new. 1315 for i in range(10): 1316 dev[0].scan(freq=2412) 1317 bss = dev[0].get_bss(bssid) 1318 if bss: 1319 idx = bss['update_idx'] 1320 if int(idx) > int(idx2): 1321 raise Exception("Unexpected update_idx increase") 1322 1323def test_scan_flush(dev, apdev): 1324 """Ongoing scan and FLUSH""" 1325 dev[0].flush_scan_cache() 1326 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1327 dev[0].dump_monitor() 1328 dev[0].request("SCAN TYPE=ONLY freq=2412-2472 passive=1") 1329 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=10) 1330 if ev is None: 1331 raise Exception("Scan did not start") 1332 time.sleep(0.1) 1333 dev[0].request("FLUSH") 1334 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS", 1335 "CTRL-EVENT-SCAN-FAILED", 1336 "CTRL-EVENT-BSS-ADDED"], timeout=10) 1337 if ev is None: 1338 raise Exception("Scan did not complete") 1339 if "CTRL-EVENT-BSS-ADDED" in ev: 1340 raise Exception("Unexpected BSS entry addition after FLUSH") 1341 1342def test_scan_ies(dev, apdev): 1343 """Scan and both Beacon and Probe Response frame IEs""" 1344 dev[0].flush_scan_cache() 1345 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan", 1346 "beacon_int": "20"}) 1347 bssid = hapd.own_addr() 1348 dev[0].dump_monitor() 1349 1350 for i in range(10): 1351 dev[0].request("SCAN TYPE=ONLY freq=2412 passive=1") 1352 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=15) 1353 if ev is None: 1354 raise Exception("Scan did not complete") 1355 if dev[0].get_bss(bssid): 1356 break 1357 1358 for i in range(10): 1359 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 1360 bss = dev[0].get_bss(bssid) 1361 if 'beacon_ie' in bss: 1362 if bss['ie'] != bss['beacon_ie']: 1363 break 1364 1365 if not bss or 'beacon_ie' not in bss: 1366 raise Exception("beacon_ie not present") 1367 ie = parse_ie(bss['ie']) 1368 logger.info("ie: " + str(list(ie.keys()))) 1369 beacon_ie = parse_ie(bss['beacon_ie']) 1370 logger.info("beacon_ie: " + str(list(ie.keys()))) 1371 if bss['ie'] == bss['beacon_ie']: 1372 raise Exception("Both ie and beacon_ie show same data") 1373 1374def test_scan_parsing(dev, apdev): 1375 """Scan result parsing""" 1376 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES START"): 1377 raise Exception("DRIVER_EVENT SCAN_RES START failed") 1378 1379 if "FAIL" not in dev[0].request("DRIVER_EVENT SCAN_RES foo "): 1380 raise Exception("Invalid DRIVER_EVENT SCAN_RES accepted") 1381 1382 tests = ["", 1383 "flags=ffffffff", 1384 "bssid=02:03:04:05:06:07", 1385 "freq=1234", 1386 "beacon_int=102", 1387 "caps=1234", 1388 "qual=10", 1389 "noise=10", 1390 "level=10", 1391 "tsf=1122334455667788", 1392 "age=123", 1393 "est_throughput=100", 1394 "snr=10", 1395 "parent_tsf=1122334455667788", 1396 "tsf_bssid=02:03:04:05:06:07", 1397 "ie=00", 1398 "beacon_ie=00", 1399 # Too long SSID 1400 "bssid=02:ff:00:00:00:01 ie=0033" + 33*'FF', 1401 # All parameters 1402 "flags=ffffffff bssid=02:ff:00:00:00:02 freq=1234 beacon_int=102 caps=1234 qual=10 noise=10 level=10 tsf=1122334455667788 age=123 est_throughput=100 snr=10 parent_tsf=1122334455667788 tsf_bssid=02:03:04:05:06:07 ie=000474657374 beacon_ie=000474657374", 1403 # Beacon IEs truncated 1404 "bssid=02:ff:00:00:00:03 ie=0000 beacon_ie=0003ffff", 1405 # Probe Response IEs truncated 1406 "bssid=02:ff:00:00:00:04 ie=00000101 beacon_ie=0000", 1407 # DMG (invalid caps) 1408 "bssid=02:ff:00:00:00:05 freq=58320 ie=0003646d67", 1409 # DMG (IBSS) 1410 "bssid=02:ff:00:00:00:06 freq=60480 caps=0001 ie=0003646d67", 1411 # DMG (PBSS) 1412 "bssid=02:ff:00:00:00:07 freq=62640 caps=0002 ie=0003646d67", 1413 # DMG (AP) 1414 "bssid=02:ff:00:00:00:08 freq=64800 caps=0003 ie=0003646d67", 1415 # Test BSS for updates 1416 "bssid=02:ff:00:00:00:09 freq=2412 caps=0011 level=1 ie=0003757064010182", 1417 # Minimal BSS data 1418 "bssid=02:ff:00:00:00:00 ie=0000"] 1419 for t in tests: 1420 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES BSS " + t): 1421 raise Exception("DRIVER_EVENT SCAN_RES BSS failed") 1422 1423 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES END"): 1424 raise Exception("DRIVER_EVENT SCAN_RES END failed") 1425 1426 res = dev[0].request("SCAN_RESULTS") 1427 logger.info("SCAN_RESULTS:\n" + res) 1428 1429 bss = [] 1430 res = dev[0].request("BSS FIRST") 1431 if "FAIL" in res: 1432 raise Exception("BSS FIRST failed") 1433 while "\nbssid=" in res: 1434 logger.info("BSS output:\n" + res) 1435 bssid = None 1436 id = None 1437 for val in res.splitlines(): 1438 if val.startswith("id="): 1439 id = val.split('=')[1] 1440 if val.startswith("bssid="): 1441 bssid = val.split('=')[1] 1442 if bssid is None or id is None: 1443 raise Exception("Missing id or bssid line") 1444 bss.append(bssid) 1445 res = dev[0].request("BSS NEXT-" + id) 1446 1447 logger.info("Discovered BSSs: " + str(bss)) 1448 invalid_bss = ["02:03:04:05:06:07", "02:ff:00:00:00:01"] 1449 valid_bss = ["02:ff:00:00:00:00", "02:ff:00:00:00:02", 1450 "02:ff:00:00:00:03", "02:ff:00:00:00:04", 1451 "02:ff:00:00:00:05", "02:ff:00:00:00:06", 1452 "02:ff:00:00:00:07", "02:ff:00:00:00:08", 1453 "02:ff:00:00:00:09"] 1454 for bssid in invalid_bss: 1455 if bssid in bss: 1456 raise Exception("Invalid BSS included: " + bssid) 1457 for bssid in valid_bss: 1458 if bssid not in bss: 1459 raise Exception("Valid BSS missing: " + bssid) 1460 1461 logger.info("Update BSS parameters") 1462 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES START"): 1463 raise Exception("DRIVER_EVENT SCAN_RES START failed") 1464 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES BSS bssid=02:ff:00:00:00:09 freq=2412 caps=0002 level=2 ie=000375706401028204"): 1465 raise Exception("DRIVER_EVENT SCAN_RES BSS failed") 1466 if "OK" not in dev[0].request("DRIVER_EVENT SCAN_RES END"): 1467 raise Exception("DRIVER_EVENT SCAN_RES END failed") 1468 res = dev[0].request("BSS 02:ff:00:00:00:09") 1469 logger.info("Updated BSS:\n" + res) 1470 1471def get_probe_req_ies(hapd): 1472 for i in range(10): 1473 msg = hapd.mgmt_rx() 1474 if msg is None: 1475 break 1476 if msg['subtype'] != 4: 1477 continue 1478 return parse_ie(binascii.hexlify(msg['payload']).decode()) 1479 1480 raise Exception("Probe Request not seen") 1481 1482def test_scan_specific_bssid(dev, apdev): 1483 """Scan for a specific BSSID""" 1484 dev[0].flush_scan_cache() 1485 hapd = hostapd.add_ap(apdev[0], {"ssid": "test-scan", 1486 "beacon_int": "1000"}) 1487 bssid = hapd.own_addr() 1488 1489 time.sleep(0.1) 1490 dev[0].request("SCAN TYPE=ONLY freq=2412 bssid=02:ff:ff:ff:ff:ff") 1491 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 1492 if ev is None: 1493 raise Exception("Scan did not complete") 1494 bss1 = dev[0].get_bss(bssid) 1495 1496 for i in range(10): 1497 dev[0].request("SCAN TYPE=ONLY freq=2412 bssid=" + bssid) 1498 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 1499 if ev is None: 1500 raise Exception("Scan did not complete") 1501 bss2 = dev[0].get_bss(bssid) 1502 if bss2: 1503 break 1504 1505 if not bss2: 1506 raise Exception("Did not find BSS") 1507 if bss1 and 'beacon_ie' in bss1 and 'ie' in bss1 and bss1['beacon_ie'] != bss1['ie']: 1508 raise Exception("First scan for unknown BSSID returned unexpected response") 1509 if bss2 and 'beacon_ie' in bss2 and 'ie' in bss2 and bss2['beacon_ie'] == bss2['ie']: 1510 raise Exception("Second scan did find Probe Response frame") 1511 1512 hapd.dump_monitor() 1513 hapd.set("ext_mgmt_frame_handling", "1") 1514 1515 # With specific SSID in the Probe Request frame 1516 dev[0].request("SCAN TYPE=ONLY freq=2412 bssid=" + bssid) 1517 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 1518 if ev is None: 1519 raise Exception("Scan did not complete") 1520 ie = get_probe_req_ies(hapd) 1521 if ie[0] != b"test-scan": 1522 raise Exception("Specific SSID not seen in Probe Request frame") 1523 1524 hapd.dump_monitor() 1525 1526 # Without specific SSID in the Probe Request frame 1527 dev[0].request("SCAN TYPE=ONLY freq=2412 wildcard_ssid=1 bssid=" + bssid) 1528 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 1529 if ev is None: 1530 raise Exception("Scan did not complete") 1531 ie = get_probe_req_ies(hapd) 1532 if len(ie[0]) != 0: 1533 raise Exception("Wildcard SSID not seen in Probe Request frame") 1534 1535def test_scan_probe_req_events(dev, apdev): 1536 """Probe Request frame RX events from hostapd""" 1537 run_scan_probe_req_events(dev, apdev) 1538 1539def test_scan_probe_req_events_with_payload(dev, apdev): 1540 """Probe Request frame RX events with payload from hostapd""" 1541 run_scan_probe_req_events(dev, apdev, with_payload=True) 1542 1543def run_scan_probe_req_events(dev, apdev, with_payload=False): 1544 params = {"ssid": "open"} 1545 if with_payload: 1546 params["notify_mgmt_frames"] = "1" 1547 hapd = hostapd.add_ap(apdev[0], params) 1548 hapd2 = hostapd.Hostapd(apdev[0]['ifname']) 1549 if "OK" not in hapd2.mon.request("ATTACH probe_rx_events=1"): 1550 raise Exception("Failed to register for events") 1551 1552 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True) 1553 1554 ev = hapd2.wait_event(["RX-PROBE-REQUEST"], timeout=5) 1555 if ev is None: 1556 raise Exception("RX-PROBE-REQUEST not reported") 1557 if "sa=" + dev[0].own_addr() not in ev: 1558 raise Exception("Unexpected event parameters: " + ev) 1559 if with_payload and " buf=40" not in ev: 1560 raise Exception("Missing payload in event parameters: " + ev) 1561 1562 ev = hapd.wait_event(["RX-PROBE-REQUEST"], timeout=0.1) 1563 if ev is not None: 1564 raise Exception("Unexpected RX-PROBE-REQUEST") 1565 1566 if "OK" not in hapd2.mon.request("ATTACH probe_rx_events=0"): 1567 raise Exception("Failed to update event registration") 1568 1569 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True) 1570 ev = hapd2.wait_event(["RX-PROBE-REQUEST"], timeout=0.5) 1571 if ev is not None: 1572 raise Exception("Unexpected RX-PROBE-REQUEST") 1573 1574 tests = ["probe_rx_events", "probe_rx_events=-1", "probe_rx_events=2"] 1575 for val in tests: 1576 if "FAIL" not in hapd2.mon.request("ATTACH " + val): 1577 raise Exception("Invalid ATTACH command accepted") 1578 1579def elem_capab(capab): 1580 # Nontransmitted BSSID Capability element (83 = 0x53) 1581 return struct.pack('<BBH', 83, 2, capab) 1582 1583def elem_ssid(ssid): 1584 # SSID element 1585 return struct.pack('BB', 0, len(ssid)) + ssid.encode() 1586 1587def elem_bssid_index(index): 1588 # Multiple BSSID-index element (85 = 0x55) 1589 return struct.pack('BBB', 85, 1, index) 1590 1591def elem_multibssid(profiles, max_bssid_indic): 1592 # TODO: add support for fragmenting over multiple Multiple BSSID elements 1593 if 1 + len(profiles) > 255: 1594 raise Exception("Too long Multiple BSSID element") 1595 elem = struct.pack('BBB', 71, 1 + len(profiles), max_bssid_indic) + profiles 1596 return binascii.hexlify(elem).decode() 1597 1598def run_scans(dev, check): 1599 for i in range(2): 1600 dev.request("SCAN TYPE=ONLY freq=2412") 1601 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10) 1602 if ev is None: 1603 raise Exception("Scan did not complete") 1604 1605 # TODO: Check IEs 1606 for (bssid, ssid, capab) in check: 1607 bss = dev.get_bss(bssid) 1608 if bss is None: 1609 raise Exception("AP " + bssid + " missing from scan results") 1610 logger.info("AP " + bssid + ": " + str(bss)) 1611 if bss['ssid'] != ssid: 1612 raise Exception("Unexpected AP " + bssid + " SSID") 1613 if int(bss['capabilities'], 16) != capab: 1614 raise Exception("Unexpected AP " + bssid + " capabilities") 1615 1616def check_multibss_sta_capa(dev): 1617 res = dev.get_capability("multibss") 1618 if res is None or 'MULTIBSS-STA' not in res: 1619 raise HwsimSkip("Multi-BSS STA functionality not supported") 1620 1621def test_scan_multi_bssid(dev, apdev): 1622 """Scan and Multiple BSSID element""" 1623 check_multibss_sta_capa(dev[0]) 1624 dev[0].flush_scan_cache() 1625 1626 params = {"ssid": "test-scan"} 1627 # Max BSSID Indicator 0 (max 1 BSSID) and no subelements 1628 params['vendor_elements'] = elem_multibssid(b'', 0) 1629 hostapd.add_ap(apdev[0], params) 1630 1631 params = {"ssid": "test-scan"} 1632 elems = elem_capab(0x0401) + elem_ssid("1") + elem_bssid_index(1) 1633 profile1 = struct.pack('BB', 0, len(elems)) + elems 1634 params['vendor_elements'] = elem_multibssid(profile1, 1) 1635 hostapd.add_ap(apdev[1], params) 1636 1637 bssid0 = apdev[0]['bssid'] 1638 bssid1 = apdev[1]['bssid'] 1639 check = [(bssid0, 'test-scan', 0x401), 1640 (bssid1, 'test-scan', 0x401), 1641 (bssid1[0:16] + '1', '1', 0x401)] 1642 run_scans(dev[0], check) 1643 1644def test_scan_multi_bssid_2(dev, apdev): 1645 """Scan and Multiple BSSID element (2)""" 1646 check_multibss_sta_capa(dev[0]) 1647 dev[0].flush_scan_cache() 1648 1649 params = {"ssid": "transmitted"} 1650 1651 # Duplicated entry for the transmitted BSS (not a normal use case) 1652 elems = elem_capab(1) + elem_ssid("transmitted") + elem_bssid_index(0) 1653 profile1 = struct.pack('BB', 0, len(elems)) + elems 1654 1655 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) 1656 profile2 = struct.pack('BB', 0, len(elems)) + elems 1657 1658 elems = elem_capab(1) + elem_ssid("nontransmitted_2") + elem_bssid_index(2) 1659 profile3 = struct.pack('BB', 0, len(elems)) + elems 1660 1661 profiles = profile1 + profile2 + profile3 1662 params['vendor_elements'] = elem_multibssid(profiles, 4) 1663 hostapd.add_ap(apdev[0], params) 1664 1665 bssid = apdev[0]['bssid'] 1666 check = [(bssid, 'transmitted', 0x401), 1667 (bssid[0:16] + '1', 'nontransmitted', 0x1), 1668 (bssid[0:16] + '2', 'nontransmitted_2', 0x1)] 1669 run_scans(dev[0], check) 1670 1671def test_scan_multi_bssid_3(dev, apdev): 1672 """Scan and Multiple BSSID element (3)""" 1673 check_multibss_sta_capa(dev[0]) 1674 dev[0].flush_scan_cache() 1675 1676 params = {"ssid": "transmitted"} 1677 1678 # Duplicated nontransmitted BSS (not a normal use case) 1679 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) 1680 profile1 = struct.pack('BB', 0, len(elems)) + elems 1681 1682 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) 1683 profile2 = struct.pack('BB', 0, len(elems)) + elems 1684 1685 profiles = profile1 + profile2 1686 params['vendor_elements'] = elem_multibssid(profiles, 2) 1687 hostapd.add_ap(apdev[0], params) 1688 1689 bssid = apdev[0]['bssid'] 1690 check = [(bssid, 'transmitted', 0x401), 1691 (bssid[0:16] + '1', 'nontransmitted', 0x1)] 1692 run_scans(dev[0], check) 1693 1694def test_scan_multi_bssid_4(dev, apdev): 1695 """Scan and Multiple BSSID element (3)""" 1696 check_multibss_sta_capa(dev[0]) 1697 dev[0].flush_scan_cache() 1698 1699 # Transmitted BSSID is not the first one in the block 1700 bssid = apdev[0]['bssid'] 1701 hapd = None 1702 try: 1703 params = {"ssid": "transmitted", 1704 "bssid": bssid[0:16] + '1'} 1705 1706 elems = elem_capab(1) + elem_ssid("1") + elem_bssid_index(1) 1707 profile1 = struct.pack('BB', 0, len(elems)) + elems 1708 1709 elems = elem_capab(1) + elem_ssid("2") + elem_bssid_index(2) 1710 profile2 = struct.pack('BB', 0, len(elems)) + elems 1711 1712 elems = elem_capab(1) + elem_ssid("3") + elem_bssid_index(3) 1713 profile3 = struct.pack('BB', 0, len(elems)) + elems 1714 1715 profiles = profile1 + profile2 + profile3 1716 params['vendor_elements'] = elem_multibssid(profiles, 2) 1717 hapd = hostapd.add_ap(apdev[0], params) 1718 1719 check = [(bssid[0:16] + '1', 'transmitted', 0x401), 1720 (bssid[0:16] + '2', '1', 0x1), 1721 (bssid[0:16] + '3', '2', 0x1), 1722 (bssid[0:16] + '0', '3', 0x1)] 1723 run_scans(dev[0], check) 1724 finally: 1725 if hapd: 1726 hapd.disable() 1727 hapd.set('bssid', bssid) 1728 hapd.enable() 1729 1730def test_scan_multi_bssid_check_ie(dev, apdev): 1731 """Scan and check if nontransmitting BSS inherits IE from transmitting BSS""" 1732 check_multibss_sta_capa(dev[0]) 1733 dev[0].flush_scan_cache() 1734 1735 params = {"ssid": "transmitted"} 1736 1737 # Duplicated entry for the transmitted BSS (not a normal use case) 1738 elems = elem_capab(1) + elem_ssid("transmitted") + elem_bssid_index(0) 1739 profile1 = struct.pack('BB', 0, len(elems)) + elems 1740 1741 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) 1742 profile2 = struct.pack('BB', 0, len(elems)) + elems 1743 1744 profiles = profile1 + profile2 1745 params['vendor_elements'] = elem_multibssid(profiles, 2) 1746 hostapd.add_ap(apdev[0], params) 1747 1748 bssid = apdev[0]['bssid'] 1749 1750 for i in range(10): 1751 dev[0].request("SCAN TYPE=ONLY freq=2412 passive=1") 1752 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=15) 1753 if ev is None: 1754 raise Exception("Scan did not complete") 1755 if dev[0].get_bss(bssid): 1756 break 1757 1758 for i in range(10): 1759 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 1760 bss = dev[0].get_bss(bssid) 1761 if 'beacon_ie' in bss: 1762 break 1763 1764 trans_bss = dev[0].get_bss(bssid) 1765 if trans_bss is None: 1766 raise Exception("AP " + bssid + " missing from scan results") 1767 1768 if not trans_bss or 'beacon_ie' not in trans_bss: 1769 raise Exception("beacon_ie not present in trans_bss") 1770 1771 beacon_ie = parse_ie(trans_bss['beacon_ie']) 1772 logger.info("trans_bss beacon_ie: " + str(list(beacon_ie.keys()))) 1773 1774 bssid = bssid[0:16] + '1' 1775 nontrans_bss1 = dev[0].get_bss(bssid) 1776 if nontrans_bss1 is None: 1777 raise Exception("AP " + bssid + " missing from scan results") 1778 1779 if not trans_bss or 'beacon_ie' not in nontrans_bss1: 1780 raise Exception("beacon_ie not present in nontrans_bss1") 1781 1782 nontx_beacon_ie = parse_ie(nontrans_bss1['beacon_ie']) 1783 logger.info("nontrans_bss1 beacon_ie: " + str(list(nontx_beacon_ie.keys()))) 1784 1785 if 71 in list(beacon_ie.keys()): 1786 ie_list = list(beacon_ie.keys()) 1787 ie_list.remove(71) 1788 nontx_ie_list = list(nontx_beacon_ie.keys()) 1789 try: 1790 nontx_ie_list.remove(85) 1791 except ValueError: 1792 pass 1793 if sorted(ie_list) != sorted(nontx_ie_list): 1794 raise Exception("check IE failed") 1795 1796def elem_fms1(): 1797 # this FMS IE has 1 FMS counter 1798 fms_counters = struct.pack('B', 0x39) 1799 fms_ids = struct.pack('B', 0x01) 1800 return struct.pack('BBB', 86, 3, 1) + fms_counters + fms_ids 1801 1802def elem_fms2(): 1803 # this FMS IE has 2 FMS counters 1804 fms_counters = struct.pack('BB', 0x29, 0x32) 1805 fms_ids = struct.pack('BB', 0x01, 0x02) 1806 return struct.pack('BBB', 86, 5, 2) + fms_counters + fms_ids 1807 1808def test_scan_multi_bssid_fms(dev, apdev): 1809 """Non-transmitting BSS has different FMS IE from transmitting BSS""" 1810 check_multibss_sta_capa(dev[0]) 1811 dev[0].flush_scan_cache() 1812 1813 params = {"ssid": "transmitted"} 1814 1815 # construct transmitting BSS Beacon with FMS IE 1816 elems = elem_capab(1) + elem_ssid("transmitted") + elem_bssid_index(0) + elem_fms1() 1817 profile1 = struct.pack('BB', 0, len(elems)) + elems 1818 1819 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) + elem_fms2() 1820 profile2 = struct.pack('BB', 0, len(elems)) + elems 1821 1822 profiles = profile1 + profile2 1823 params['vendor_elements'] = elem_multibssid(profiles, 2) + binascii.hexlify(elem_fms1()).decode() 1824 hostapd.add_ap(apdev[0], params) 1825 1826 bssid = apdev[0]['bssid'] 1827 1828 for i in range(10): 1829 dev[0].request("SCAN TYPE=ONLY freq=2412 passive=1") 1830 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=15) 1831 if ev is None: 1832 raise Exception("Scan did not complete") 1833 if dev[0].get_bss(bssid): 1834 break 1835 1836 for i in range(10): 1837 dev[0].scan_for_bss(bssid, freq=2412, force_scan=True) 1838 bss = dev[0].get_bss(bssid) 1839 if 'beacon_ie' in bss: 1840 break 1841 1842 trans_bss = dev[0].get_bss(bssid) 1843 if trans_bss is None: 1844 raise Exception("AP " + bssid + " missing from scan results") 1845 1846 if not trans_bss or 'beacon_ie' not in trans_bss: 1847 raise Exception("beacon_ie not present in trans_bss") 1848 1849 beacon_ie = parse_ie(trans_bss['beacon_ie']) 1850 trans_bss_fms = beacon_ie[86] 1851 logger.info("trans_bss fms ie: " + binascii.hexlify(trans_bss_fms).decode()) 1852 1853 bssid = bssid[0:16] + '1' 1854 nontrans_bss1 = dev[0].get_bss(bssid) 1855 if nontrans_bss1 is None: 1856 raise Exception("AP " + bssid + " missing from scan results") 1857 1858 if not nontrans_bss1 or 'beacon_ie' not in nontrans_bss1: 1859 raise Exception("beacon_ie not present in nontrans_bss1") 1860 1861 nontrans_beacon_ie = parse_ie(nontrans_bss1['beacon_ie']) 1862 nontrans_bss_fms = nontrans_beacon_ie[86] 1863 logger.info("nontrans_bss fms ie: " + binascii.hexlify(nontrans_bss_fms).decode()) 1864 1865 if binascii.hexlify(trans_bss_fms) == binascii.hexlify(nontrans_bss_fms): 1866 raise Exception("Nontrans BSS has the same FMS IE as trans BSS") 1867 1868def test_scan_multiple_mbssid_ie(dev, apdev): 1869 """Transmitting BSS has 2 MBSSID IE""" 1870 check_multibss_sta_capa(dev[0]) 1871 dev[0].flush_scan_cache() 1872 1873 bssid = apdev[0]['bssid'] 1874 logger.info("bssid: " + bssid) 1875 hapd = None 1876 1877 # construct 2 MBSSID IEs, each MBSSID IE contains 1 profile 1878 params = {"ssid": "transmitted", 1879 "bssid": bssid} 1880 1881 elems = elem_capab(1) + elem_ssid("1") + elem_bssid_index(1) 1882 profile1 = struct.pack('BB', 0, len(elems)) + elems 1883 1884 elems = elem_capab(2) + elem_ssid("2") + elem_bssid_index(2) 1885 profile2 = struct.pack('BB', 0, len(elems)) + elems 1886 1887 params['vendor_elements'] = elem_multibssid(profile1, 2) + elem_multibssid(profile2, 2) 1888 hapd = hostapd.add_ap(apdev[0], params) 1889 1890 check = [(bssid, 'transmitted', 0x401), 1891 (bssid[0:16] + '1', '1', 0x1), 1892 (bssid[0:16] + '2', '2', 0x2)] 1893 run_scans(dev[0], check) 1894 1895def test_scan_mbssid_hidden_ssid(dev, apdev): 1896 """Non-transmitting BSS has hidden SSID""" 1897 check_multibss_sta_capa(dev[0]) 1898 dev[0].flush_scan_cache() 1899 1900 bssid = apdev[0]['bssid'] 1901 logger.info("bssid: " + bssid) 1902 hapd = None 1903 1904 # construct 2 MBSSID IEs, each MBSSID IE contains 1 profile 1905 params = {"ssid": "transmitted", 1906 "bssid": bssid} 1907 1908 elems = elem_capab(1) + elem_ssid("") + elem_bssid_index(1) 1909 profile1 = struct.pack('BB', 0, len(elems)) + elems 1910 1911 elems = elem_capab(2) + elem_ssid("2") + elem_bssid_index(2) 1912 profile2 = struct.pack('BB', 0, len(elems)) + elems 1913 1914 profiles = profile1 + profile2 1915 params['vendor_elements'] = elem_multibssid(profiles, 2) 1916 hapd = hostapd.add_ap(apdev[0], params) 1917 1918 check = [(bssid, 'transmitted', 0x401), 1919 (bssid[0:16] + '1', '', 0x1), 1920 (bssid[0:16] + '2', '2', 0x2)] 1921 run_scans(dev[0], check) 1922 1923def test_connect_mbssid_open_1(dev, apdev): 1924 """Connect to transmitting and nontransmitting BSS in open mode""" 1925 check_multibss_sta_capa(dev[0]) 1926 dev[0].flush_scan_cache() 1927 1928 bssid = apdev[0]['bssid'] 1929 params = {"ssid": "transmitted"} 1930 1931 elems = elem_capab(1) + elem_ssid("nontransmitted") + elem_bssid_index(1) 1932 profile1 = struct.pack('BB', 0, len(elems)) + elems 1933 1934 elems = elem_capab(1) + elem_ssid("nontransmitted_2") + elem_bssid_index(2) 1935 profile2 = struct.pack('BB', 0, len(elems)) + elems 1936 1937 profiles = profile1 + profile2 1938 params['vendor_elements'] = elem_multibssid(profiles, 4) 1939 hostapd.add_ap(apdev[0], params) 1940 1941 dev[0].connect("transmitted", key_mgmt="NONE", scan_freq="2412") 1942 dev[0].request("REMOVE_NETWORK all") 1943 dev[0].wait_disconnected() 1944 dev[0].dump_monitor() 1945 1946 dev[0].connect("nontransmitted", key_mgmt="NONE", scan_freq="2412", 1947 wait_connect=False) 1948 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=10) 1949 if ev is None: 1950 raise Exception("Connection attempt to nontransmitted BSS not started") 1951 if "02:00:00:00:03:01 (SSID='nontransmitted'" not in ev: 1952 raise Exception("Unexpected authentication target") 1953 # hostapd does not yet support Multiple-BSSID, so only verify that STA is 1954 # able to start connection attempt. 1955 dev[0].request("REMOVE_NETWORK all") 1956 dev[0].dump_monitor() 1957 1958 dev[0].connect("nontransmitted_2", key_mgmt="NONE", scan_freq="2412", 1959 wait_connect=False) 1960 ev = dev[0].wait_event(["SME: Trying to authenticate"], timeout=10) 1961 if ev is None: 1962 raise Exception("Connection attempt to nontransmitted BSS not started") 1963 if "02:00:00:00:03:02 (SSID='nontransmitted_2'" not in ev: 1964 raise Exception("Unexpected authentication target") 1965 # hostapd does not yet support Multiple-BSSID, so only verify that STA is 1966 # able to start connection attempt. 1967 dev[0].request("REMOVE_NETWORK all") 1968 dev[0].dump_monitor() 1969 1970def test_scan_only_one(dev, apdev): 1971 """Test that scanning with a single active AP only returns that one""" 1972 dev[0].flush_scan_cache() 1973 hostapd.add_ap(apdev[0], {"ssid": "test-scan"}) 1974 bssid = apdev[0]['bssid'] 1975 1976 check_scan(dev[0], "use_id=1", test_busy=True) 1977 dev[0].scan_for_bss(bssid, freq="2412") 1978 1979 status, stdout = hostapd.cmd_execute(dev[0], ['iw', dev[0].ifname, 'scan', 'dump']) 1980 if status != 0: 1981 raise Exception("iw scan dump failed with code %d" % status) 1982 lines = stdout.split('\n') 1983 entries = len(list(filter(lambda x: x.startswith('BSS '), lines))) 1984 if entries != 1: 1985 raise Exception("expected to find 1 BSS entry, got %d" % entries) 1986 1987def test_scan_ssid_list(dev, apdev): 1988 """Scan using SSID List element""" 1989 dev[0].flush_scan_cache() 1990 ssid = "test-ssid-list" 1991 hapd = hostapd.add_ap(apdev[0], {"ssid": ssid, 1992 "ignore_broadcast_ssid": "1"}) 1993 bssid = apdev[0]['bssid'] 1994 found = False 1995 try: 1996 payload = struct.pack('BB', 0, len(ssid)) + ssid.encode() 1997 ssid_list = struct.pack('BB', 84, len(payload)) + payload 1998 cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode() 1999 if "OK" not in dev[0].request(cmd): 2000 raise Exception("VENDOR_ELEM_ADD failed") 2001 for i in range(10): 2002 check_scan(dev[0], "freq=2412 use_id=1") 2003 if ssid in dev[0].request("SCAN_RESULTS"): 2004 found = True 2005 break 2006 finally: 2007 dev[0].request("VENDOR_ELEM_REMOVE 14 *") 2008 hapd.disable() 2009 dev[0].flush_scan_cache(freq=2432) 2010 dev[0].flush_scan_cache() 2011 2012 if not found: 2013 raise Exception("AP not found in scan results") 2014 2015def test_scan_short_ssid_list(dev, apdev): 2016 """Scan using Short SSID List element""" 2017 dev[0].flush_scan_cache() 2018 ssid = "test-short-ssid-list" 2019 hapd = hostapd.add_ap(apdev[0], {"ssid": ssid, 2020 "ignore_broadcast_ssid": "1"}) 2021 bssid = apdev[0]['bssid'] 2022 found = False 2023 try: 2024 payload = struct.pack('<L', binascii.crc32(ssid.encode())) 2025 ssid_list = struct.pack('BBB', 255, 1 + len(payload), 58) + payload 2026 cmd = "VENDOR_ELEM_ADD 14 " + binascii.hexlify(ssid_list).decode() 2027 if "OK" not in dev[0].request(cmd): 2028 raise Exception("VENDOR_ELEM_ADD failed") 2029 for i in range(10): 2030 check_scan(dev[0], "freq=2412 use_id=1") 2031 if ssid in dev[0].request("SCAN_RESULTS"): 2032 found = True 2033 break 2034 finally: 2035 dev[0].request("VENDOR_ELEM_REMOVE 14 *") 2036 hapd.disable() 2037 dev[0].flush_scan_cache(freq=2432) 2038 dev[0].flush_scan_cache() 2039 2040 if not found: 2041 raise Exception("AP not found in scan results") 2042