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