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