2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
7 from remotehost import remote_compatible
12 logger = logging.getLogger()
16 from wpasupplicant import WpaSupplicant
17 from utils import alloc_fail, wait_fail_trigger
18 from wlantest import Wlantest
21 def test_wnm_bss_transition_mgmt(dev, apdev):
22 """WNM BSS Transition Management"""
23 params = { "ssid": "test-wnm",
24 "time_advertisement": "2",
26 "wnm_sleep_mode": "1",
27 "bss_transition": "1" }
28 hostapd.add_ap(apdev[0], params)
30 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
31 dev[0].request("WNM_BSS_QUERY 0")
34 def test_wnm_disassoc_imminent(dev, apdev):
35 """WNM Disassociation Imminent"""
36 params = { "ssid": "test-wnm",
37 "time_advertisement": "2",
39 "wnm_sleep_mode": "1",
40 "bss_transition": "1" }
41 hapd = hostapd.add_ap(apdev[0], params)
43 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
44 addr = dev[0].p2p_interface_addr()
45 hapd.request("DISASSOC_IMMINENT " + addr + " 10")
46 ev = dev[0].wait_event(["WNM: Disassociation Imminent"])
48 raise Exception("Timeout while waiting for disassociation imminent")
49 if "Disassociation Timer 10" not in ev:
50 raise Exception("Unexpected disassociation imminent contents")
51 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
53 raise Exception("Timeout while waiting for re-connection scan")
56 def test_wnm_ess_disassoc_imminent(dev, apdev):
57 """WNM ESS Disassociation Imminent"""
58 params = { "ssid": "test-wnm",
59 "time_advertisement": "2",
61 "wnm_sleep_mode": "1",
62 "bss_transition": "1" }
63 hapd = hostapd.add_ap(apdev[0], params)
65 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
66 addr = dev[0].p2p_interface_addr()
67 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
68 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
70 raise Exception("Timeout while waiting for ESS disassociation imminent")
71 if "0 1024 http://example.com/session-info" not in ev:
72 raise Exception("Unexpected ESS disassociation imminent message contents")
73 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
75 raise Exception("Timeout while waiting for re-connection scan")
78 def test_wnm_ess_disassoc_imminent_pmf(dev, apdev):
79 """WNM ESS Disassociation Imminent"""
80 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
81 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
82 params["ieee80211w"] = "2"
83 params["bss_transition"] = "1"
84 hapd = hostapd.add_ap(apdev[0], params)
86 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
87 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
88 addr = dev[0].p2p_interface_addr()
89 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
90 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
92 raise Exception("Timeout while waiting for ESS disassociation imminent")
93 if "1 1024 http://example.com/session-info" not in ev:
94 raise Exception("Unexpected ESS disassociation imminent message contents")
95 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
97 raise Exception("Timeout while waiting for re-connection scan")
99 def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None):
100 addr = dev.p2p_interface_addr()
101 sta = hapd.get_sta(addr)
102 if "[WNM_SLEEP_MODE]" in sta['flags']:
103 raise Exception("Station unexpectedly in WNM-Sleep Mode")
105 logger.info("Going to WNM Sleep Mode")
107 if interval is not None:
108 extra += " interval=" + str(interval)
110 extra += " tfs_req=" + tfs_req
111 if "OK" not in dev.request("WNM_SLEEP enter" + extra):
112 raise Exception("WNM_SLEEP failed")
116 sta = hapd.get_sta(addr)
117 if "[WNM_SLEEP_MODE]" in sta['flags']:
121 raise Exception("Station failed to enter WNM-Sleep Mode")
123 logger.info("Waking up from WNM Sleep Mode")
125 dev.request("WNM_SLEEP exit")
128 sta = hapd.get_sta(addr)
129 if "[WNM_SLEEP_MODE]" not in sta['flags']:
133 raise Exception("Station failed to exit WNM-Sleep Mode")
136 def test_wnm_sleep_mode_open(dev, apdev):
137 """WNM Sleep Mode - open"""
138 params = { "ssid": "test-wnm",
139 "time_advertisement": "2",
141 "wnm_sleep_mode": "1",
142 "bss_transition": "1" }
143 hapd = hostapd.add_ap(apdev[0], params)
145 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
146 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
148 raise Exception("No connection event received from hostapd")
149 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
150 check_wnm_sleep_mode_enter_exit(hapd, dev[0], interval=100)
151 check_wnm_sleep_mode_enter_exit(hapd, dev[0], tfs_req="5b17010001130e110000071122334455661122334455661234")
154 "exit tfs_req=123 interval=10",
155 "enter tfs_req=qq interval=10" ]
157 if "FAIL" not in dev[0].request("WNM_SLEEP " + cmd):
158 raise Exception("Invalid WNM_SLEEP accepted")
161 def test_wnm_sleep_mode_rsn(dev, apdev):
162 """WNM Sleep Mode - RSN"""
163 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
164 params["time_advertisement"] = "2"
165 params["time_zone"] = "EST5"
166 params["wnm_sleep_mode"] = "1"
167 params["bss_transition"] = "1"
168 hapd = hostapd.add_ap(apdev[0], params)
170 dev[0].connect("test-wnm-rsn", psk="12345678", scan_freq="2412")
171 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
173 raise Exception("No connection event received from hostapd")
174 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
177 def test_wnm_sleep_mode_ap_oom(dev, apdev):
178 """WNM Sleep Mode - AP side OOM"""
179 params = { "ssid": "test-wnm",
180 "wnm_sleep_mode": "1" }
181 hapd = hostapd.add_ap(apdev[0], params)
183 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
184 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
186 raise Exception("No connection event received from hostapd")
187 with alloc_fail(hapd, 1, "ieee802_11_send_wnmsleep_resp"):
188 dev[0].request("WNM_SLEEP enter")
189 wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
190 with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"):
191 dev[0].request("WNM_SLEEP exit")
192 wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
195 def test_wnm_sleep_mode_rsn_pmf(dev, apdev):
196 """WNM Sleep Mode - RSN with PMF"""
197 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
198 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
199 params["ieee80211w"] = "2"
200 params["time_advertisement"] = "2"
201 params["time_zone"] = "EST5"
202 params["wnm_sleep_mode"] = "1"
203 params["bss_transition"] = "1"
204 hapd = hostapd.add_ap(apdev[0], params)
209 wt.add_passphrase("12345678")
211 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
212 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
213 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
215 raise Exception("No connection event received from hostapd")
216 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
218 MGMT_SUBTYPE_ACTION = 13
219 ACTION_CATEG_WNM = 10
220 WNM_ACT_BSS_TM_REQ = 7
221 WNM_ACT_BSS_TM_RESP = 8
222 WNM_ACT_SLEEP_MODE_REQ = 16
223 WNM_ACT_SLEEP_MODE_RESP = 17
224 WNM_ACT_NOTIFICATION_REQ = 26
225 WNM_ACT_NOTIFICATION_RESP = 27
226 WNM_NOTIF_TYPE_FW_UPGRADE = 0
227 WNM_NOTIF_TYPE_WFA = 1
228 WLAN_EID_TFS_RESP = 92
229 WLAN_EID_WNMSLEEP = 93
230 WNM_SLEEP_MODE_ENTER = 0
231 WNM_SLEEP_MODE_EXIT = 1
232 WNM_STATUS_SLEEP_ACCEPT = 0
233 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1
234 WNM_STATUS_DENIED_ACTION = 2
235 WNM_STATUS_DENIED_TMP = 3
236 WNM_STATUS_DENIED_KEY = 4
237 WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5
238 WNM_SLEEP_SUBELEM_GTK = 0
239 WNM_SLEEP_SUBELEM_IGTK = 1
241 def bss_tm_req(dst, src, dialog_token=1, req_mode=0, disassoc_timer=0,
242 validity_interval=1):
244 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
248 msg['payload'] = struct.pack("<BBBBHB",
249 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
250 dialog_token, req_mode, disassoc_timer,
254 def rx_bss_tm_resp(hapd, expect_dialog=None, expect_status=None):
255 for i in range(0, 100):
256 resp = hapd.mgmt_rx()
258 raise Exception("No BSS TM Response received")
259 if resp['subtype'] == MGMT_SUBTYPE_ACTION:
262 raise Exception("Not an Action frame")
263 payload = resp['payload']
264 if len(payload) < 2 + 3:
265 raise Exception("Too short payload")
266 (category, action) = struct.unpack('BB', payload[0:2])
267 if category != ACTION_CATEG_WNM or action != WNM_ACT_BSS_TM_RESP:
268 raise Exception("Not a BSS TM Response")
270 (dialog, status, bss_term_delay) = struct.unpack('BBB', pos[0:3])
271 resp['dialog'] = dialog
272 resp['status'] = status
273 resp['bss_term_delay'] = bss_term_delay
275 if len(pos) >= 6 and status == 0:
276 resp['target_bssid'] = binascii.hexlify(pos[0:6])
278 resp['candidates'] = pos
279 if expect_dialog is not None and dialog != expect_dialog:
280 raise Exception("Unexpected dialog token")
281 if expect_status is not None and status != expect_status:
282 raise Exception("Unexpected status code %d" % status)
285 def expect_ack(hapd):
286 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
288 raise Exception("Missing TX status")
290 raise Exception("Action frame not acknowledged")
293 def test_wnm_bss_tm_req(dev, apdev):
294 """BSS Transition Management Request"""
295 params = { "ssid": "test-wnm", "bss_transition": "1" }
296 hapd = hostapd.add_ap(apdev[0], params)
297 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
298 hapd2 = hostapd.add_ap(apdev[1], params)
300 hapd.set("ext_mgmt_frame_handling", "1")
302 # truncated BSS TM Request
303 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
305 req['payload'] = struct.pack("<BBBBH",
306 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
311 # no disassociation and no candidate list
312 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
315 resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1)
317 # truncated BSS Termination Duration
318 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
323 # BSS Termination Duration with TSF=0 and Duration=10
324 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
325 req_mode=0x08, dialog_token=3)
326 req['payload'] += struct.pack("<BBQH", 4, 10, 0, 10)
328 resp = rx_bss_tm_resp(hapd, expect_dialog=3, expect_status=1)
330 # truncated Session Information URL
331 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
335 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
337 req['payload'] += struct.pack("<BBB", 3, 65, 66)
341 # Session Information URL
342 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
343 req_mode=0x10, dialog_token=4)
344 req['payload'] += struct.pack("<BBB", 2, 65, 66)
346 resp = rx_bss_tm_resp(hapd, expect_dialog=4, expect_status=0)
348 # Preferred Candidate List without any entries
349 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
350 req_mode=0x01, dialog_token=5)
352 resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7)
354 # Preferred Candidate List with a truncated entry
355 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
357 req['payload'] += struct.pack("<BB", 52, 1)
361 # Preferred Candidate List with a too short entry
362 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
363 req_mode=0x01, dialog_token=6)
364 req['payload'] += struct.pack("<BB", 52, 0)
366 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
368 # Preferred Candidate List with a non-matching entry
369 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
370 req_mode=0x01, dialog_token=6)
371 req['payload'] += struct.pack("<BB6BLBBB", 52, 13,
375 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
377 # Preferred Candidate List with a truncated subelement
378 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
379 req_mode=0x01, dialog_token=7)
380 req['payload'] += struct.pack("<BB6BLBBBBB", 52, 13 + 2,
385 resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7)
387 # Preferred Candidate List with lots of invalid optional subelements
388 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
389 req_mode=0x01, dialog_token=8)
390 subelems = struct.pack("<BBHB", 1, 3, 0, 100)
391 subelems += struct.pack("<BBB", 2, 1, 65)
392 subelems += struct.pack("<BB", 3, 0)
393 subelems += struct.pack("<BBQB", 4, 9, 0, 10)
394 subelems += struct.pack("<BBHLB", 5, 7, 0, 0, 0)
395 subelems += struct.pack("<BB", 66, 0)
396 subelems += struct.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
397 subelems += struct.pack("<BB", 71, 0)
398 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
400 0, 81, 1, 7) + subelems
402 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
404 # Preferred Candidate List with lots of valid optional subelements (twice)
405 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
406 req_mode=0x01, dialog_token=8)
408 subelems = struct.pack("<BBHH", 1, 4, 0, 100)
409 # Condensed Country String
410 subelems += struct.pack("<BBBB", 2, 2, 65, 66)
411 # BSS Transition Candidate Preference
412 subelems += struct.pack("<BBB", 3, 1, 100)
413 # BSS Termination Duration
414 subelems += struct.pack("<BBQH", 4, 10, 0, 10)
416 subelems += struct.pack("<BBHLH", 5, 8, 0, 0, 0)
417 # Measurement Pilot Transmission
418 subelems += struct.pack("<BBBBB", 66, 3, 0, 0, 0)
419 # RM Enabled Capabilities
420 subelems += struct.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
422 subelems += struct.pack("<BBBB", 71, 2, 0, 0)
423 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems) * 2,
425 0, 81, 1, 7) + subelems + subelems
427 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
429 # Preferred Candidate List followed by vendor element
430 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
431 req_mode=0x01, dialog_token=8)
433 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
435 0, 81, 1, 7) + subelems
436 req['payload'] += binascii.unhexlify("DD0411223344")
438 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
441 def test_wnm_bss_keep_alive(dev, apdev):
443 params = { "ssid": "test-wnm",
444 "ap_max_inactivity": "1" }
445 hapd = hostapd.add_ap(apdev[0], params)
447 addr = dev[0].p2p_interface_addr()
448 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
449 start = hapd.get_sta(addr)
450 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=2)
452 raise Exception("Unexpected disconnection")
453 end = hapd.get_sta(addr)
454 if int(end['rx_packets']) <= int(start['rx_packets']):
455 raise Exception("No keep-alive packets received")
457 # Disable client keep-alive so that hostapd will verify connection
459 dev[0].request("SET no_keep_alive 1")
461 sta = hapd.get_sta(addr)
462 logger.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta['timeout_next'], sta['rx_packets'], sta['tx_packets']))
463 if i > 1 and sta['timeout_next'] != "NULLFUNC POLL" and int(sta['tx_packets']) > int(end['tx_packets']):
465 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
467 raise Exception("Unexpected disconnection (client poll expected)")
469 dev[0].request("SET no_keep_alive 0")
470 if int(sta['tx_packets']) <= int(end['tx_packets']):
471 raise Exception("No client poll packet seen")
473 def test_wnm_bss_tm(dev, apdev):
474 """WNM BSS Transition Management"""
478 params = { "ssid": "test-wnm",
479 "country_code": "FI",
483 "bss_transition": "1" }
484 hapd = hostapd.add_ap(apdev[0], params)
486 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
487 dev[0].set_network(id, "scan_freq", "")
489 params = { "ssid": "test-wnm",
490 "country_code": "FI",
494 "bss_transition": "1" }
495 hapd2 = hostapd.add_ap(apdev[1], params)
497 addr = dev[0].p2p_interface_addr()
498 dev[0].dump_monitor()
500 logger.info("No neighbor list entries")
501 if "OK" not in hapd.request("BSS_TM_REQ " + addr):
502 raise Exception("BSS_TM_REQ command failed")
503 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
505 raise Exception("No BSS Transition Management Response")
507 raise Exception("Unexpected BSS Transition Management Response address")
508 if "status_code=0" in ev:
509 raise Exception("BSS transition accepted unexpectedly")
510 dev[0].dump_monitor()
512 logger.info("Neighbor list entry, but not claimed as Preferred Candidate List")
513 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
514 raise Exception("BSS_TM_REQ command failed")
515 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
517 raise Exception("No BSS Transition Management Response")
518 if "status_code=0" in ev:
519 raise Exception("BSS transition accepted unexpectedly")
520 dev[0].dump_monitor()
522 logger.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
523 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=22:33:44:55:66:77,0x0000,1,36,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a"):
524 raise Exception("BSS_TM_REQ command failed")
525 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
527 raise Exception("No BSS Transition Management Response")
528 if "status_code=0" in ev:
529 raise Exception("BSS transition accepted unexpectedly")
530 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
532 raise Exception("No scan started")
533 dev[0].dump_monitor()
535 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
536 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"):
537 raise Exception("BSS_TM_REQ command failed")
538 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
540 raise Exception("No BSS Transition Management Response")
541 if "status_code=0" not in ev:
542 raise Exception("BSS transition request was not accepted: " + ev)
543 if "target_bssid=" + apdev[1]['bssid'] not in ev:
544 raise Exception("Unexpected target BSS: " + ev)
545 dev[0].wait_connected(timeout=15, error="No reassociation seen")
546 if apdev[1]['bssid'] not in ev:
547 raise Exception("Unexpected reassociation target: " + ev)
548 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
550 raise Exception("Unexpected scan started")
551 dev[0].dump_monitor()
553 logger.info("Preferred Candidate List with two matches, no roam needed")
554 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"):
555 raise Exception("BSS_TM_REQ command failed")
556 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
558 raise Exception("No BSS Transition Management Response")
559 if "status_code=0" not in ev:
560 raise Exception("BSS transition request was not accepted: " + ev)
561 if "target_bssid=" + apdev[1]['bssid'] not in ev:
562 raise Exception("Unexpected target BSS: " + ev)
563 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
565 raise Exception("Unexpected scan started")
566 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
568 raise Exception("Unexpected reassociation")
570 dev[0].request("DISCONNECT")
572 hapd.request("DISABLE")
574 hapd2.request("DISABLE")
575 subprocess.call(['iw', 'reg', 'set', '00'])
576 dev[0].flush_scan_cache()
578 def test_wnm_bss_tm_scan_not_needed(dev, apdev):
579 """WNM BSS Transition Management and scan not needed"""
580 run_wnm_bss_tm_scan_not_needed(dev, apdev)
582 def test_wnm_bss_tm_nei_vht(dev, apdev):
583 """WNM BSS Transition Management and VHT neighbor"""
584 run_wnm_bss_tm_scan_not_needed(dev, apdev, vht=True, nei_info="115,36,9")
586 def test_wnm_bss_tm_nei_11a(dev, apdev):
587 """WNM BSS Transition Management and 11a neighbor"""
588 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, nei_info="115,36,4")
590 def test_wnm_bss_tm_nei_11g(dev, apdev):
591 """WNM BSS Transition Management and 11g neighbor"""
592 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='g',
593 channel='2', freq=2417, nei_info="81,2,6")
595 def test_wnm_bss_tm_nei_11b(dev, apdev):
596 """WNM BSS Transition Management and 11g neighbor"""
597 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='b',
598 channel='3', freq=2422, nei_info="81,2,5")
600 def run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=True, vht=False, hwmode='a',
601 channel='36', freq=5180,
602 nei_info="115,36,7,0301ff"):
606 params = { "ssid": "test-wnm",
607 "country_code": "FI",
611 "bss_transition": "1" }
612 hapd = hostapd.add_ap(apdev[0], params)
614 params = { "ssid": "test-wnm",
615 "country_code": "FI",
619 "bss_transition": "1" }
621 params['ieee80211n'] = '0'
623 params['ieee80211ac'] = "1"
624 params["vht_oper_chwidth"] = "0"
625 params["vht_oper_centr_freq_seg0_idx"] = "0"
627 hapd2 = hostapd.add_ap(apdev[1], params)
629 dev[0].scan_for_bss(apdev[1]['bssid'], freq)
631 id = dev[0].connect("test-wnm", key_mgmt="NONE",
632 bssid=apdev[0]['bssid'], scan_freq="2412")
633 dev[0].set_network(id, "scan_freq", "")
634 dev[0].set_network(id, "bssid", "")
636 addr = dev[0].own_addr()
637 dev[0].dump_monitor()
639 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
640 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + nei_info):
641 raise Exception("BSS_TM_REQ command failed")
642 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
644 raise Exception("No BSS Transition Management Response")
645 if "status_code=0" not in ev:
646 raise Exception("BSS transition request was not accepted: " + ev)
647 if "target_bssid=" + apdev[1]['bssid'] not in ev:
648 raise Exception("Unexpected target BSS: " + ev)
649 dev[0].wait_connected(timeout=15, error="No reassociation seen")
650 if apdev[1]['bssid'] not in ev:
651 raise Exception("Unexpected reassociation target: " + ev)
652 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
654 raise Exception("Unexpected scan started")
655 dev[0].dump_monitor()
657 dev[0].request("DISCONNECT")
659 hapd.request("DISABLE")
661 hapd2.request("DISABLE")
662 subprocess.call(['iw', 'reg', 'set', '00'])
663 dev[0].flush_scan_cache()
665 def test_wnm_bss_tm_scan_needed(dev, apdev):
666 """WNM BSS Transition Management and scan needed"""
670 params = { "ssid": "test-wnm",
671 "country_code": "FI",
675 "bss_transition": "1" }
676 hapd = hostapd.add_ap(apdev[0], params)
678 params = { "ssid": "test-wnm",
679 "country_code": "FI",
683 "bss_transition": "1" }
684 hapd2 = hostapd.add_ap(apdev[1], params)
686 dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
688 id = dev[0].connect("test-wnm", key_mgmt="NONE",
689 bssid=apdev[0]['bssid'], scan_freq="2412")
690 dev[0].set_network(id, "scan_freq", "")
691 dev[0].set_network(id, "bssid", "")
693 addr = dev[0].own_addr()
694 dev[0].dump_monitor()
696 logger.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
698 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
699 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"):
700 raise Exception("BSS_TM_REQ command failed")
701 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
703 raise Exception("No BSS Transition Management Response")
704 if "status_code=0" not in ev:
705 raise Exception("BSS transition request was not accepted: " + ev)
706 if "target_bssid=" + apdev[1]['bssid'] not in ev:
707 raise Exception("Unexpected target BSS: " + ev)
708 dev[0].wait_connected(timeout=15, error="No reassociation seen")
709 if apdev[1]['bssid'] not in ev:
710 raise Exception("Unexpected reassociation target: " + ev)
711 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
713 raise Exception("Unexpected scan started")
714 dev[0].dump_monitor()
716 dev[0].request("DISCONNECT")
718 hapd.request("DISABLE")
720 hapd2.request("DISABLE")
721 subprocess.call(['iw', 'reg', 'set', '00'])
722 dev[0].flush_scan_cache()
724 def start_wnm_tm(ap, country, dev):
725 params = { "ssid": "test-wnm",
726 "country_code": country,
730 "bss_transition": "1" }
731 hapd = hostapd.add_ap(ap, params)
732 id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
734 dev.set_network(id, "scan_freq", "")
737 def stop_wnm_tm(hapd, dev):
738 dev.request("DISCONNECT")
740 dev.wait_disconnected()
744 hapd.request("DISABLE")
745 subprocess.call(['iw', 'reg', 'set', '00'])
746 dev.flush_scan_cache()
748 def wnm_bss_tm_check(hapd, dev, data):
749 addr = dev.p2p_interface_addr()
750 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " " + data):
751 raise Exception("BSS_TM_REQ command failed")
752 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
754 raise Exception("No scan started")
755 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
757 raise Exception("Scan did not complete")
759 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
761 raise Exception("No BSS Transition Management Response")
762 if "status_code=7" not in ev:
763 raise Exception("Unexpected response: " + ev)
765 def test_wnm_bss_tm_country_us(dev, apdev):
766 """WNM BSS Transition Management (US)"""
769 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
771 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
772 wnm_bss_tm_check(hapd, dev[0], "pref=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")
774 # Make the test take less time by limiting full scans
775 dev[0].set_network(id, "scan_freq", "2412")
776 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
777 wnm_bss_tm_check(hapd, dev[0], "pref=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")
779 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
780 wnm_bss_tm_check(hapd, dev[0], "pref=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")
782 stop_wnm_tm(hapd, dev[0])
784 def test_wnm_bss_tm_country_fi(dev, apdev):
785 """WNM BSS Transition Management (FI)"""
786 addr = dev[0].p2p_interface_addr()
789 hapd, id = start_wnm_tm(apdev[0], "FI", dev[0])
791 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
792 wnm_bss_tm_check(hapd, dev[0], "pref=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")
794 # Make the test take less time by limiting full scans
795 dev[0].set_network(id, "scan_freq", "2412")
796 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
797 wnm_bss_tm_check(hapd, dev[0], "pref=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")
799 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
800 wnm_bss_tm_check(hapd, dev[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
802 stop_wnm_tm(hapd, dev[0])
804 def test_wnm_bss_tm_country_jp(dev, apdev):
805 """WNM BSS Transition Management (JP)"""
806 addr = dev[0].p2p_interface_addr()
809 hapd, id = start_wnm_tm(apdev[0], "JP", dev[0])
811 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
812 wnm_bss_tm_check(hapd, dev[0], "pref=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")
814 # Make the test take less time by limiting full scans
815 dev[0].set_network(id, "scan_freq", "2412")
816 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
817 wnm_bss_tm_check(hapd, dev[0], "pref=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")
819 stop_wnm_tm(hapd, dev[0])
821 def test_wnm_bss_tm_country_cn(dev, apdev):
822 """WNM BSS Transition Management (CN)"""
823 addr = dev[0].p2p_interface_addr()
826 hapd, id = start_wnm_tm(apdev[0], "CN", dev[0])
828 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
829 wnm_bss_tm_check(hapd, dev[0], "pref=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")
831 # Make the test take less time by limiting full scans
832 dev[0].set_network(id, "scan_freq", "2412")
833 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
834 wnm_bss_tm_check(hapd, dev[0], "pref=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")
836 stop_wnm_tm(hapd, dev[0])
838 def test_wnm_bss_tm_global(dev, apdev):
839 """WNM BSS Transition Management (global)"""
840 addr = dev[0].p2p_interface_addr()
843 hapd, id = start_wnm_tm(apdev[0], "XX", dev[0])
845 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
846 wnm_bss_tm_check(hapd, dev[0], "pref=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")
848 # Make the test take less time by limiting full scans
849 dev[0].set_network(id, "scan_freq", "2412")
850 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
851 wnm_bss_tm_check(hapd, dev[0], "pref=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")
853 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
854 wnm_bss_tm_check(hapd, dev[0], "pref=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")
856 stop_wnm_tm(hapd, dev[0])
858 def test_wnm_bss_tm_op_class_0(dev, apdev):
859 """WNM BSS Transition Management with invalid operating class"""
862 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
864 logger.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
865 wnm_bss_tm_check(hapd, dev[0], "pref=1 neighbor=00:11:22:33:44:59,0x0000,0,149,7 neighbor=00:11:22:33:44:5b,0x0000,0,1,7")
867 stop_wnm_tm(hapd, dev[0])
869 def test_wnm_action_proto(dev, apdev):
870 """WNM Action protocol testing"""
871 params = { "ssid": "test-wnm" }
872 params['wnm_sleep_mode'] = '1'
873 hapd = hostapd.add_ap(apdev[0], params)
874 bssid = apdev[0]['bssid']
875 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
876 dev[0].request("WNM_SLEEP enter")
878 hapd.set("ext_mgmt_frame_handling", "1")
881 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
882 msg['da'] = dev[0].own_addr()
888 logger.debug("Unexpected WNM-Notification Response")
889 # Note: This is actually not registered for user space processing in
890 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
891 # it to wpa_supplicant.
892 msg['payload'] = struct.pack("<BBBB",
893 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_RESP,
898 logger.debug("Truncated WNM-Notification Request (no Type field)")
899 msg['payload'] = struct.pack("<BBB",
900 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
905 logger.debug("WFA WNM-Notification Request with truncated IE (min)")
906 msg['payload'] = struct.pack("<BBBBBB",
907 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
908 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 1)
912 logger.debug("WFA WNM-Notification Request with truncated IE (max)")
913 msg['payload'] = struct.pack("<BBBBBB",
914 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
915 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 255)
919 logger.debug("WFA WNM-Notification Request with too short IE")
920 msg['payload'] = struct.pack("<BBBBBB",
921 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
922 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 0)
926 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
927 msg['payload'] = struct.pack(">BBBBBBLB",
928 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
929 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
934 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
935 msg['payload'] = struct.pack(">BBBBBBLBB",
936 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
937 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 6,
942 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
943 msg['payload'] = struct.pack(">BBBBBBLB",
944 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
945 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
950 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
951 msg['payload'] = struct.pack(">BBBBBBLBHB",
952 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
953 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
958 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
959 msg['payload'] = struct.pack(">BBBBBBLBHB",
960 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
961 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
962 0x506f9a01, 0, 0, 0xff)
966 logger.debug("WFA WNM-Notification Request with unsupported IE")
967 msg['payload'] = struct.pack("<BBBBBBL",
968 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
969 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 4, 0)
973 logger.debug("WNM-Notification Request with unknown WNM-Notification type 0")
974 msg['payload'] = struct.pack("<BBBB",
975 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
976 dialog_token, WNM_NOTIF_TYPE_FW_UPGRADE)
980 logger.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
981 msg['payload'] = struct.pack("<BB",
982 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP)
986 logger.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
987 msg['payload'] = struct.pack("<BBB",
988 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0)
992 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
993 msg['payload'] = struct.pack("<BBBH",
994 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
999 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1000 msg['payload'] = struct.pack("<BBBH",
1001 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1006 logger.debug("WNM Sleep Mode Response - truncated IE header")
1007 msg['payload'] = struct.pack("<BBBHB",
1008 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1013 logger.debug("WNM Sleep Mode Response - truncated IE")
1014 msg['payload'] = struct.pack("<BBBHBB",
1015 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1020 logger.debug("WNM Sleep Mode Response - Empty TFS Response")
1021 msg['payload'] = struct.pack("<BBBHBB",
1022 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1023 0, WLAN_EID_TFS_RESP, 0)
1027 logger.debug("WNM Sleep Mode Response - EID 0 not recognized")
1028 msg['payload'] = struct.pack("<BBBHBB",
1029 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1034 logger.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1035 msg['payload'] = struct.pack("<BBBHBBBB",
1036 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1037 0, WLAN_EID_WNMSLEEP, 0, WLAN_EID_TFS_RESP, 0)
1041 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1042 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1043 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1044 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1045 WNM_STATUS_SLEEP_ACCEPT, 0,
1046 WLAN_EID_TFS_RESP, 0)
1050 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1051 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1052 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1053 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1054 WNM_STATUS_DENIED_KEY, 0,
1055 WLAN_EID_TFS_RESP, 0)
1059 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1060 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1061 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1062 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1063 WNM_STATUS_DENIED_KEY, 0,
1064 WLAN_EID_TFS_RESP, 0)
1069 def test_wnm_action_proto_pmf(dev, apdev):
1070 """WNM Action protocol testing (PMF enabled)"""
1071 ssid = "test-wnm-pmf"
1072 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1073 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1074 params["ieee80211w"] = "2"
1075 params['wnm_sleep_mode'] = '1'
1076 hapd = hostapd.add_ap(apdev[0], params)
1077 bssid = apdev[0]['bssid']
1078 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
1079 proto="WPA2", ieee80211w="2", scan_freq="2412")
1080 dev[0].request("WNM_SLEEP enter")
1082 hapd.set("ext_mgmt_frame_handling", "1")
1085 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1086 msg['da'] = dev[0].own_addr()
1088 msg['bssid'] = bssid
1090 logger.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1091 keydata = struct.pack("<BB", 0, 1)
1092 msg['payload'] = struct.pack("<BBBH",
1093 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1095 msg['payload'] += keydata
1096 msg['payload'] += struct.pack("<BBBBHBB",
1097 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1098 WNM_STATUS_SLEEP_ACCEPT, 0,
1099 WLAN_EID_TFS_RESP, 0)
1103 logger.debug("WNM Sleep Mode Response - Too short GTK subelem")
1104 keydata = struct.pack("<BB", WNM_SLEEP_SUBELEM_GTK, 0)
1105 msg['payload'] = struct.pack("<BBBH",
1106 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1108 msg['payload'] += keydata
1109 msg['payload'] += struct.pack("<BBBBHBB",
1110 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1111 WNM_STATUS_SLEEP_ACCEPT, 0,
1112 WLAN_EID_TFS_RESP, 0)
1116 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1117 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1118 0, 17, 0, 0, 0, 0, 0, 0)
1119 msg['payload'] = struct.pack("<BBBH",
1120 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1122 msg['payload'] += keydata
1123 msg['payload'] += struct.pack("<BBBBHBB",
1124 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1125 WNM_STATUS_SLEEP_ACCEPT, 0,
1126 WLAN_EID_TFS_RESP, 0)
1130 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1131 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1132 0, 0, 0, 0, 0, 0, 0, 0)
1133 msg['payload'] = struct.pack("<BBBH",
1134 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1136 msg['payload'] += keydata
1137 msg['payload'] += struct.pack("<BBBBHBB",
1138 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1139 WNM_STATUS_SLEEP_ACCEPT, 0,
1140 WLAN_EID_TFS_RESP, 0)
1144 logger.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1145 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1146 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1147 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1148 keydata += struct.pack("<BB", WNM_SLEEP_SUBELEM_IGTK, 0)
1149 msg['payload'] = struct.pack("<BBBH",
1150 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1152 msg['payload'] += keydata
1153 msg['payload'] += struct.pack("<BBBBHBB",
1154 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1155 WNM_STATUS_SLEEP_ACCEPT, 0,
1156 WLAN_EID_TFS_RESP, 0)
1160 logger.debug("WNM Sleep Mode Response - Unknown subelem")
1161 keydata = struct.pack("<BB", 255, 0)
1162 msg['payload'] = struct.pack("<BBBH",
1163 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1165 msg['payload'] += keydata
1166 msg['payload'] += struct.pack("<BBBBHBB",
1167 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1168 WNM_STATUS_SLEEP_ACCEPT, 0,
1169 WLAN_EID_TFS_RESP, 0)
1174 def test_wnm_action_proto_no_pmf(dev, apdev):
1175 """WNM Action protocol testing (PMF disabled)"""
1176 ssid = "test-wnm-no-pmf"
1177 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1178 params['wnm_sleep_mode'] = '1'
1179 hapd = hostapd.add_ap(apdev[0], params)
1180 bssid = apdev[0]['bssid']
1181 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1182 proto="WPA2", ieee80211w="0", scan_freq="2412")
1183 dev[0].request("WNM_SLEEP enter")
1185 hapd.set("ext_mgmt_frame_handling", "1")
1188 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1189 msg['da'] = dev[0].own_addr()
1191 msg['bssid'] = bssid
1193 logger.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1194 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1195 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1196 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1197 keydata += struct.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK, 2 + 6 + 16, 0,
1199 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1200 msg['payload'] = struct.pack("<BBBH",
1201 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1203 msg['payload'] += keydata
1204 msg['payload'] += struct.pack("<BBBBHBB",
1205 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1206 WNM_STATUS_SLEEP_ACCEPT, 0,
1207 WLAN_EID_TFS_RESP, 0)
1211 ev = dev[0].wait_event(["WNM: Ignore Key Data"], timeout=5)
1213 raise Exception("Key Data not ignored")
1215 def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev):
1216 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1217 ssid = "test-wnm-mbo"
1218 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1219 hapd = hostapd.add_ap(apdev[0], params)
1220 bssid = apdev[0]['bssid']
1221 if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
1222 raise Exception("Failed to set STA as cellular data capable")
1224 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1225 proto="WPA2", ieee80211w="0", scan_freq="2412")
1227 logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1228 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"):
1229 raise Exception("BSS transition management succeeded unexpectedly")
1231 logger.debug("BTM request with invalid MBO transition reason code")
1232 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"):
1233 raise Exception("BSS transition management succeeded unexpectedly")
1235 logger.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1236 if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1237 raise Exception("BSS transition management command failed")
1239 ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1240 if ev is None or "preference=1" not in ev:
1241 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1243 ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1244 if ev is None or "reason=3" not in ev:
1245 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1247 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1249 raise Exception("No BSS Transition Management Response")
1250 if dev[0].own_addr() not in ev:
1251 raise Exception("Unexpected BSS Transition Management Response address")
1253 ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1255 raise Exception("Station did not disconnect although disassoc imminent was set")
1257 # Set the scan interval to make dev[0] look for connections
1258 if 'OK' not in dev[0].request("SCAN_INTERVAL 1"):
1259 raise Exception("Failed to set scan interval")
1261 # Make sure no connection is made during the retry delay
1262 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1264 raise Exception("Station connected before assoc retry delay was over")
1266 # After the assoc retry delay is over, we can reconnect
1267 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1269 raise Exception("Station did not connect after assoc retry delay is over")
1271 if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
1272 raise Exception("Failed to set STA as cellular data not-capable")
1275 def test_wnm_bss_transition_mgmt_query(dev, apdev):
1276 """WNM BSS Transition Management query"""
1277 params = { "ssid": "test-wnm",
1278 "bss_transition": "1" }
1279 hapd = hostapd.add_ap(apdev[0], params)
1280 params = { "ssid": "another" }
1281 hapd2 = hostapd.add_ap(apdev[1], params)
1283 dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
1284 dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
1286 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1287 dev[0].request("WNM_BSS_QUERY 0 list")
1289 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
1292 raise Exception("No BSS Transition Management Request frame seen")
1294 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1296 raise Exception("No BSS Transition Management Response frame seen")
1299 def test_wnm_bss_tm_security_mismatch(dev, apdev):
1300 """WNM BSS Transition Management and security mismatch"""
1301 params = { "ssid": "test-wnm",
1303 "wpa_key_mgmt": "WPA-PSK",
1304 "rsn_pairwise": "CCMP",
1305 "wpa_passphrase": "12345678",
1308 "bss_transition": "1" }
1309 hapd = hostapd.add_ap(apdev[0], params)
1311 params = { "ssid": "test-wnm",
1314 "bss_transition": "1" }
1315 hapd2 = hostapd.add_ap(apdev[1], params)
1317 dev[0].scan_for_bss(apdev[1]['bssid'], 2462)
1319 id = dev[0].connect("test-wnm", psk="12345678",
1320 bssid=apdev[0]['bssid'], scan_freq="2412")
1321 dev[0].set_network(id, "scan_freq", "")
1322 dev[0].set_network(id, "bssid", "")
1324 addr = dev[0].own_addr()
1325 dev[0].dump_monitor()
1327 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1328 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"):
1329 raise Exception("BSS_TM_REQ command failed")
1330 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1332 raise Exception("No BSS Transition Management Response")
1333 if "status_code=7" not in ev:
1334 raise Exception("Unexpected BSS transition request response: " + ev)
1336 def test_wnm_bss_tm_connect_cmd(dev, apdev):
1337 """WNM BSS Transition Management and cfg80211 connect command"""
1338 params = { "ssid": "test-wnm",
1341 "bss_transition": "1" }
1342 hapd = hostapd.add_ap(apdev[0], params)
1344 params = { "ssid": "test-wnm",
1347 "bss_transition": "1" }
1348 hapd2 = hostapd.add_ap(apdev[1], params)
1350 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1351 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1353 wpas.scan_for_bss(apdev[1]['bssid'], 2462)
1355 id = wpas.connect("test-wnm", key_mgmt="NONE",
1356 bssid=apdev[0]['bssid'], scan_freq="2412")
1357 wpas.set_network(id, "scan_freq", "")
1358 wpas.set_network(id, "bssid", "")
1360 addr = wpas.own_addr()
1363 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1364 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"):
1365 raise Exception("BSS_TM_REQ command failed")
1366 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1368 raise Exception("No BSS Transition Management Response")
1369 if "status_code=0" not in ev:
1370 raise Exception("BSS transition request was not accepted: " + ev)
1371 if "target_bssid=" + apdev[1]['bssid'] not in ev:
1372 raise Exception("Unexpected target BSS: " + ev)
1373 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
1374 "CTRL-EVENT-DISCONNECTED"], timeout=10)
1376 raise Exception("No reassociation seen")
1377 if "CTRL-EVENT-DISCONNECTED" in ev:
1378 #TODO: Uncomment this once kernel side changes for Connect command
1379 #reassociation are in upstream.
1380 #raise Exception("Unexpected disconnection reported")
1381 logger.info("Unexpected disconnection reported")
1382 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
1384 raise Exception("No reassociation seen")
1385 if apdev[1]['bssid'] not in ev:
1386 raise Exception("Unexpected reassociation target: " + ev)