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