1 # WNM tests 2 # Copyright (c) 2013-2019, 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 7 from remotehost import remote_compatible 8 import binascii 9 import struct 10 import time 11 import logging 12 logger = logging.getLogger() 13 import subprocess 14 15 import hostapd 16 from wpasupplicant import WpaSupplicant 17 from utils import * 18 from wlantest import Wlantest 19 from datetime import datetime 20 21 def clear_regdom_state(dev, hapd, hapd2): 22 for i in range(0, 3): 23 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 24 if ev is None or "init=COUNTRY_IE" in ev: 25 break 26 if hapd: 27 hapd.request("DISABLE") 28 if hapd2: 29 hapd2.request("DISABLE") 30 subprocess.call(['iw', 'reg', 'set', '00']) 31 dev[0].disconnect_and_stop_scan() 32 subprocess.call(['iw', 'reg', 'set', '00']) 33 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 34 dev[0].flush_scan_cache() 35 36 def start_wnm_ap(apdev, bss_transition=True, time_adv=False, ssid=None, 37 wnm_sleep_mode=False, wnm_sleep_mode_no_keys=False, rsn=False, 38 ocv=False, ap_max_inactivity=0, coloc_intf_reporting=False, 39 hw_mode=None, channel=None, country_code=None, country3=None, 40 pmf=True, passphrase=None, ht=True, vht=False, mbo=False, 41 beacon_prot=False, he=False, bss_max_idle=None, 42 wpa_group_rekey=None, no_disconnect_on_group_keyerror=False, 43 max_acceptable_idle_period=None): 44 if rsn: 45 if not ssid: 46 ssid = "test-wnm-rsn" 47 if not passphrase: 48 passphrase = "12345678" 49 params = hostapd.wpa2_params(ssid, passphrase) 50 if pmf: 51 params["wpa_key_mgmt"] = "WPA-PSK-SHA256" 52 params["ieee80211w"] = "2" 53 if beacon_prot: 54 params["beacon_prot"] = "1" 55 else: 56 params = {"ssid": "test-wnm"} 57 if bss_transition: 58 params["bss_transition"] = "1" 59 if time_adv: 60 params["time_advertisement"] = "2" 61 params["time_zone"] = "EST5" 62 if wnm_sleep_mode: 63 params["wnm_sleep_mode"] = "1" 64 if wnm_sleep_mode_no_keys: 65 params["wnm_sleep_mode_no_keys"] = "1" 66 if ocv: 67 params["ocv"] = "1" 68 if ap_max_inactivity: 69 params["ap_max_inactivity"] = str(ap_max_inactivity) 70 if coloc_intf_reporting: 71 params["coloc_intf_reporting"] = "1" 72 if hw_mode: 73 params["hw_mode"] = hw_mode 74 if channel: 75 params["channel"] = channel 76 if country_code: 77 params["country_code"] = country_code 78 params["ieee80211d"] = "1" 79 if country3: 80 params["country3"] = country3 81 if not ht: 82 params['ieee80211n'] = '0' 83 if vht: 84 params['ieee80211ac'] = "1" 85 params["vht_oper_chwidth"] = "0" 86 params["vht_oper_centr_freq_seg0_idx"] = "0" 87 if he: 88 params["ieee80211ax"] = "1" 89 params["he_bss_color"] = "42" 90 if mbo: 91 params["mbo"] = "1" 92 if bss_max_idle is not None: 93 params["bss_max_idle"] = str(bss_max_idle) 94 if wpa_group_rekey: 95 params["wpa_group_rekey"] = str(wpa_group_rekey) 96 if no_disconnect_on_group_keyerror: 97 params["no_disconnect_on_group_keyerror"] = "1" 98 if max_acceptable_idle_period is not None: 99 params["max_acceptable_idle_period"] = str(max_acceptable_idle_period) 100 try: 101 hapd = hostapd.add_ap(apdev, params) 102 except Exception as e: 103 if "Failed to set hostapd parameter ocv" in str(e): 104 raise HwsimSkip("OCV not supported") 105 raise 106 if rsn: 107 Wlantest.setup(hapd) 108 wt = Wlantest() 109 wt.flush() 110 wt.add_passphrase("12345678") 111 return hapd 112 113 @remote_compatible 114 def test_wnm_bss_transition_mgmt(dev, apdev): 115 """WNM BSS Transition Management""" 116 start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True) 117 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 118 dev[0].request("WNM_BSS_QUERY 0") 119 120 def test_wnm_bss_transition_mgmt_oom(dev, apdev): 121 """WNM BSS Transition Management OOM""" 122 hapd = start_wnm_ap(apdev[0]) 123 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 124 with alloc_fail(hapd, 1, "ieee802_11_send_bss_trans_mgmt_request"): 125 dev[0].request("WNM_BSS_QUERY 0") 126 wait_fail_trigger(hapd, "GET_ALLOC_FAIL") 127 128 @remote_compatible 129 def test_wnm_disassoc_imminent(dev, apdev): 130 """WNM Disassociation Imminent""" 131 hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True) 132 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 133 addr = dev[0].p2p_interface_addr() 134 hapd.request("DISASSOC_IMMINENT " + addr + " 10") 135 ev = dev[0].wait_event(["WNM: Disassociation Imminent"]) 136 if ev is None: 137 raise Exception("Timeout while waiting for disassociation imminent") 138 if "Disassociation Timer 10" not in ev: 139 raise Exception("Unexpected disassociation imminent contents") 140 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 141 if ev is None: 142 raise Exception("Timeout while waiting for re-connection scan") 143 144 def test_wnm_disassoc_imminent_bssid_set(dev, apdev): 145 """WNM Disassociation Imminent and bssid set""" 146 hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True) 147 hapd2 = start_wnm_ap(apdev[1], time_adv=True, wnm_sleep_mode=True) 148 dev[0].connect("test-wnm", key_mgmt="NONE", bssid=hapd.own_addr(), 149 scan_freq="2412") 150 addr = dev[0].own_addr() 151 cmd = "BSS_TM_REQ " + addr + " pref=1 disassoc_imminent=1 disassoc_timer=100 neighbor=" + apdev[1]['bssid'] + ",0x0000," + "81,1,7,0301ff" 152 if "OK" not in hapd.request(cmd): 153 raise Exception("BSS_TM_REQ command failed") 154 155 ev = dev[0].wait_event(["WNM: Disassociation Imminent"]) 156 if ev is None: 157 raise Exception("Timeout while waiting for disassociation imminent") 158 if "Disassociation Timer 100" not in ev: 159 raise Exception("Unexpected disassociation imminent contents") 160 161 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 162 if ev is None: 163 raise Exception("No BSS Transition Management Response") 164 if "status_code=7" not in ev: 165 raise Exception("Unexpected BSS TM response status: " + ev) 166 167 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=2) 168 if ev is not None: 169 raise Exception("Unexpected scan started") 170 171 dev[0].request("DISCONNECT") 172 dev[0].wait_disconnected() 173 174 def test_wnm_disassoc_imminent_fail(dev, apdev): 175 """WNM Disassociation Imminent failure""" 176 hapd = start_wnm_ap(apdev[0]) 177 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 178 addr = dev[0].own_addr() 179 with fail_test(hapd, 1, "wnm_send_disassoc_imminent"): 180 if "FAIL" not in hapd.request("DISASSOC_IMMINENT " + addr + " 10"): 181 raise Exception("DISASSOC_IMMINENT succeeded during failure testing") 182 183 @remote_compatible 184 def test_wnm_ess_disassoc_imminent(dev, apdev): 185 """WNM ESS Disassociation Imminent""" 186 hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True) 187 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 188 addr = dev[0].p2p_interface_addr() 189 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info") 190 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"]) 191 if ev is None: 192 raise Exception("Timeout while waiting for ESS disassociation imminent") 193 if "0 1024 http://example.com/session-info" not in ev: 194 raise Exception("Unexpected ESS disassociation imminent message contents") 195 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 196 if ev is None: 197 raise Exception("Timeout while waiting for re-connection scan") 198 199 def test_wnm_ess_disassoc_imminent_fail(dev, apdev): 200 """WNM ESS Disassociation Imminent failure""" 201 hapd = start_wnm_ap(apdev[0]) 202 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 203 addr = dev[0].own_addr() 204 if "FAIL" not in hapd.request("ESS_DISASSOC " + addr + " 10 http://" + 256*'a'): 205 raise Exception("Invalid ESS_DISASSOC URL accepted") 206 with fail_test(hapd, 1, "wnm_send_ess_disassoc_imminent"): 207 if "FAIL" not in hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info"): 208 raise Exception("ESS_DISASSOC succeeded during failure testing") 209 210 def test_wnm_ess_disassoc_imminent_reject(dev, apdev): 211 """WNM ESS Disassociation Imminent getting rejected""" 212 hapd = start_wnm_ap(apdev[0]) 213 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 214 addr = dev[0].own_addr() 215 if "OK" not in dev[0].request("SET reject_btm_req_reason 123"): 216 raise Exception("Failed to set reject_btm_req_reason") 217 218 hapd.request("ESS_DISASSOC " + addr + " 1 http://example.com/session-info") 219 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=10) 220 if ev is None: 221 raise Exception("BSS-TM-RESP not seen") 222 if "status_code=123" not in ev: 223 raise Exception("Unexpected response status: " + ev) 224 dev[0].wait_disconnected() 225 dev[0].request("DISCONNECT") 226 227 @remote_compatible 228 def test_wnm_ess_disassoc_imminent_pmf(dev, apdev): 229 """WNM ESS Disassociation Imminent""" 230 hapd = start_wnm_ap(apdev[0], rsn=True) 231 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 232 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 233 addr = dev[0].p2p_interface_addr() 234 hapd.wait_sta(wait_4way_hs=True) 235 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info") 236 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"]) 237 if ev is None: 238 raise Exception("Timeout while waiting for ESS disassociation imminent") 239 if "1 1024 http://example.com/session-info" not in ev: 240 raise Exception("Unexpected ESS disassociation imminent message contents") 241 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"]) 242 if ev is None: 243 raise Exception("Timeout while waiting for re-connection scan") 244 245 def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None, 246 rekey=False): 247 addr = dev.p2p_interface_addr() 248 sta = hapd.get_sta(addr) 249 if "[WNM_SLEEP_MODE]" in sta['flags']: 250 raise Exception("Station unexpectedly in WNM-Sleep Mode") 251 252 logger.info("Going to WNM Sleep Mode") 253 extra = "" 254 if interval is not None: 255 extra += " interval=" + str(interval) 256 if tfs_req: 257 extra += " tfs_req=" + tfs_req 258 if "OK" not in dev.request("WNM_SLEEP enter" + extra): 259 raise Exception("WNM_SLEEP failed") 260 ok = False 261 for i in range(20): 262 time.sleep(0.1) 263 sta = hapd.get_sta(addr) 264 if "[WNM_SLEEP_MODE]" in sta['flags']: 265 ok = True 266 break 267 if not ok: 268 raise Exception("Station failed to enter WNM-Sleep Mode") 269 270 if rekey: 271 time.sleep(0.1) 272 if "OK" not in hapd.request("REKEY_GTK"): 273 raise Exception("REKEY_GTK failed") 274 ev = dev.wait_event(["RSN: Group rekeying completed"], timeout=0.1) 275 if ev is not None: 276 raise Exception("Unexpected report of GTK rekey during WNM-Sleep Mode") 277 278 logger.info("Waking up from WNM Sleep Mode") 279 ok = False 280 dev.request("WNM_SLEEP exit") 281 for i in range(20): 282 time.sleep(0.1) 283 sta = hapd.get_sta(addr) 284 if "[WNM_SLEEP_MODE]" not in sta['flags']: 285 ok = True 286 break 287 if not ok: 288 raise Exception("Station failed to exit WNM-Sleep Mode") 289 290 if rekey: 291 time.sleep(0.1) 292 if "OK" not in hapd.request("REKEY_GTK"): 293 raise Exception("REKEY_GTK failed") 294 ev = dev.wait_event(["RSN: Group rekeying completed"], timeout=2) 295 if ev is None: 296 raise Exception("GTK rekey timed out") 297 298 @remote_compatible 299 def test_wnm_sleep_mode_open(dev, apdev): 300 """WNM Sleep Mode - open""" 301 hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True) 302 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 303 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 304 if ev is None: 305 raise Exception("No connection event received from hostapd") 306 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 307 check_wnm_sleep_mode_enter_exit(hapd, dev[0], interval=100) 308 check_wnm_sleep_mode_enter_exit(hapd, dev[0], tfs_req="5b17010001130e110000071122334455661122334455661234") 309 310 cmds = ["foo", 311 "exit tfs_req=123 interval=10", 312 "enter tfs_req=qq interval=10"] 313 for cmd in cmds: 314 if "FAIL" not in dev[0].request("WNM_SLEEP " + cmd): 315 raise Exception("Invalid WNM_SLEEP accepted") 316 317 def test_wnm_sleep_mode_open_fail(dev, apdev): 318 """WNM Sleep Mode - open (fail)""" 319 hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=True) 320 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 321 with fail_test(hapd, 1, "nl80211_send_frame_cmd;ieee802_11_send_wnmsleep_resp"): 322 dev[0].request("WNM_SLEEP enter") 323 wait_fail_trigger(hapd, "GET_FAIL") 324 325 def test_wnm_sleep_mode_disabled_on_ap(dev, apdev): 326 """WNM Sleep Mode disabled on AP""" 327 hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=False) 328 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 329 # Ignore WNM-Sleep Mode Request from 02:00:00:00:00:00 since WNM-Sleep Mode is disabled 330 dev[0].request("WNM_SLEEP enter") 331 time.sleep(0.1) 332 333 @remote_compatible 334 def test_wnm_sleep_mode_rsn(dev, apdev): 335 """WNM Sleep Mode - RSN""" 336 hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True, rsn=True, 337 pmf=False) 338 dev[0].connect("test-wnm-rsn", psk="12345678", scan_freq="2412") 339 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 340 if ev is None: 341 raise Exception("No connection event received from hostapd") 342 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 343 344 @remote_compatible 345 def test_wnm_sleep_mode_ap_oom(dev, apdev): 346 """WNM Sleep Mode - AP side OOM""" 347 hapd = start_wnm_ap(apdev[0], bss_transition=False, wnm_sleep_mode=True) 348 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 349 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 350 if ev is None: 351 raise Exception("No connection event received from hostapd") 352 with alloc_fail(hapd, 1, "ieee802_11_send_wnmsleep_resp"): 353 dev[0].request("WNM_SLEEP enter") 354 wait_fail_trigger(hapd, "GET_ALLOC_FAIL") 355 with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"): 356 dev[0].request("WNM_SLEEP exit") 357 wait_fail_trigger(hapd, "GET_ALLOC_FAIL") 358 359 @remote_compatible 360 def test_wnm_sleep_mode_rsn_pmf(dev, apdev): 361 """WNM Sleep Mode - RSN with PMF""" 362 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, time_adv=True) 363 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 364 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 365 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 366 if ev is None: 367 raise Exception("No connection event received from hostapd") 368 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 369 370 def test_wnm_sleep_mode_rsn_beacon_prot(dev, apdev): 371 """WNM Sleep Mode - RSN with PMF and beacon protection""" 372 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, time_adv=True, 373 beacon_prot=True) 374 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 375 beacon_prot="1", 376 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 377 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 378 if ev is None: 379 raise Exception("No connection event received from hostapd") 380 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 381 check_wnm_sleep_mode_enter_exit(hapd, dev[0], rekey=True) 382 383 @remote_compatible 384 def test_wnm_sleep_mode_rsn_ocv(dev, apdev): 385 """WNM Sleep Mode - RSN with OCV""" 386 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, 387 time_adv=True, ocv=True) 388 389 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1", 390 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 391 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 392 if ev is None: 393 raise Exception("No connection event received from hostapd") 394 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 395 396 # Check if OCV succeeded or failed 397 ev = dev[0].wait_event(["OCV failed"], timeout=1) 398 if ev is not None: 399 raise Exception("OCI verification failed: " + ev) 400 401 @remote_compatible 402 def test_wnm_sleep_mode_rsn_badocv(dev, apdev): 403 """WNM Sleep Mode - RSN with OCV and bad OCI elements""" 404 ssid = "test-wnm-rsn" 405 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ocv=True) 406 bssid = apdev[0]['bssid'] 407 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", ocv="1", 408 proto="WPA2", ieee80211w="2", scan_freq="2412") 409 dev[0].request("WNM_SLEEP enter") 410 time.sleep(0.1) 411 412 msg = {'fc': MGMT_SUBTYPE_ACTION << 4, 413 'da': bssid, 414 'sa': dev[0].own_addr(), 415 'bssid': bssid} 416 417 logger.debug("WNM Sleep Mode Request - Missing OCI element") 418 msg['payload'] = struct.pack("<BBBBBBBHBB", 419 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_REQ, 0, 420 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 0, 0, 421 WLAN_EID_TFS_REQ, 0) 422 mgmt_tx(dev[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format( 423 msg['da'], msg['bssid'], binascii.hexlify(msg['payload']).decode())) 424 ev = hapd.wait_event(["OCV failed"], timeout=5) 425 if ev is None: 426 raise Exception("AP did not report missing OCI element") 427 428 logger.debug("WNM Sleep Mode Request - Bad OCI element") 429 msg['payload'] = struct.pack("<BBBBBBBHBB", 430 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_REQ, 0, 431 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 0, 432 0, 433 WLAN_EID_TFS_REQ, 0) 434 oci_ie = struct.pack("<BBB", 81, 2, 0) 435 msg['payload'] += struct.pack("<BBB", WLAN_EID_EXTENSION, 1 + len(oci_ie), 436 WLAN_EID_EXT_OCV_OCI) + oci_ie 437 mgmt_tx(dev[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format( 438 msg['da'], msg['bssid'], binascii.hexlify(msg['payload']).decode())) 439 ev = hapd.wait_event(["OCV failed"], timeout=5) 440 if ev is None: 441 raise Exception("AP did not report bad OCI element") 442 443 msg = {'fc': MGMT_SUBTYPE_ACTION << 4, 444 'da': dev[0].own_addr(), 445 'sa': bssid, 446 'bssid': bssid} 447 hapd.set("ext_mgmt_frame_handling", "1") 448 449 logger.debug("WNM Sleep Mode Response - Missing OCI element") 450 msg['payload'] = struct.pack("<BBBHBBBBHBB", 451 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 452 0, 453 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 454 WNM_STATUS_SLEEP_ACCEPT, 0, 455 WLAN_EID_TFS_RESP, 0) 456 dev[0].request("WNM_SLEEP exit") 457 hapd.mgmt_tx(msg) 458 expect_ack(hapd) 459 ev = dev[0].wait_event(["OCV failed"], timeout=5) 460 if ev is None: 461 raise Exception("STA did not report missing OCI element") 462 463 logger.debug("WNM Sleep Mode Response - Bad OCI element") 464 msg['payload'] = struct.pack("<BBBHBBBBHBB", 465 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 466 0, 467 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 468 WNM_STATUS_SLEEP_ACCEPT, 0, 469 WLAN_EID_TFS_RESP, 0) 470 oci_ie = struct.pack("<BBB", 81, 2, 0) 471 msg['payload'] += struct.pack("<BBB", WLAN_EID_EXTENSION, 1 + len(oci_ie), 472 WLAN_EID_EXT_OCV_OCI) + oci_ie 473 hapd.mgmt_tx(msg) 474 expect_ack(hapd) 475 ev = dev[0].wait_event(["OCV failed"], timeout=5) 476 if ev is None: 477 raise Exception("STA did not report bad OCI element") 478 479 def test_wnm_sleep_mode_rsn_ocv_failure(dev, apdev): 480 """WNM Sleep Mode - RSN with OCV - local failure""" 481 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, 482 time_adv=True, ocv=True) 483 484 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1", 485 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 486 hapd.wait_sta() 487 # Failed to allocate buffer for OCI element in WNM-Sleep Mode frame 488 with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"): 489 if "OK" not in dev[0].request("WNM_SLEEP enter"): 490 raise Exception("WNM_SLEEP failed") 491 wait_fail_trigger(hapd, "GET_ALLOC_FAIL") 492 493 def test_wnm_sleep_mode_rsn_pmf_key_workaround(dev, apdev): 494 """WNM Sleep Mode - RSN with PMF and GTK/IGTK workaround""" 495 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, 496 wnm_sleep_mode_no_keys=True, 497 time_adv=True, ocv=True) 498 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 499 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 500 ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5) 501 if ev is None: 502 raise Exception("No connection event received from hostapd") 503 check_wnm_sleep_mode_enter_exit(hapd, dev[0]) 504 505 def test_wnm_sleep_mode_proto(dev, apdev): 506 """WNM Sleep Mode - protocol testing""" 507 hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=True, bss_transition=False) 508 bssid = hapd.own_addr() 509 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 510 addr = dev[0].own_addr() 511 512 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000" 513 hapd.set("ext_mgmt_frame_handling", "1") 514 tests = ["0a10", 515 "0a1001", 516 "0a10015d00", 517 "0a10015d01", 518 "0a10015d0400000000", 519 "0a1001" + 7*("5bff" + 255*"00") + "5d00", 520 "0a1001ff00"] 521 for t in tests: 522 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t): 523 raise Exception("MGMT_RX_PROCESS failed") 524 525 hapd.set("ext_mgmt_frame_handling", "0") 526 527 MGMT_SUBTYPE_ACTION = 13 528 ACTION_CATEG_WNM = 10 529 WNM_ACT_EVENT_REPORT = 1 530 WNM_ACT_BSS_TM_REQ = 7 531 WNM_ACT_BSS_TM_RESP = 8 532 WNM_ACT_SLEEP_MODE_REQ = 16 533 WNM_ACT_SLEEP_MODE_RESP = 17 534 WNM_ACT_NOTIFICATION_REQ = 26 535 WNM_ACT_NOTIFICATION_RESP = 27 536 WNM_NOTIF_TYPE_FW_UPGRADE = 0 537 WNM_NOTIF_TYPE_WFA = 1 538 WLAN_EID_EVENT_REPORT = 79 539 WLAN_EID_TFS_REQ = 91 540 WLAN_EID_TFS_RESP = 92 541 WLAN_EID_WNMSLEEP = 93 542 WLAN_EID_EXTENSION = 255 543 WLAN_EID_EXT_OCV_OCI = 54 544 WNM_SLEEP_MODE_ENTER = 0 545 WNM_SLEEP_MODE_EXIT = 1 546 WNM_STATUS_SLEEP_ACCEPT = 0 547 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1 548 WNM_STATUS_DENIED_ACTION = 2 549 WNM_STATUS_DENIED_TMP = 3 550 WNM_STATUS_DENIED_KEY = 4 551 WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5 552 WNM_SLEEP_SUBELEM_GTK = 0 553 WNM_SLEEP_SUBELEM_IGTK = 1 554 555 def bss_tm_req(dst, src, dialog_token=1, req_mode=0, disassoc_timer=0, 556 validity_interval=1): 557 msg = {} 558 msg['fc'] = MGMT_SUBTYPE_ACTION << 4 559 msg['da'] = dst 560 msg['sa'] = src 561 msg['bssid'] = src 562 msg['payload'] = struct.pack("<BBBBHB", 563 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ, 564 dialog_token, req_mode, disassoc_timer, 565 validity_interval) 566 return msg 567 568 def rx_bss_tm_resp(hapd, expect_dialog=None, expect_status=None): 569 for i in range(0, 100): 570 resp = hapd.mgmt_rx() 571 if resp is None: 572 raise Exception("No BSS TM Response received") 573 if resp['subtype'] == MGMT_SUBTYPE_ACTION: 574 break 575 if i == 99: 576 raise Exception("Not an Action frame") 577 payload = resp['payload'] 578 if len(payload) < 2 + 3: 579 raise Exception("Too short payload") 580 (category, action) = struct.unpack('BB', payload[0:2]) 581 if category != ACTION_CATEG_WNM or action != WNM_ACT_BSS_TM_RESP: 582 raise Exception("Not a BSS TM Response") 583 pos = payload[2:] 584 (dialog, status, bss_term_delay) = struct.unpack('BBB', pos[0:3]) 585 resp['dialog'] = dialog 586 resp['status'] = status 587 resp['bss_term_delay'] = bss_term_delay 588 pos = pos[3:] 589 if len(pos) >= 6 and status == 0: 590 resp['target_bssid'] = binascii.hexlify(pos[0:6]) 591 pos = pos[6:] 592 resp['candidates'] = pos 593 if expect_dialog is not None and dialog != expect_dialog: 594 raise Exception("Unexpected dialog token") 595 if expect_status is not None and status != expect_status: 596 raise Exception("Unexpected status code %d" % status) 597 return resp 598 599 def expect_ack(hapd): 600 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5) 601 if ev is None: 602 raise Exception("Missing TX status") 603 if "ok=1" not in ev: 604 raise Exception("Action frame not acknowledged") 605 606 def mgmt_tx(dev, msg): 607 if "FAIL" in dev.request(msg): 608 raise Exception("Failed to send Action frame") 609 ev = dev.wait_event(["MGMT-TX-STATUS"], timeout=10) 610 if ev is None: 611 raise Exception("Timeout on MGMT-TX-STATUS") 612 if "result=SUCCESS" not in ev: 613 raise Exception("Peer did not ack Action frame") 614 615 @remote_compatible 616 def test_wnm_bss_tm_req(dev, apdev): 617 """BSS Transition Management Request""" 618 hapd = start_wnm_ap(apdev[0]) 619 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 620 addr = dev[0].own_addr() 621 622 hapd.set("ext_mgmt_frame_handling", "1") 623 624 # truncated BSS TM Request 625 req = bss_tm_req(addr, apdev[0]['bssid'], 626 req_mode=0x0a) 627 req['payload'] = struct.pack("<BBBBH", 628 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ, 629 1, 0, 0) 630 hapd.mgmt_tx(req) 631 expect_ack(hapd) 632 dev[0].dump_monitor() 633 634 # no disassociation and no candidate list 635 req = bss_tm_req(addr, apdev[0]['bssid'], 636 dialog_token=2, req_mode=0x02) 637 hapd.mgmt_tx(req) 638 resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1) 639 dev[0].dump_monitor() 640 641 # truncated BSS Termination Duration 642 req = bss_tm_req(addr, apdev[0]['bssid'], 643 req_mode=0x0a) 644 hapd.mgmt_tx(req) 645 expect_ack(hapd) 646 dev[0].dump_monitor() 647 648 # BSS Termination Duration with TSF=0 and Duration=10 649 req = bss_tm_req(addr, apdev[0]['bssid'], 650 req_mode=0x0a, dialog_token=3) 651 req['payload'] += struct.pack("<BBQH", 4, 10, 0, 10) 652 hapd.mgmt_tx(req) 653 resp = rx_bss_tm_resp(hapd, expect_dialog=3, expect_status=1) 654 dev[0].dump_monitor() 655 656 # truncated Session Information URL 657 req = bss_tm_req(addr, apdev[0]['bssid'], 658 req_mode=0x12) 659 hapd.mgmt_tx(req) 660 expect_ack(hapd) 661 req = bss_tm_req(addr, apdev[0]['bssid'], 662 req_mode=0x12) 663 req['payload'] += struct.pack("<BBB", 3, 65, 66) 664 hapd.mgmt_tx(req) 665 expect_ack(hapd) 666 dev[0].dump_monitor() 667 668 # Session Information URL 669 req = bss_tm_req(addr, apdev[0]['bssid'], 670 req_mode=0x12, dialog_token=4) 671 req['payload'] += struct.pack("<BBB", 2, 65, 66) 672 hapd.mgmt_tx(req) 673 resp = rx_bss_tm_resp(hapd, expect_dialog=4, expect_status=0) 674 dev[0].dump_monitor() 675 676 # Preferred Candidate List without any entries 677 req = bss_tm_req(addr, apdev[0]['bssid'], 678 req_mode=0x03, dialog_token=5) 679 hapd.mgmt_tx(req) 680 resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7) 681 dev[0].dump_monitor() 682 683 # Preferred Candidate List with a truncated entry 684 req = bss_tm_req(addr, apdev[0]['bssid'], 685 req_mode=0x03) 686 req['payload'] += struct.pack("<BB", 52, 1) 687 hapd.mgmt_tx(req) 688 expect_ack(hapd) 689 dev[0].dump_monitor() 690 691 # Preferred Candidate List with a too short entry 692 req = bss_tm_req(addr, apdev[0]['bssid'], 693 req_mode=0x03, dialog_token=6) 694 req['payload'] += struct.pack("<BB", 52, 0) 695 hapd.mgmt_tx(req) 696 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7) 697 dev[0].dump_monitor() 698 699 # Preferred Candidate List with a non-matching entry 700 req = bss_tm_req(addr, apdev[0]['bssid'], 701 req_mode=0x03, dialog_token=6) 702 req['payload'] += struct.pack("<BB6BLBBB", 52, 13, 703 1, 2, 3, 4, 5, 6, 704 0, 81, 1, 7) 705 hapd.mgmt_tx(req) 706 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7) 707 dev[0].dump_monitor() 708 709 # Preferred Candidate List with a truncated subelement 710 req = bss_tm_req(addr, apdev[0]['bssid'], 711 req_mode=0x03, dialog_token=7) 712 req['payload'] += struct.pack("<BB6BLBBBBB", 52, 13 + 2, 713 1, 2, 3, 4, 5, 6, 714 0, 81, 1, 7, 715 1, 1) 716 hapd.mgmt_tx(req) 717 resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7) 718 dev[0].dump_monitor() 719 720 # Preferred Candidate List with lots of invalid optional subelements 721 req = bss_tm_req(addr, apdev[0]['bssid'], 722 req_mode=0x03, dialog_token=8) 723 subelems = struct.pack("<BBHB", 1, 3, 0, 100) 724 subelems += struct.pack("<BBB", 2, 1, 65) 725 subelems += struct.pack("<BB", 3, 0) 726 subelems += struct.pack("<BBQB", 4, 9, 0, 10) 727 subelems += struct.pack("<BBHLB", 5, 7, 0, 0, 0) 728 subelems += struct.pack("<BB", 66, 0) 729 subelems += struct.pack("<BBBBBB", 70, 4, 0, 0, 0, 0) 730 subelems += struct.pack("<BB", 71, 0) 731 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems), 732 1, 2, 3, 4, 5, 6, 733 0, 81, 1, 7) + subelems 734 hapd.mgmt_tx(req) 735 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7) 736 dev[0].dump_monitor() 737 738 # Preferred Candidate List with lots of valid optional subelements (twice) 739 req = bss_tm_req(addr, apdev[0]['bssid'], 740 req_mode=0x03, dialog_token=8) 741 # TSF Information 742 subelems = struct.pack("<BBHH", 1, 4, 0, 100) 743 # Condensed Country String 744 subelems += struct.pack("<BBBB", 2, 2, 65, 66) 745 # BSS Transition Candidate Preference 746 subelems += struct.pack("<BBB", 3, 1, 100) 747 # BSS Termination Duration 748 subelems += struct.pack("<BBQH", 4, 10, 0, 10) 749 # Bearing 750 subelems += struct.pack("<BBHLH", 5, 8, 0, 0, 0) 751 # Measurement Pilot Transmission 752 subelems += struct.pack("<BBBBB", 66, 3, 0, 0, 0) 753 # RM Enabled Capabilities 754 subelems += struct.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0) 755 # Multiple BSSID 756 subelems += struct.pack("<BBBB", 71, 2, 0, 0) 757 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems) * 2, 758 1, 2, 3, 4, 5, 6, 759 0, 81, 1, 7) + subelems + subelems 760 hapd.mgmt_tx(req) 761 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7) 762 dev[0].dump_monitor() 763 764 # Preferred Candidate List with truncated BSS Termination Duration 765 # WNM: Too short BSS termination duration 766 req = bss_tm_req(addr, apdev[0]['bssid'], 767 req_mode=0x03, dialog_token=8) 768 # BSS Termination Duration (truncated) 769 subelems = struct.pack("<BBQB", 4, 9, 0, 10) 770 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems), 771 1, 2, 3, 4, 5, 6, 772 0, 81, 1, 7) + subelems 773 hapd.mgmt_tx(req) 774 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7) 775 dev[0].dump_monitor() 776 777 # Preferred Candidate List followed by vendor element 778 req = bss_tm_req(addr, apdev[0]['bssid'], 779 req_mode=0x03, dialog_token=8) 780 subelems = b'' 781 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems), 782 1, 2, 3, 4, 5, 6, 783 0, 81, 1, 7) + subelems 784 req['payload'] += binascii.unhexlify("DD0411223344") 785 hapd.mgmt_tx(req) 786 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7) 787 dev[0].dump_monitor() 788 789 @remote_compatible 790 @disable_ipv6 791 def test_wnm_bss_keep_alive(dev, apdev): 792 """WNM keep-alive""" 793 run_wnm_bss_keep_alive(dev, apdev, False) 794 795 def test_wnm_bss_protected_keep_alive(dev, apdev): 796 """WNM protected keep-alive""" 797 run_wnm_bss_keep_alive(dev, apdev, True) 798 799 def run_wnm_bss_keep_alive(dev, apdev, protected): 800 hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=1, 801 bss_max_idle=2 if protected else 1, rsn=True) 802 addr = dev[0].p2p_interface_addr() 803 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 804 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 805 start = hapd.get_sta(addr) 806 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=2) 807 if ev is not None: 808 raise Exception("Unexpected disconnection") 809 end = hapd.get_sta(addr) 810 if int(end['rx_packets']) <= int(start['rx_packets']): 811 raise Exception("No keep-alive packets received") 812 try: 813 # Disable client keep-alive so that hostapd will verify connection 814 # with client poll 815 dev[0].request("SET no_keep_alive 1") 816 for i in range(60): 817 sta = hapd.get_sta(addr) 818 logger.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta['timeout_next'], sta['rx_packets'], sta['tx_packets'])) 819 if i > 1 and sta['timeout_next'] != "NULLFUNC POLL" and int(sta['tx_packets']) > int(end['tx_packets']): 820 break 821 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5) 822 if ev is not None: 823 raise Exception("Unexpected disconnection (client poll expected)") 824 finally: 825 dev[0].request("SET no_keep_alive 0") 826 if int(sta['tx_packets']) <= int(end['tx_packets']): 827 raise Exception("No client poll packet seen") 828 829 def test_wnm_bss_max_idle_period_management(dev, apdev): 830 """WNM BSS max idle period management""" 831 hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=10, 832 max_acceptable_idle_period=1000, rsn=True) 833 addr = dev[0].own_addr() 834 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 835 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412", 836 max_idle="1500") 837 addr1 = dev[1].own_addr() 838 dev[1].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 839 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 840 841 ap_val = hapd.get_sta(addr)['max_idle_period'] 842 if ap_val != '1000': 843 raise Exception("AP reported unexpected value: " + ap_val) 844 845 sta_val = dev[0].get_status_field("bss_max_idle_period") 846 if sta_val != '1000': 847 raise Exception("STA reported unexpected value: " + sta_val) 848 849 sta = hapd.get_sta(addr1) 850 if 'max_idle_period' in sta: 851 raise Exception("AP reported unexpected value(2): " + sta['max_idle_period']) 852 853 sta_val = dev[1].get_status_field("bss_max_idle_period") 854 if sta_val != '9': 855 raise Exception("STA reported unexpected value(2): " + sta_val) 856 857 def test_wnm_bss_group_rekey(dev, apdev): 858 """WNM BSS max idle period and group rekey""" 859 hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=100, 860 wpa_group_rekey=2, rsn=True) 861 addr = dev[0].own_addr() 862 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 863 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 864 start = hapd.get_sta(addr) 865 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", 866 "RSN: Group rekeying completed"], timeout=3) 867 if ev is None: 868 raise Exception("No group rekeying") 869 if "CTRL-EVENT-DISCONNECTED" in ev: 870 raise Exception("Unexpected disconnection") 871 872 hapd.set("ext_eapol_frame_io", "1") 873 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", 874 "RSN: Group rekeying completed"], timeout=20) 875 if ev is None or "CTRL-EVENT-DISCONNECTED" not in ev: 876 raise Exception("No disconnection reported on missing group rekeying") 877 dev[0].request("DISCONNECT") 878 879 def test_wnm_bss_group_rekey_skip(dev, apdev): 880 """WNM BSS max idle period and group rekey skip allowed""" 881 hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=100, 882 wpa_group_rekey=2, rsn=True, 883 no_disconnect_on_group_keyerror=True) 884 addr = dev[0].own_addr() 885 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", 886 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412") 887 start = hapd.get_sta(addr) 888 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", 889 "RSN: Group rekeying completed"], timeout=3) 890 if ev is None: 891 raise Exception("No group rekeying") 892 if "CTRL-EVENT-DISCONNECTED" in ev: 893 raise Exception("Unexpected disconnection") 894 895 hapd.set("ext_eapol_frame_io", "1") 896 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED", 897 "RSN: Group rekeying completed"], timeout=20) 898 if ev: 899 raise Exception("Unexpected event reported: " + ev) 900 dev[0].request("DISCONNECT") 901 902 def test_wnm_bss_tm(dev, apdev): 903 """WNM BSS Transition Management""" 904 try: 905 hapd = None 906 hapd2 = None 907 hapd = start_wnm_ap(apdev[0], country_code="FI") 908 dev[0].flush_scan_cache() 909 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 910 dev[0].set_network(id, "scan_freq", "") 911 912 hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a", 913 channel="36") 914 915 addr = dev[0].p2p_interface_addr() 916 dev[0].dump_monitor() 917 918 logger.info("No neighbor list entries") 919 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1"): 920 raise Exception("BSS_TM_REQ command failed") 921 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 922 if ev is None: 923 raise Exception("No BSS Transition Management Response") 924 if addr not in ev: 925 raise Exception("Unexpected BSS Transition Management Response address") 926 if "status_code=0" in ev: 927 raise Exception("BSS transition accepted unexpectedly") 928 dev[0].dump_monitor() 929 930 logger.info("Neighbor list entry, but not claimed as Preferred Candidate List") 931 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1 dialog_token=123 neighbor=11:22:33:44:55:66,0x0000,81,3,7"): 932 raise Exception("BSS_TM_REQ command failed") 933 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 934 if ev is None: 935 raise Exception("No BSS Transition Management Response") 936 if "status_code=0" in ev: 937 raise Exception("BSS transition accepted unexpectedly") 938 dev[0].dump_monitor() 939 940 logger.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent") 941 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1 pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=22:33:44:55:66:77,0x0000,1,44,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a"): 942 raise Exception("BSS_TM_REQ command failed") 943 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 944 if ev is None: 945 raise Exception("No BSS Transition Management Response") 946 if "status_code=0" in ev: 947 raise Exception("BSS transition accepted unexpectedly") 948 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) 949 if ev is None: 950 raise Exception("No scan started") 951 dev[0].dump_monitor() 952 953 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 954 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 955 raise Exception("BSS_TM_REQ command failed") 956 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 957 if ev is None: 958 raise Exception("No BSS Transition Management Response") 959 if "status_code=0" not in ev: 960 raise Exception("BSS transition request was not accepted: " + ev) 961 if "target_bssid=" + apdev[1]['bssid'] not in ev: 962 raise Exception("Unexpected target BSS: " + ev) 963 dev[0].wait_connected(timeout=15, error="No reassociation seen") 964 if apdev[1]['bssid'] not in ev: 965 raise Exception("Unexpected reassociation target: " + ev) 966 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 967 if ev is not None: 968 raise Exception("Unexpected scan started") 969 dev[0].dump_monitor() 970 971 logger.info("Preferred Candidate List with two matches, no roam needed") 972 if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 973 raise Exception("BSS_TM_REQ command failed") 974 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10) 975 if ev is None: 976 raise Exception("No BSS Transition Management Response") 977 if "status_code=0" not in ev: 978 raise Exception("BSS transition request was not accepted: " + ev) 979 if "target_bssid=" + apdev[1]['bssid'] not in ev: 980 raise Exception("Unexpected target BSS: " + ev) 981 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 982 if ev is not None: 983 raise Exception("Unexpected scan started") 984 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5) 985 if ev is not None: 986 raise Exception("Unexpected reassociation") 987 988 logger.info("Preferred Candidate List with two matches and extra frequency (160 MHz), no roam needed") 989 if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff" + ' neighbor=00:11:22:33:44:55,0x0000,129,36,7'): 990 raise Exception("BSS_TM_REQ command failed") 991 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10) 992 if ev is None: 993 raise Exception("No BSS Transition Management Response") 994 if "status_code=0" not in ev: 995 raise Exception("BSS transition request was not accepted: " + ev) 996 if "target_bssid=" + apdev[1]['bssid'] not in ev: 997 raise Exception("Unexpected target BSS: " + ev) 998 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 999 if ev is not None: 1000 raise Exception("Unexpected scan started") 1001 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5) 1002 if ev is not None: 1003 raise Exception("Unexpected reassociation") 1004 1005 dev[0].flush_scan_cache() 1006 logger.info("Candidate list is used even if not required by spec (pref=0, abridged=0)") 1007 if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " pref=0 abridged=0 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff" + ' neighbor=' + apdev[1]['bssid'] + ",0x0000,115,36,7,030100"): 1008 raise Exception("BSS_TM_REQ command failed") 1009 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10) 1010 if ev is None: 1011 raise Exception("No BSS Transition Management Response") 1012 if "status_code=0" not in ev: 1013 raise Exception("BSS transition request was not accepted: " + ev) 1014 if "target_bssid=" + apdev[0]['bssid'] not in ev: 1015 raise Exception("Unexpected target BSS: " + ev) 1016 # This scans only one frequency 1017 scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0) 1018 if scan_ev is None: 1019 raise Exception("Expected scan started") 1020 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1021 if apdev[0]['bssid'] not in ev: 1022 raise Exception("Unexpected reassociation target: " + ev) 1023 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 1024 if ev is not None: 1025 raise Exception("Unexpected scan started") 1026 1027 finally: 1028 clear_regdom_state(dev, hapd, hapd2) 1029 1030 def test_wnm_bss_tm_drv_processing(dev, apdev): 1031 """WNM BSS Transition Management - driver processing of candidates""" 1032 try: 1033 hapd = None 1034 hapd2 = None 1035 hapd = start_wnm_ap(apdev[0], country_code="FI") 1036 dev[0].flush_scan_cache() 1037 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1038 dev[0].set_network(id, "scan_freq", "") 1039 1040 hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a", 1041 channel="36") 1042 1043 addr = dev[0].own_addr() 1044 dev[0].dump_monitor() 1045 # The following two tests exercise the MBO target querying to the driver 1046 dev[0].flush_scan_cache() 1047 logger.info("BTM request with candidate list and all are valid, roams because MBO is enabled and the driver rejects current") 1048 with fail_test(dev[0], 1, "simulate;nl80211_get_bss_transition_status", 1049 1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status", 1050 # Second time post-scan 1051 1, "simulate;nl80211_get_bss_transition_status", 1052 1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status"): 1053 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 mbo=3:0:1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 1054 raise Exception("BSS_TM_REQ command failed") 1055 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1056 if ev is None: 1057 raise Exception("No BSS Transition Management Response") 1058 if "status_code=0" not in ev: 1059 raise Exception("BSS transition request was not accepted: " + ev) 1060 if "target_bssid=" + apdev[1]['bssid'] not in ev: 1061 raise Exception("Unexpected target BSS: " + ev) 1062 # This scans only one frequency 1063 scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1) 1064 if scan_ev is None: 1065 raise Exception("Expected scan not started") 1066 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1067 if apdev[1]['bssid'] not in ev: 1068 raise Exception("Unexpected reassociation target: " + ev) 1069 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 1070 if ev is not None: 1071 raise Exception("Unexpected scan started") 1072 1073 dev[0].flush_scan_cache() 1074 logger.info("BTM request with candidate list forcing other AP through disassoc imminent, the driver does MBO reject, but still roams") 1075 with fail_test(dev[0], 1, "simulate;nl80211_get_bss_transition_status", 1076 1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status", 1077 # And a second time post-scan 1078 1, "simulate;nl80211_get_bss_transition_status", 1079 1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status"): 1080 if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " disassoc_imminent=1 pref=1 abridged=1 mbo=3:5:1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff"): 1081 raise Exception("BSS_TM_REQ command failed") 1082 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10) 1083 if ev is None: 1084 raise Exception("No BSS Transition Management Response") 1085 if "status_code=0" not in ev: 1086 raise Exception("BSS transition request was not accepted: " + ev) 1087 if "target_bssid=" + apdev[0]['bssid'] not in ev: 1088 raise Exception("Unexpected target BSS: " + ev) 1089 # This scans only one frequency 1090 scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1) 1091 if scan_ev is None: 1092 raise Exception("Expected scan not started") 1093 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1094 if apdev[0]['bssid'] not in ev: 1095 raise Exception("Unexpected reassociation target: " + ev) 1096 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 1097 if ev is not None: 1098 raise Exception("Unexpected scan started") 1099 1100 finally: 1101 clear_regdom_state(dev, hapd, hapd2) 1102 1103 def test_wnm_bss_tm_steering_timeout(dev, apdev): 1104 """WNM BSS Transition Management and steering timeout""" 1105 hapd = start_wnm_ap(apdev[0]) 1106 dev[0].flush_scan_cache() 1107 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1108 hapd2 = start_wnm_ap(apdev[1]) 1109 dev[0].scan_for_bss(apdev[1]['bssid'], 2412) 1110 hapd2.disable() 1111 addr = dev[0].own_addr() 1112 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,81,1,7,0301ff"): 1113 raise Exception("BSS_TM_REQ command failed") 1114 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=5) 1115 if ev is None: 1116 raise Exception("No BSS Transition Management Response") 1117 if "status_code=0" not in ev: 1118 raise Exception("BSS transition request was not accepted: " + ev) 1119 # Wait for the ap_sta_reset_steer_flag_timer timeout to occur 1120 # "Reset steering flag for STA 02:00:00:00:00:00" 1121 time.sleep(2.1) 1122 1123 ev = dev[0].wait_event(["Trying to authenticate"], timeout=5) 1124 if ev is None: 1125 raise Exception("No authentication attempt seen") 1126 if hapd2.own_addr() not in ev: 1127 raise Exception("Unexpected authentication target: " + ev) 1128 # Wait for return back to the previous AP 1129 dev[0].wait_connected() 1130 1131 def test_wnm_bss_tm_errors(dev, apdev): 1132 """WNM BSS Transition Management errors""" 1133 hapd = start_wnm_ap(apdev[0]) 1134 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1135 addr = dev[0].own_addr() 1136 1137 tests = ["BSS_TM_REQ q", 1138 "BSS_TM_REQ 22:22:22:22:22:22", 1139 "BSS_TM_REQ %s disassoc_timer=-1" % addr, 1140 "BSS_TM_REQ %s disassoc_timer=65536" % addr, 1141 "BSS_TM_REQ %s bss_term=foo" % addr, 1142 "BSS_TM_REQ %s neighbor=q" % addr, 1143 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55" % addr, 1144 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0" % addr, 1145 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0" % addr, 1146 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0" % addr, 1147 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,q" % addr, 1148 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,0q" % addr, 1149 "BSS_TM_REQ " + addr + " url=" + 256*'a', 1150 "BSS_TM_REQ %s url=foo mbo=1:2" % addr, 1151 "BSS_TM_REQ %s url=foo mbo=100000:0:0" % addr, 1152 "BSS_TM_REQ %s url=foo mbo=0:0:254" % addr, 1153 "BSS_TM_REQ %s url=foo mbo=0:100000:0" % addr] 1154 for t in tests: 1155 if "FAIL" not in hapd.request(t): 1156 raise Exception("Invalid command accepted: %s" % t) 1157 1158 with alloc_fail(hapd, 1, "=hostapd_ctrl_iface_bss_tm_req"): 1159 if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr): 1160 raise Exception("BSS_TM_REQ accepted during OOM") 1161 1162 with alloc_fail(hapd, 1, "=wnm_send_bss_tm_req"): 1163 if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr): 1164 raise Exception("BSS_TM_REQ accepted during OOM") 1165 1166 with fail_test(hapd, 1, "wnm_send_bss_tm_req"): 1167 if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr): 1168 raise Exception("BSS_TM_REQ accepted during failure testing") 1169 1170 def test_wnm_bss_tm_termination(dev, apdev): 1171 """WNM BSS Transition Management and BSS termination""" 1172 hapd = start_wnm_ap(apdev[0]) 1173 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1174 addr = dev[0].own_addr() 1175 1176 if "OK" not in hapd.request("BSS_TM_REQ %s bss_term=0,1" % addr): 1177 raise Exception("BSS_TM_REQ failed") 1178 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5) 1179 if ev is None: 1180 raise Exception("No BSS-TM-RESP event seen") 1181 1182 if "OK" not in hapd.request("BSS_TM_REQ %s url=http://example.com/" % addr): 1183 raise Exception("BSS_TM_REQ failed") 1184 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5) 1185 if ev is None: 1186 raise Exception("No BSS-TM-RESP event seen") 1187 1188 def test_wnm_bss_tm_scan_not_needed(dev, apdev): 1189 """WNM BSS Transition Management and scan not needed""" 1190 run_wnm_bss_tm_scan_not_needed(dev, apdev) 1191 1192 def test_wnm_bss_tm_nei_vht(dev, apdev): 1193 """WNM BSS Transition Management and VHT neighbor""" 1194 run_wnm_bss_tm_scan_not_needed(dev, apdev, vht=True, nei_info="115,36,9") 1195 1196 def test_wnm_bss_tm_nei_11a(dev, apdev): 1197 """WNM BSS Transition Management and 11a neighbor""" 1198 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, nei_info="115,36,4") 1199 1200 def test_wnm_bss_tm_nei_11g(dev, apdev): 1201 """WNM BSS Transition Management and 11g neighbor""" 1202 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='g', 1203 channel='2', freq=2417, nei_info="81,2,6") 1204 1205 def test_wnm_bss_tm_nei_11b(dev, apdev): 1206 """WNM BSS Transition Management and 11g neighbor""" 1207 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='b', 1208 channel='3', freq=2422, nei_info="81,2,5") 1209 1210 def run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=True, vht=False, hwmode='a', 1211 channel='36', freq=5180, 1212 nei_info="115,36,7,0301ff"): 1213 try: 1214 hapd = None 1215 hapd2 = None 1216 hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g", 1217 channel="1") 1218 hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode=hwmode, 1219 channel=channel, ht=ht, vht=vht) 1220 dev[0].scan_for_bss(apdev[1]['bssid'], freq) 1221 1222 id = dev[0].connect("test-wnm", key_mgmt="NONE", 1223 bssid=apdev[0]['bssid'], scan_freq="2412") 1224 dev[0].set_network(id, "scan_freq", "") 1225 dev[0].set_network(id, "bssid", "") 1226 1227 addr = dev[0].own_addr() 1228 dev[0].dump_monitor() 1229 1230 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 1231 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + nei_info): 1232 raise Exception("BSS_TM_REQ command failed") 1233 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1234 if ev is None: 1235 raise Exception("No BSS Transition Management Response") 1236 if "status_code=0" not in ev: 1237 raise Exception("BSS transition request was not accepted: " + ev) 1238 if "target_bssid=" + apdev[1]['bssid'] not in ev: 1239 raise Exception("Unexpected target BSS: " + ev) 1240 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1241 if apdev[1]['bssid'] not in ev: 1242 raise Exception("Unexpected reassociation target: " + ev) 1243 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 1244 if ev is not None: 1245 raise Exception("Unexpected scan started") 1246 dev[0].dump_monitor() 1247 finally: 1248 clear_regdom_state(dev, hapd, hapd2) 1249 1250 def test_wnm_bss_tm_scan_needed(dev, apdev): 1251 """WNM BSS Transition Management and scan needed""" 1252 try: 1253 hapd = None 1254 hapd2 = None 1255 hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g", 1256 channel="1") 1257 hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a", 1258 channel="36") 1259 1260 dev[0].flush_scan_cache() 1261 dev[0].scan_for_bss(apdev[1]['bssid'], 5180) 1262 1263 id = dev[0].connect("test-wnm", key_mgmt="NONE", 1264 bssid=apdev[0]['bssid'], scan_freq="2412") 1265 dev[0].set_network(id, "scan_freq", "") 1266 dev[0].set_network(id, "bssid", "") 1267 1268 addr = dev[0].own_addr() 1269 dev[0].dump_monitor() 1270 1271 logger.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table") 1272 time.sleep(11) 1273 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 1274 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 1275 raise Exception("BSS_TM_REQ command failed") 1276 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1277 if ev is None: 1278 raise Exception("No BSS Transition Management Response") 1279 if "status_code=0" not in ev: 1280 raise Exception("BSS transition request was not accepted: " + ev) 1281 if "target_bssid=" + apdev[1]['bssid'] not in ev: 1282 raise Exception("Unexpected target BSS: " + ev) 1283 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1284 if apdev[1]['bssid'] not in ev: 1285 raise Exception("Unexpected reassociation target: " + ev) 1286 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1) 1287 if ev is not None: 1288 raise Exception("Unexpected scan started") 1289 dev[0].dump_monitor() 1290 finally: 1291 clear_regdom_state(dev, hapd, hapd2) 1292 1293 def test_wnm_bss_tm_scan_needed_e4(dev, apdev): 1294 """WNM BSS Transition Management and scan needed (Table E-4)""" 1295 try: 1296 hapd = None 1297 hapd2 = None 1298 hapd = start_wnm_ap(apdev[0], country_code="FI", country3="0x04", 1299 hw_mode="g", channel="1") 1300 hapd2 = start_wnm_ap(apdev[1], country_code="FI", country3="0x04", 1301 hw_mode="a", channel="36") 1302 dev[0].flush_scan_cache() 1303 id = dev[0].connect("test-wnm", key_mgmt="NONE", 1304 bssid=apdev[0]['bssid'], scan_freq="2412") 1305 dev[0].set_network(id, "scan_freq", "") 1306 dev[0].set_network(id, "bssid", "") 1307 1308 addr = dev[0].own_addr() 1309 dev[0].dump_monitor() 1310 1311 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 1312 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 1313 raise Exception("BSS_TM_REQ command failed") 1314 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=4) 1315 if ev is None: 1316 raise Exception("No BSS Transition Management Response seen quickly enough - did scan optimization fail?") 1317 if "status_code=0" not in ev: 1318 raise Exception("BSS transition request was not accepted: " + ev) 1319 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1320 # Wait for regdom change due to country IE to avoid issues with that 1321 # processing happening only after the disconnection and cfg80211 ending 1322 # up intersecting regdoms when we try to clear state back to world (00) 1323 # regdom below. 1324 while True: 1325 ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 1326 if not ev or "COUNTRY_IE" in ev: 1327 break 1328 dev[0].dump_monitor() 1329 finally: 1330 clear_regdom_state(dev, hapd, hapd2) 1331 1332 def start_wnm_tm(ap, country, dev, country3=None): 1333 hapd = start_wnm_ap(ap, country_code=country, country3=country3) 1334 id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1335 wait_regdom_changes(dev) 1336 dev.dump_monitor() 1337 dev.set_network(id, "scan_freq", "") 1338 return hapd, id 1339 1340 def stop_wnm_tm(hapd, dev): 1341 if hapd: 1342 hapd.request("DISABLE") 1343 time.sleep(0.1) 1344 dev[0].disconnect_and_stop_scan() 1345 subprocess.call(['iw', 'reg', 'set', '00']) 1346 wait_regdom_changes(dev[0]) 1347 country = dev[0].get_driver_status_field("country") 1348 logger.info("Country code at the end: " + country) 1349 if country != "00": 1350 clear_country(dev) 1351 1352 dev[0].flush_scan_cache() 1353 1354 def wnm_bss_tm_check(hapd, dev, data): 1355 addr = dev.p2p_interface_addr() 1356 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " " + data): 1357 raise Exception("BSS_TM_REQ command failed") 1358 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5) 1359 if ev is None: 1360 raise Exception("No scan started") 1361 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15) 1362 if ev is None: 1363 raise Exception("Scan did not complete") 1364 1365 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1366 if ev is None: 1367 raise Exception("No BSS Transition Management Response") 1368 if "status_code=7" not in ev: 1369 raise Exception("Unexpected response: " + ev) 1370 1371 def test_wnm_bss_tm_country_us(dev, apdev): 1372 """WNM BSS Transition Management (US)""" 1373 try: 1374 hapd = None 1375 hapd, id = start_wnm_tm(apdev[0], "US", dev[0]) 1376 1377 logger.info("Preferred Candidate List (no matching neighbor, known channels)") 1378 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,12,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,2,52,7,03010a neighbor=00:11:22:33:44:57,0x0000,4,100,7 neighbor=00:11:22:33:44:59,0x0000,3,149,7 neighbor=00:11:22:33:44:5b,0x0000,34,1,7 neighbor=00:11:22:33:44:5d,0x0000,5,149,7") 1379 1380 # Make the test take less time by limiting full scans 1381 dev[0].set_network(id, "scan_freq", "2412") 1382 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)") 1383 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,12,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,12,12,7 neighbor=00:11:22:33:44:55,0x0000,2,35,7,03010a neighbor=00:11:22:33:44:56,0x0000,2,65,7 neighbor=00:11:22:33:44:57,0x0000,4,99,7 neighbor=00:11:22:33:44:58,0x0000,4,145,7") 1384 1385 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)") 1386 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:59,0x0000,3,148,7 neighbor=00:11:22:33:44:5a,0x0000,3,162,7 neighbor=00:11:22:33:44:5b,0x0000,34,0,7 neighbor=00:11:22:33:44:5c,0x0000,34,4,7 neighbor=00:11:22:33:44:5d,0x0000,5,148,7 neighbor=00:11:22:33:44:5e,0x0000,5,166,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7") 1387 finally: 1388 stop_wnm_tm(hapd, dev) 1389 1390 def test_wnm_bss_tm_country_fi(dev, apdev): 1391 """WNM BSS Transition Management (FI)""" 1392 addr = dev[0].p2p_interface_addr() 1393 try: 1394 hapd = None 1395 hapd, id = start_wnm_tm(apdev[0], "FI", dev[0]) 1396 1397 logger.info("Preferred Candidate List (no matching neighbor, known channels)") 1398 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,4,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,1,36,7,03010a neighbor=00:11:22:33:44:57,0x0000,3,100,7 neighbor=00:11:22:33:44:59,0x0000,17,149,7 neighbor=00:11:22:33:44:5c,0x0000,18,1,7") 1399 1400 # Make the test take less time by limiting full scans 1401 dev[0].set_network(id, "scan_freq", "2412") 1402 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)") 1403 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:00,0x0000,4,0,7 neighbor=00:11:22:33:44:01,0x0000,4,14,7 neighbor=00:11:22:33:44:02,0x0000,1,35,7 neighbor=00:11:22:33:44:03,0x0000,1,65,7 neighbor=00:11:22:33:44:04,0x0000,3,99,7 neighbor=00:11:22:33:44:05,0x0000,3,141,7 neighbor=00:11:22:33:44:06,0x0000,17,148,7 neighbor=00:11:22:33:44:07,0x0000,17,170,7 neighbor=00:11:22:33:44:08,0x0000,18,0,7 neighbor=00:11:22:33:44:09,0x0000,18,5,7") 1404 1405 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)") 1406 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7") 1407 finally: 1408 stop_wnm_tm(hapd, dev) 1409 1410 def test_wnm_bss_tm_country_jp(dev, apdev): 1411 """WNM BSS Transition Management (JP)""" 1412 addr = dev[0].p2p_interface_addr() 1413 try: 1414 hapd = None 1415 hapd, id = start_wnm_tm(apdev[0], "JP", dev[0]) 1416 1417 logger.info("Preferred Candidate List (no matching neighbor, known channels)") 1418 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,30,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,31,14,7,03010a neighbor=00:11:22:33:44:57,0x0000,1,36,7 neighbor=00:11:22:33:44:59,0x0000,34,100,7 neighbor=00:11:22:33:44:5c,0x0000,59,1,7") 1419 1420 # Make the test take less time by limiting full scans 1421 dev[0].set_network(id, "scan_freq", "2412") 1422 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)") 1423 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,30,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,30,14,7 neighbor=00:11:22:33:44:56,0x0000,31,13,7 neighbor=00:11:22:33:44:57,0x0000,1,33,7 neighbor=00:11:22:33:44:58,0x0000,1,65,7 neighbor=00:11:22:33:44:5a,0x0000,34,99,7 neighbor=00:11:22:33:44:5b,0x0000,34,141,7 neighbor=00:11:22:33:44:5d,0x0000,59,0,7 neighbor=00:11:22:33:44:5e,0x0000,59,4,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7") 1424 finally: 1425 stop_wnm_tm(hapd, dev) 1426 1427 def test_wnm_bss_tm_country_cn(dev, apdev): 1428 """WNM BSS Transition Management (CN)""" 1429 addr = dev[0].p2p_interface_addr() 1430 try: 1431 hapd = None 1432 hapd, id = start_wnm_tm(apdev[0], "CN", dev[0]) 1433 1434 logger.info("Preferred Candidate List (no matching neighbor, known channels)") 1435 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,7,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,1,36,7,03010a neighbor=00:11:22:33:44:57,0x0000,3,149,7 neighbor=00:11:22:33:44:59,0x0000,6,149,7") 1436 1437 # Make the test take less time by limiting full scans 1438 dev[0].set_network(id, "scan_freq", "2412") 1439 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)") 1440 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,7,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,7,14,7 neighbor=00:11:22:33:44:56,0x0000,1,35,7 neighbor=00:11:22:33:44:57,0x0000,1,65,7 neighbor=00:11:22:33:44:58,0x0000,3,148,7 neighbor=00:11:22:33:44:5a,0x0000,3,166,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7") 1441 finally: 1442 stop_wnm_tm(hapd, dev) 1443 1444 def test_wnm_bss_tm_global(dev, apdev): 1445 """WNM BSS Transition Management (global)""" 1446 run_wnm_bss_tm_global(dev, apdev, "XX", None) 1447 1448 def test_wnm_bss_tm_global4(dev, apdev): 1449 """WNM BSS Transition Management (global; indicate table E-4)""" 1450 run_wnm_bss_tm_global(dev, apdev, "FI", "0x04") 1451 1452 def run_wnm_bss_tm_global(dev, apdev, country, country3): 1453 addr = dev[0].p2p_interface_addr() 1454 try: 1455 hapd = None 1456 hapd, id = start_wnm_tm(apdev[0], country, dev[0], country3=country3) 1457 1458 logger.info("Preferred Candidate List (no matching neighbor, known channels)") 1459 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,82,14,7,03010a neighbor=00:11:22:33:44:57,0x0000,83,1,7 neighbor=00:11:22:33:44:59,0x0000,115,36,7 neighbor=00:11:22:33:44:5a,0x0000,121,100,7 neighbor=00:11:22:33:44:5c,0x0000,124,149,7 neighbor=00:11:22:33:44:5d,0x0000,125,149,7 neighbor=00:11:22:33:44:5e,0x0000,128,42,7 neighbor=00:11:22:33:44:5f,0x0000,129,50,7 neighbor=00:11:22:33:44:60,0x0000,180,1,7") 1460 1461 # Make the test take less time by limiting full scans 1462 dev[0].set_network(id, "scan_freq", "2412") 1463 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)") 1464 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:00,0x0000,81,0,7 neighbor=00:11:22:33:44:01,0x0000,81,14,7 neighbor=00:11:22:33:44:02,0x0000,82,13,7 neighbor=00:11:22:33:44:03,0x0000,83,0,7 neighbor=00:11:22:33:44:04,0x0000,83,14,7 neighbor=00:11:22:33:44:05,0x0000,115,35,7 neighbor=00:11:22:33:44:06,0x0000,115,65,7 neighbor=00:11:22:33:44:07,0x0000,121,99,7 neighbor=00:11:22:33:44:08,0x0000,121,141,7 neighbor=00:11:22:33:44:09,0x0000,124,148,7") 1465 1466 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)") 1467 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:00,0x0000,124,162,7 neighbor=00:11:22:33:44:01,0x0000,125,148,7 neighbor=00:11:22:33:44:02,0x0000,125,170,7 neighbor=00:11:22:33:44:03,0x0000,128,35,7 neighbor=00:11:22:33:44:04,0x0000,128,162,7 neighbor=00:11:22:33:44:05,0x0000,129,49,7 neighbor=00:11:22:33:44:06,0x0000,129,115,7 neighbor=00:11:22:33:44:07,0x0000,180,0,7 neighbor=00:11:22:33:44:08,0x0000,180,5,7 neighbor=00:11:22:33:44:09,0x0000,0,0,7") 1468 finally: 1469 stop_wnm_tm(hapd, dev) 1470 1471 def test_wnm_bss_tm_op_class_0(dev, apdev): 1472 """WNM BSS Transition Management with invalid operating class""" 1473 try: 1474 hapd = None 1475 hapd, id = start_wnm_tm(apdev[0], "US", dev[0]) 1476 1477 logger.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)") 1478 wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:59,0x0000,0,149,7 neighbor=00:11:22:33:44:5b,0x0000,0,1,7") 1479 finally: 1480 stop_wnm_tm(hapd, dev) 1481 1482 def test_wnm_bss_tm_rsn(dev, apdev): 1483 """WNM BSS Transition Management with RSN""" 1484 passphrase = "zxcvbnm,.-" 1485 try: 1486 hapd = None 1487 hapd2 = None 1488 hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g", 1489 channel="1", 1490 rsn=True, pmf=False, passphrase=passphrase) 1491 hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a", 1492 channel="36", 1493 rsn=True, pmf=False, passphrase=passphrase) 1494 dev[0].scan_for_bss(apdev[1]['bssid'], 5180) 1495 1496 id = dev[0].connect("test-wnm-rsn", psk=passphrase, 1497 bssid=apdev[0]['bssid'], scan_freq="2412") 1498 dev[0].set_network(id, "scan_freq", "") 1499 dev[0].set_network(id, "bssid", "") 1500 1501 addr = dev[0].own_addr() 1502 dev[0].dump_monitor() 1503 1504 time.sleep(0.5) 1505 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 1506 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + "115,36,7,0301ff"): 1507 raise Exception("BSS_TM_REQ command failed") 1508 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1509 if ev is None: 1510 raise Exception("No BSS Transition Management Response") 1511 if "status_code=0" not in ev: 1512 raise Exception("BSS transition request was not accepted: " + ev) 1513 if "target_bssid=" + apdev[1]['bssid'] not in ev: 1514 raise Exception("Unexpected target BSS: " + ev) 1515 dev[0].wait_connected(timeout=15, error="No reassociation seen") 1516 if apdev[1]['bssid'] not in ev: 1517 raise Exception("Unexpected reassociation target: " + ev) 1518 finally: 1519 clear_regdom_state(dev, hapd, hapd2) 1520 1521 def test_wnm_action_proto(dev, apdev): 1522 """WNM Action protocol testing""" 1523 hapd = start_wnm_ap(apdev[0], bss_transition=False, wnm_sleep_mode=True) 1524 bssid = apdev[0]['bssid'] 1525 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1526 dev[0].request("WNM_SLEEP enter") 1527 time.sleep(0.1) 1528 hapd.set("ext_mgmt_frame_handling", "1") 1529 1530 msg = {} 1531 msg['fc'] = MGMT_SUBTYPE_ACTION << 4 1532 msg['da'] = dev[0].own_addr() 1533 msg['sa'] = bssid 1534 msg['bssid'] = bssid 1535 1536 dialog_token = 1 1537 1538 logger.debug("Unexpected WNM-Notification Response") 1539 # Note: This is actually not registered for user space processing in 1540 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make 1541 # it to wpa_supplicant. 1542 msg['payload'] = struct.pack("<BBBB", 1543 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_RESP, 1544 dialog_token, 0) 1545 hapd.mgmt_tx(msg) 1546 expect_ack(hapd) 1547 1548 logger.debug("Truncated WNM-Notification Request (no Type field)") 1549 msg['payload'] = struct.pack("<BBB", 1550 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1551 dialog_token) 1552 hapd.mgmt_tx(msg) 1553 expect_ack(hapd) 1554 1555 logger.debug("WFA WNM-Notification Request with truncated IE (min)") 1556 msg['payload'] = struct.pack("<BBBBBB", 1557 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1558 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 1) 1559 hapd.mgmt_tx(msg) 1560 expect_ack(hapd) 1561 1562 logger.debug("WFA WNM-Notification Request with truncated IE (max)") 1563 msg['payload'] = struct.pack("<BBBBBB", 1564 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1565 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 255) 1566 hapd.mgmt_tx(msg) 1567 expect_ack(hapd) 1568 1569 logger.debug("WFA WNM-Notification Request with too short IE") 1570 msg['payload'] = struct.pack("<BBBBBB", 1571 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1572 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 0) 1573 hapd.mgmt_tx(msg) 1574 expect_ack(hapd) 1575 1576 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL") 1577 msg['payload'] = struct.pack(">BBBBBBLB", 1578 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1579 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5, 1580 0x506f9a00, 1) 1581 hapd.mgmt_tx(msg) 1582 expect_ack(hapd) 1583 1584 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)") 1585 msg['payload'] = struct.pack(">BBBBBBLBB", 1586 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1587 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 6, 1588 0x506f9a00, 1, 0) 1589 hapd.mgmt_tx(msg) 1590 expect_ack(hapd) 1591 1592 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)") 1593 msg['payload'] = struct.pack(">BBBBBBLB", 1594 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1595 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5, 1596 0x506f9a00, 0xff) 1597 hapd.mgmt_tx(msg) 1598 expect_ack(hapd) 1599 1600 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)") 1601 msg['payload'] = struct.pack(">BBBBBBLBHB", 1602 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1603 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8, 1604 0x506f9a01, 0, 0, 1) 1605 hapd.mgmt_tx(msg) 1606 expect_ack(hapd) 1607 1608 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)") 1609 msg['payload'] = struct.pack(">BBBBBBLBHB", 1610 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1611 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8, 1612 0x506f9a01, 0, 0, 0xff) 1613 hapd.mgmt_tx(msg) 1614 expect_ack(hapd) 1615 1616 logger.debug("WFA WNM-Notification Request with unsupported IE") 1617 msg['payload'] = struct.pack("<BBBBBBL", 1618 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1619 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 4, 0) 1620 hapd.mgmt_tx(msg) 1621 expect_ack(hapd) 1622 1623 logger.debug("WNM-Notification Request with unknown WNM-Notification type 0") 1624 msg['payload'] = struct.pack("<BBBB", 1625 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ, 1626 dialog_token, WNM_NOTIF_TYPE_FW_UPGRADE) 1627 hapd.mgmt_tx(msg) 1628 expect_ack(hapd) 1629 1630 logger.debug("Truncated WNM Sleep Mode Response - no Dialog Token") 1631 msg['payload'] = struct.pack("<BB", 1632 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP) 1633 hapd.mgmt_tx(msg) 1634 expect_ack(hapd) 1635 1636 logger.debug("Truncated WNM Sleep Mode Response - no Key Data Length") 1637 msg['payload'] = struct.pack("<BBB", 1638 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0) 1639 hapd.mgmt_tx(msg) 1640 expect_ack(hapd) 1641 1642 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)") 1643 msg['payload'] = struct.pack("<BBBH", 1644 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1645 1) 1646 hapd.mgmt_tx(msg) 1647 expect_ack(hapd) 1648 1649 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)") 1650 msg['payload'] = struct.pack("<BBBH", 1651 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1652 0xffff) 1653 hapd.mgmt_tx(msg) 1654 expect_ack(hapd) 1655 1656 logger.debug("WNM Sleep Mode Response - truncated IE header") 1657 msg['payload'] = struct.pack("<BBBHB", 1658 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1659 0, 0) 1660 hapd.mgmt_tx(msg) 1661 expect_ack(hapd) 1662 1663 logger.debug("WNM Sleep Mode Response - truncated IE") 1664 msg['payload'] = struct.pack("<BBBHBB", 1665 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1666 0, 0, 1) 1667 hapd.mgmt_tx(msg) 1668 expect_ack(hapd) 1669 1670 logger.debug("WNM Sleep Mode Response - Empty TFS Response") 1671 msg['payload'] = struct.pack("<BBBHBB", 1672 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1673 0, WLAN_EID_TFS_RESP, 0) 1674 hapd.mgmt_tx(msg) 1675 expect_ack(hapd) 1676 1677 logger.debug("WNM Sleep Mode Response - EID 0 not recognized") 1678 msg['payload'] = struct.pack("<BBBHBB", 1679 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1680 0, 0, 0) 1681 hapd.mgmt_tx(msg) 1682 expect_ack(hapd) 1683 1684 logger.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element") 1685 msg['payload'] = struct.pack("<BBBHBBBB", 1686 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1687 0, WLAN_EID_WNMSLEEP, 0, WLAN_EID_TFS_RESP, 0) 1688 hapd.mgmt_tx(msg) 1689 expect_ack(hapd) 1690 1691 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element") 1692 msg['payload'] = struct.pack("<BBBHBBBBHBB", 1693 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1694 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER, 1695 WNM_STATUS_SLEEP_ACCEPT, 0, 1696 WLAN_EID_TFS_RESP, 0) 1697 hapd.mgmt_tx(msg) 1698 expect_ack(hapd) 1699 1700 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element") 1701 msg['payload'] = struct.pack("<BBBHBBBBHBB", 1702 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1703 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1704 WNM_STATUS_DENIED_KEY, 0, 1705 WLAN_EID_TFS_RESP, 0) 1706 hapd.mgmt_tx(msg) 1707 expect_ack(hapd) 1708 1709 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element") 1710 msg['payload'] = struct.pack("<BBBHBBBBHBB", 1711 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1712 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER, 1713 WNM_STATUS_DENIED_KEY, 0, 1714 WLAN_EID_TFS_RESP, 0) 1715 hapd.mgmt_tx(msg) 1716 expect_ack(hapd) 1717 1718 @remote_compatible 1719 def test_wnm_action_proto_pmf(dev, apdev): 1720 """WNM Action protocol testing (PMF enabled)""" 1721 ssid = "test-wnm-pmf" 1722 hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ssid=ssid) 1723 bssid = apdev[0]['bssid'] 1724 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", 1725 proto="WPA2", ieee80211w="2", scan_freq="2412") 1726 dev[0].request("WNM_SLEEP enter") 1727 time.sleep(0.1) 1728 hapd.set("ext_mgmt_frame_handling", "1") 1729 1730 msg = {} 1731 msg['fc'] = MGMT_SUBTYPE_ACTION << 4 1732 msg['da'] = dev[0].own_addr() 1733 msg['sa'] = bssid 1734 msg['bssid'] = bssid 1735 1736 logger.debug("WNM Sleep Mode Response - Invalid Key Data element length") 1737 keydata = struct.pack("<BB", 0, 1) 1738 msg['payload'] = struct.pack("<BBBH", 1739 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1740 len(keydata)) 1741 msg['payload'] += keydata 1742 msg['payload'] += struct.pack("<BBBBHBB", 1743 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1744 WNM_STATUS_SLEEP_ACCEPT, 0, 1745 WLAN_EID_TFS_RESP, 0) 1746 hapd.mgmt_tx(msg) 1747 expect_ack(hapd) 1748 1749 logger.debug("WNM Sleep Mode Response - Too short GTK subelem") 1750 keydata = struct.pack("<BB", WNM_SLEEP_SUBELEM_GTK, 0) 1751 msg['payload'] = struct.pack("<BBBH", 1752 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1753 len(keydata)) 1754 msg['payload'] += keydata 1755 msg['payload'] += struct.pack("<BBBBHBB", 1756 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1757 WNM_STATUS_SLEEP_ACCEPT, 0, 1758 WLAN_EID_TFS_RESP, 0) 1759 hapd.mgmt_tx(msg) 1760 expect_ack(hapd) 1761 1762 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem") 1763 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 1764 0, 17, 0, 0, 0, 0, 0, 0) 1765 msg['payload'] = struct.pack("<BBBH", 1766 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1767 len(keydata)) 1768 msg['payload'] += keydata 1769 msg['payload'] += struct.pack("<BBBBHBB", 1770 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1771 WNM_STATUS_SLEEP_ACCEPT, 0, 1772 WLAN_EID_TFS_RESP, 0) 1773 hapd.mgmt_tx(msg) 1774 expect_ack(hapd) 1775 1776 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)") 1777 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 1778 0, 0, 0, 0, 0, 0, 0, 0) 1779 msg['payload'] = struct.pack("<BBBH", 1780 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1781 len(keydata)) 1782 msg['payload'] += keydata 1783 msg['payload'] += struct.pack("<BBBBHBB", 1784 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1785 WNM_STATUS_SLEEP_ACCEPT, 0, 1786 WLAN_EID_TFS_RESP, 0) 1787 hapd.mgmt_tx(msg) 1788 expect_ack(hapd) 1789 1790 logger.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem") 1791 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16) 1792 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708, 1793 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff) 1794 keydata += struct.pack("<BB", WNM_SLEEP_SUBELEM_IGTK, 0) 1795 msg['payload'] = struct.pack("<BBBH", 1796 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1797 len(keydata)) 1798 msg['payload'] += keydata 1799 msg['payload'] += struct.pack("<BBBBHBB", 1800 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1801 WNM_STATUS_SLEEP_ACCEPT, 0, 1802 WLAN_EID_TFS_RESP, 0) 1803 hapd.mgmt_tx(msg) 1804 expect_ack(hapd) 1805 1806 logger.debug("WNM Sleep Mode Response - Unknown subelem") 1807 keydata = struct.pack("<BB", 255, 0) 1808 msg['payload'] = struct.pack("<BBBH", 1809 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1810 len(keydata)) 1811 msg['payload'] += keydata 1812 msg['payload'] += struct.pack("<BBBBHBB", 1813 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1814 WNM_STATUS_SLEEP_ACCEPT, 0, 1815 WLAN_EID_TFS_RESP, 0) 1816 hapd.mgmt_tx(msg) 1817 expect_ack(hapd) 1818 1819 @remote_compatible 1820 def test_wnm_action_proto_no_pmf(dev, apdev): 1821 """WNM Action protocol testing (PMF disabled)""" 1822 ssid = "test-wnm-no-pmf" 1823 hapd = start_wnm_ap(apdev[0], rsn=True, pmf=False, bss_transition=False, 1824 wnm_sleep_mode=True, ssid=ssid) 1825 bssid = apdev[0]['bssid'] 1826 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK", 1827 proto="WPA2", ieee80211w="0", scan_freq="2412") 1828 dev[0].request("WNM_SLEEP enter") 1829 time.sleep(0.1) 1830 hapd.set("ext_mgmt_frame_handling", "1") 1831 hapd.dump_monitor() 1832 dev[0].request("WNM_SLEEP exit") 1833 ev = hapd.wait_event(['MGMT-RX'], timeout=5) 1834 if ev is None: 1835 raise Exception("WNM-Sleep Mode Request not seen") 1836 1837 msg = {} 1838 msg['fc'] = MGMT_SUBTYPE_ACTION << 4 1839 msg['da'] = dev[0].own_addr() 1840 msg['sa'] = bssid 1841 msg['bssid'] = bssid 1842 1843 logger.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem") 1844 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16) 1845 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708, 1846 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff) 1847 keydata += struct.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK, 2 + 6 + 16, 0, 1848 0x10203040, 0x5060, 1849 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff) 1850 msg['payload'] = struct.pack("<BBBH", 1851 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0, 1852 len(keydata)) 1853 msg['payload'] += keydata 1854 msg['payload'] += struct.pack("<BBBBHBB", 1855 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 1856 WNM_STATUS_SLEEP_ACCEPT, 0, 1857 WLAN_EID_TFS_RESP, 0) 1858 hapd.mgmt_tx(msg) 1859 expect_ack(hapd) 1860 1861 ev = dev[0].wait_event(["WNM: Ignore Key Data"], timeout=5) 1862 if ev is None: 1863 raise Exception("Key Data not ignored") 1864 1865 def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev): 1866 """WNM BSS transition request with MBO IE and reassociation delay attribute""" 1867 ssid = "test-wnm-mbo" 1868 hapd = start_wnm_ap(apdev[0], rsn=True, pmf=False, ssid=ssid) 1869 bssid = apdev[0]['bssid'] 1870 if "OK" not in dev[0].request("SET mbo_cell_capa 1"): 1871 raise Exception("Failed to set STA as cellular data capable") 1872 1873 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK", 1874 proto="WPA2", ieee80211w="0", scan_freq="2412") 1875 1876 logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set") 1877 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"): 1878 raise Exception("BSS transition management succeeded unexpectedly") 1879 1880 logger.debug("BTM request with invalid MBO transition reason code") 1881 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"): 1882 raise Exception("BSS transition management succeeded unexpectedly") 1883 1884 logger.debug("BTM request with MBO reassociation retry delay of 5 seconds") 1885 if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"): 1886 raise Exception("BSS transition management command failed") 1887 1888 ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1) 1889 if ev is None or "preference=1" not in ev: 1890 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event") 1891 1892 ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1) 1893 if ev is None or "reason=3" not in ev: 1894 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event") 1895 1896 t0 = datetime.now() 1897 1898 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1899 if ev is None: 1900 raise Exception("No BSS Transition Management Response") 1901 if dev[0].own_addr() not in ev: 1902 raise Exception("Unexpected BSS Transition Management Response address") 1903 1904 ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5) 1905 if ev is None: 1906 raise Exception("Station did not disconnect although disassoc imminent was set") 1907 1908 # Set the scan interval to make dev[0] look for connections 1909 if 'OK' not in dev[0].request("SCAN_INTERVAL 1"): 1910 raise Exception("Failed to set scan interval") 1911 1912 # Wait until connected 1913 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 10) 1914 if ev is None: 1915 raise Exception("Station did not connect") 1916 1917 # Make sure no connection is made during the retry delay 1918 time_diff = datetime.now() - t0 1919 if time_diff.total_seconds() < 5: 1920 raise Exception("Station connected before assoc retry delay was over") 1921 1922 if "OK" not in dev[0].request("SET mbo_cell_capa 3"): 1923 raise Exception("Failed to set STA as cellular data not-capable") 1924 1925 @remote_compatible 1926 def test_wnm_bss_transition_mgmt_query(dev, apdev): 1927 """WNM BSS Transition Management query""" 1928 hapd = start_wnm_ap(apdev[0]) 1929 params = {"ssid": "another"} 1930 hapd2 = hostapd.add_ap(apdev[1], params) 1931 1932 dev[0].scan_for_bss(apdev[1]['bssid'], 2412) 1933 dev[0].scan_for_bss(apdev[0]['bssid'], 2412) 1934 1935 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1936 dev[0].request("WNM_BSS_QUERY 0 list") 1937 1938 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"], 1939 timeout=5) 1940 if ev is None: 1941 raise Exception("No BSS Transition Management Request frame seen") 1942 1943 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5) 1944 if ev is None: 1945 raise Exception("No BSS Transition Management Response frame seen") 1946 1947 def test_wnm_bss_transition_mgmt_query_disabled_on_ap(dev, apdev): 1948 """WNM BSS Transition Management query - TM disabled on AP""" 1949 hapd = start_wnm_ap(apdev[0], bss_transition=False) 1950 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1951 # Ignore BSS Transition Management Query from 02:00:00:00:00:00 since BSS Transition Management is disabled 1952 dev[0].request("WNM_BSS_QUERY 0 list") 1953 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=0.1) 1954 if ev is not None: 1955 raise Exception("Unexpected BSS TM Response reported") 1956 1957 def test_wnm_bss_transition_mgmt_query_mbo(dev, apdev): 1958 """WNM BSS Transition Management query - TM only due to MBO on AP""" 1959 hapd = start_wnm_ap(apdev[0], bss_transition=False, mbo=True) 1960 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 1961 dev[0].request("WNM_BSS_QUERY 0 list") 1962 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5) 1963 if ev is None: 1964 raise Exception("No BSS TM Response reported") 1965 1966 @remote_compatible 1967 def test_wnm_bss_tm_security_mismatch(dev, apdev): 1968 """WNM BSS Transition Management and security mismatch""" 1969 hapd = start_wnm_ap(apdev[0], hw_mode="g", channel="1", ssid="test-wnm", 1970 rsn=True, pmf=False) 1971 hapd2 = start_wnm_ap(apdev[1], hw_mode="g", channel="11") 1972 dev[0].scan_for_bss(apdev[1]['bssid'], 2462) 1973 1974 id = dev[0].connect("test-wnm", psk="12345678", 1975 bssid=apdev[0]['bssid'], scan_freq="2412") 1976 dev[0].set_network(id, "scan_freq", "") 1977 dev[0].set_network(id, "bssid", "") 1978 1979 addr = dev[0].own_addr() 1980 dev[0].dump_monitor() 1981 1982 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 1983 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 1984 raise Exception("BSS_TM_REQ command failed") 1985 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 1986 if ev is None: 1987 raise Exception("No BSS Transition Management Response") 1988 if "status_code=7" not in ev: 1989 raise Exception("Unexpected BSS transition request response: " + ev) 1990 1991 def test_wnm_bss_tm_connect_cmd(dev, apdev): 1992 """WNM BSS Transition Management and cfg80211 connect command""" 1993 hapd = start_wnm_ap(apdev[0], hw_mode="g", channel="1") 1994 hapd2 = start_wnm_ap(apdev[1], hw_mode="g", channel="11") 1995 1996 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 1997 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") 1998 1999 wpas.scan_for_bss(apdev[1]['bssid'], 2462) 2000 2001 id = wpas.connect("test-wnm", key_mgmt="NONE", 2002 bssid=apdev[0]['bssid'], scan_freq="2412") 2003 wpas.set_network(id, "scan_freq", "") 2004 wpas.set_network(id, "bssid", "") 2005 2006 addr = wpas.own_addr() 2007 wpas.dump_monitor() 2008 2009 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent") 2010 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"): 2011 raise Exception("BSS_TM_REQ command failed") 2012 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 2013 if ev is None: 2014 raise Exception("No BSS Transition Management Response") 2015 if "status_code=0" not in ev: 2016 raise Exception("BSS transition request was not accepted: " + ev) 2017 if "target_bssid=" + apdev[1]['bssid'] not in ev: 2018 raise Exception("Unexpected target BSS: " + ev) 2019 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED", 2020 "CTRL-EVENT-DISCONNECTED"], timeout=10) 2021 if ev is None: 2022 raise Exception("No reassociation seen") 2023 if "CTRL-EVENT-DISCONNECTED" in ev: 2024 raise Exception("Unexpected disconnection reported") 2025 if apdev[1]['bssid'] not in ev: 2026 raise Exception("Unexpected reassociation target: " + ev) 2027 2028 def test_wnm_bss_tm_reject(dev, apdev): 2029 """WNM BSS Transition Management request getting rejected""" 2030 try: 2031 hapd = None 2032 hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g", 2033 channel="1") 2034 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2035 addr = dev[0].own_addr() 2036 dev[0].dump_monitor() 2037 2038 if "OK" not in dev[0].request("SET reject_btm_req_reason 123"): 2039 raise Exception("Failed to set reject_btm_req_reason") 2040 2041 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " disassoc_timer=1"): 2042 raise Exception("BSS_TM_REQ command failed") 2043 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10) 2044 if ev is None: 2045 raise Exception("No BSS Transition Management Response") 2046 if addr not in ev: 2047 raise Exception("Unexpected BSS Transition Management Response address") 2048 if "status_code=123" not in ev: 2049 raise Exception("Unexpected BSS Transition Management Response status: " + ev) 2050 dev[0].wait_disconnected() 2051 dev[0].wait_connected() 2052 finally: 2053 if hapd: 2054 hapd.request("DISABLE") 2055 dev[0].disconnect_and_stop_scan() 2056 subprocess.call(['iw', 'reg', 'set', '00']) 2057 dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5) 2058 dev[0].flush_scan_cache() 2059 2060 def test_wnm_bss_tm_ap_proto(dev, apdev): 2061 """WNM BSS TM - protocol testing for AP message parsing""" 2062 hapd = start_wnm_ap(apdev[0]) 2063 bssid = hapd.own_addr() 2064 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2065 addr = dev[0].own_addr() 2066 2067 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000" 2068 hapd.set("ext_mgmt_frame_handling", "1") 2069 tests = ["0a", 2070 "0a06", 2071 "0a0601", 2072 "0a060100", 2073 "0a080000", 2074 "0a08000000", 2075 "0a080000001122334455", 2076 "0a08000000112233445566", 2077 "0a08000000112233445566112233445566778899", 2078 "0a08ffffff", 2079 "0a08ffffff112233445566778899", 2080 "0a1a", 2081 "0a1a00", 2082 "0a1a0000", 2083 "0a0c016015007f0f000000000000000000000000000000000000", 2084 "0a0700", 2085 "0aff00", 2086 "0aff"] 2087 for t in tests: 2088 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t): 2089 raise Exception("MGMT_RX_PROCESS failed") 2090 2091 hapd.set("ext_mgmt_frame_handling", "0") 2092 2093 def test_wnm_bss_transition_mgmt_query_with_unknown_candidates(dev, apdev): 2094 """WNM BSS Transition Management query with unknown candidates""" 2095 hapd = start_wnm_ap(apdev[0]) 2096 dev[0].scan_for_bss(apdev[0]['bssid'], 2412) 2097 2098 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2099 dev[0].request("WNM_BSS_QUERY 0 neighbor=00:11:22:33:44:55,0,81,1,4") 2100 2101 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"], 2102 timeout=5) 2103 if ev is None: 2104 raise Exception("No BSS Transition Management Request frame seen") 2105 2106 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5) 2107 if ev is None: 2108 raise Exception("No BSS Transition Management Response frame seen") 2109 2110 def test_wnm_time_adv_without_time_zone(dev, apdev): 2111 """WNM Time Advertisement without time zone configuration""" 2112 params = {"ssid": "test-wnm", 2113 "time_advertisement": "2"} 2114 hostapd.add_ap(apdev[0], params) 2115 2116 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2117 2118 def test_wnm_coloc_intf_reporting(dev, apdev): 2119 """WNM Collocated Interference Reporting""" 2120 hapd = start_wnm_ap(apdev[0], bss_transition=False, 2121 coloc_intf_reporting=True) 2122 2123 no_intf = struct.pack("<BBBBBLLLLH", 96, 21, 0, 127, 0x0f, 0, 0, 0, 0, 0) 2124 2125 try: 2126 dev[0].set("coloc_intf_reporting", "1") 2127 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2128 addr = dev[0].own_addr() 2129 if "OK" not in hapd.request("COLOC_INTF_REQ %s 1 5" % addr): 2130 raise Exception("Could not send Collocated Interference Request") 2131 ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2) 2132 if ev is None: 2133 raise Exception("No Collocated Interference Request frame seen") 2134 vals = ev.split(' ') 2135 if vals[2] != '1' or vals[3] != '5': 2136 raise Exception("Unexpected request values: " + ev) 2137 dev[0].set("coloc_intf_elems", binascii.hexlify(no_intf).decode()) 2138 ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1) 2139 if ev is None: 2140 raise Exception("No Collocated Interference Report frame seen") 2141 if addr + " 1 " + binascii.hexlify(no_intf).decode() not in ev: 2142 raise Exception("Unexpected report values: " + ev) 2143 2144 if "OK" not in hapd.request("COLOC_INTF_REQ %s 0 0" % addr): 2145 raise Exception("Could not send Collocated Interference Request") 2146 ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2) 2147 if ev is None: 2148 raise Exception("No Collocated Interference Request frame seen") 2149 vals = ev.split(' ') 2150 if vals[2] != '0' or vals[3] != '0': 2151 raise Exception("Unexpected request values: " + ev) 2152 2153 res = dev[0].request("COLOC_INTF_REPORT " + binascii.hexlify(no_intf).decode()) 2154 if "OK" not in res: 2155 raise Exception("Could not send unsolicited report") 2156 ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1) 2157 if ev is None: 2158 raise Exception("No Collocated Interference Report frame seen") 2159 if addr + " 0 " + binascii.hexlify(no_intf).decode() not in ev: 2160 raise Exception("Unexpected report values: " + ev) 2161 2162 if "FAIL" not in hapd.request("COLOC_INTF_REQ foo 1 5"): 2163 raise Exception("Invalid COLOC_INTF_REQ accepted") 2164 if "FAIL" not in hapd.request("COLOC_INTF_REQ 02:ff:ff:ff:ff:ff 1 5"): 2165 raise Exception("COLOC_INTF_REQ for unknown STA accepted") 2166 if "FAIL" not in hapd.request("COLOC_INTF_REQ %s 1" % addr): 2167 raise Exception("Invalid COLOC_INTF_REQ accepted") 2168 if "FAIL" not in hapd.request("COLOC_INTF_REQ %s" % addr): 2169 raise Exception("Invalid COLOC_INTF_REQ accepted") 2170 finally: 2171 dev[0].set("coloc_intf_reporting", "0") 2172 dev[0].set("coloc_intf_elems", "") 2173 2174 def test_wnm_coloc_intf_reporting_errors(dev, apdev): 2175 """WNM Collocated Interference Reporting errors""" 2176 hapd = start_wnm_ap(apdev[0], bss_transition=False, 2177 coloc_intf_reporting=True) 2178 bssid = hapd.own_addr() 2179 dev[0].set("coloc_intf_reporting", "1") 2180 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2181 addr = dev[0].own_addr() 2182 if "FAIL" not in hapd.request("COLOC_INTF_REQ %s 4 5" % addr): 2183 raise Exception("Invalid Collocated Interference Request accepted") 2184 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000" 2185 hapd.set("ext_mgmt_frame_handling", "1") 2186 tests = ["0a0c016015007f0f000000000000000000000000000000000000", 2187 "0a0c"] 2188 with alloc_fail(hapd, 1, "ieee802_11_rx_wnm_coloc_intf_report"): 2189 for t in tests: 2190 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t): 2191 raise Exception("MGMT_RX_PROCESS failed") 2192 2193 hapd.set("ext_mgmt_frame_handling", "0") 2194 2195 def test_wnm_bss_transition_mgmt_disabled(dev, apdev): 2196 """WNM BSS Transition Management disabled""" 2197 hapd = start_wnm_ap(apdev[0]) 2198 try: 2199 dev[0].set("disable_btm", "1") 2200 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2201 addr = dev[0].own_addr() 2202 hapd.request("BSS_TM_REQ " + addr) 2203 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=0.5) 2204 if ev is not None: 2205 raise Exception("Unexpected BSS Transition Management Response") 2206 finally: 2207 dev[0].set("disable_btm", "0") 2208 2209 def test_wnm_time_adv_restart(dev, apdev): 2210 """WNM time advertisement and interface restart""" 2211 hapd = start_wnm_ap(apdev[0], time_adv=True) 2212 hapd.disable() 2213 hapd.enable() 2214 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412") 2215 2216 def test_wnm_event_report(dev, apdev): 2217 """WNM event report""" 2218 ssid = "test-wnm-rsn" 2219 hapd = start_wnm_ap(apdev[0], rsn=True, he=True) 2220 bssid = apdev[0]['bssid'] 2221 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", 2222 proto="WPA2", ieee80211w="2", scan_freq="2412") 2223 hapd.wait_sta() 2224 2225 msg = {'fc': MGMT_SUBTYPE_ACTION << 4, 2226 'da': bssid, 2227 'sa': dev[0].own_addr(), 2228 'bssid': bssid} 2229 cmd = "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1=".format(bssid, bssid) 2230 cmd += " action=" 2231 2232 for i in range(10): 2233 hapd.note("Event Type %d" % i) 2234 payload = struct.pack("<3B5B", 2235 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2236 WLAN_EID_EVENT_REPORT, 3, 0, i, 0) 2237 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2238 2239 hapd.note("Too short Event Report element") 2240 payload = struct.pack("<3B4B", 2241 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2242 WLAN_EID_EVENT_REPORT, 2, 0, 0) 2243 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2244 2245 hapd.note("Truncated Event Report element") 2246 payload = struct.pack("<3B4B", 2247 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2248 WLAN_EID_EVENT_REPORT, 3, 0, 0) 2249 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2250 2251 hapd.note("Request failed") 2252 payload = struct.pack("<3B5B", 2253 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2254 WLAN_EID_EVENT_REPORT, 3, 0, 0, 1) 2255 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2256 2257 hapd.note("Unexpected element ID") 2258 payload = struct.pack("<3B5B", 2259 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2260 WLAN_EID_EVENT_REPORT + 1, 3, 0, 0, 0) 2261 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2262 2263 hapd.note("Too short BSS color collision report") 2264 payload = struct.pack("<3B5B", 2265 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2266 WLAN_EID_EVENT_REPORT, 3, 0, 4, 0) 2267 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2268 2269 hapd.note("Too short BSS color collision report") 2270 payload = struct.pack("<3B5BQ7B", 2271 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2272 WLAN_EID_EVENT_REPORT, 3 + 8 + 7, 0, 4, 0, 0, 2273 0, 0, 0, 0, 0, 0, 0) 2274 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2275 2276 hapd.note("BSS color collision report") 2277 payload = struct.pack("<3B5BQQ", 2278 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2279 WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0, 2280 0x1122334455667788, 0x123456789) 2281 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2282 2283 hapd.note("Too short BSS color in use report") 2284 payload = struct.pack("<3B5B", 2285 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2286 WLAN_EID_EVENT_REPORT, 3, 0, 5, 0) 2287 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2288 2289 hapd.note("Too short BSS color in use report") 2290 payload = struct.pack("<3B5BQ", 2291 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2292 WLAN_EID_EVENT_REPORT, 3 + 8, 0, 5, 0, 0) 2293 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2294 2295 hapd.note("BSS color in use report for color 1") 2296 payload = struct.pack("<3B5BQB", 2297 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2298 WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 1) 2299 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2300 2301 hapd.note("BSS color in use report for canceling") 2302 payload = struct.pack("<3B5BQB", 2303 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2304 WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 0) 2305 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2306 2307 hapd.note("BSS color in use report for invalid color") 2308 payload = struct.pack("<3B5BQB", 2309 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2310 WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 64) 2311 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2312 2313 time.sleep(51) 2314 hapd.note("BSS color collision report for more colors") 2315 payload = struct.pack("<3B5BQQ", 2316 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2317 WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0, 2318 0x1122334455667788, 0xfffffffffffffff0) 2319 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2320 2321 time.sleep(11) 2322 hapd.note("BSS color collision report") 2323 payload = struct.pack("<3B5BQQ", 2324 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2325 WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0, 2326 0x1122334455667788, 0xf) 2327 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2328 2329 time.sleep(51) 2330 hapd.note("BSS color collision report for all colors") 2331 payload = struct.pack("<3B5BQQ", 2332 ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0, 2333 WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0, 2334 0x1122334455667788, 0xffffffffffffffff) 2335 mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode()) 2336 2337 time.sleep(11) 2338