]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_wnm.py
tests: Fix mbo_supp_oper_classes after cfg80211 change
[thirdparty/hostap.git] / tests / hwsim / test_wnm.py
CommitLineData
6435799b 1# WNM tests
554a59bc 2# Copyright (c) 2013-2017, 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
3006241e 17from utils import alloc_fail, fail_test, wait_fail_trigger, HwsimSkip
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
26 dev[0].request("DISCONNECT")
27 dev[0].request("ABORT_SCAN")
28 dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
29 if hapd:
30 hapd.request("DISABLE")
31 if hapd2:
32 hapd2.request("DISABLE")
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)
313 except Exception, 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
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)
346 except Exception, 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
ce4e80ad
JM
421def 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
6435799b
JM
438 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
439 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
7f08b2f9
JM
440 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
441 if ev is None:
442 raise Exception("No connection event received from hostapd")
6435799b 443 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
2de01c9d 444
5fcc8c5c
JM
445def 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
2de01c9d
JM
467MGMT_SUBTYPE_ACTION = 13
468ACTION_CATEG_WNM = 10
469WNM_ACT_BSS_TM_REQ = 7
470WNM_ACT_BSS_TM_RESP = 8
c4082f78
JM
471WNM_ACT_SLEEP_MODE_REQ = 16
472WNM_ACT_SLEEP_MODE_RESP = 17
473WNM_ACT_NOTIFICATION_REQ = 26
474WNM_ACT_NOTIFICATION_RESP = 27
475WNM_NOTIF_TYPE_FW_UPGRADE = 0
476WNM_NOTIF_TYPE_WFA = 1
3006241e 477WLAN_EID_TFS_REQ = 91
c4082f78
JM
478WLAN_EID_TFS_RESP = 92
479WLAN_EID_WNMSLEEP = 93
3006241e
MV
480WLAN_EID_EXTENSION = 255
481WLAN_EID_EXT_OCV_OCI = 54
c4082f78
JM
482WNM_SLEEP_MODE_ENTER = 0
483WNM_SLEEP_MODE_EXIT = 1
484WNM_STATUS_SLEEP_ACCEPT = 0
485WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1
486WNM_STATUS_DENIED_ACTION = 2
487WNM_STATUS_DENIED_TMP = 3
488WNM_STATUS_DENIED_KEY = 4
489WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5
490WNM_SLEEP_SUBELEM_GTK = 0
491WNM_SLEEP_SUBELEM_IGTK = 1
2de01c9d
JM
492
493def 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
506def 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
73360424 537def expect_ack(hapd):
2de01c9d
JM
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
3006241e
MV
544def 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
9fd6804d 553@remote_compatible
2de01c9d
JM
554def test_wnm_bss_tm_req(dev, apdev):
555 """BSS Transition Management Request"""
556 params = { "ssid": "test-wnm", "bss_transition": "1" }
8b8a1864 557 hapd = hostapd.add_ap(apdev[0], params)
2de01c9d 558 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
4fe798bd 559 addr = dev[0].own_addr()
2de01c9d
JM
560
561 hapd.set("ext_mgmt_frame_handling", "1")
562
563 # truncated BSS TM Request
4fe798bd 564 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
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)
73360424 570 expect_ack(hapd)
4fe798bd 571 dev[0].dump_monitor()
2de01c9d
JM
572
573 # no disassociation and no candidate list
4fe798bd 574 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
575 dialog_token=2)
576 hapd.mgmt_tx(req)
577 resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1)
4fe798bd 578 dev[0].dump_monitor()
2de01c9d
JM
579
580 # truncated BSS Termination Duration
4fe798bd 581 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
582 req_mode=0x08)
583 hapd.mgmt_tx(req)
73360424 584 expect_ack(hapd)
4fe798bd 585 dev[0].dump_monitor()
2de01c9d
JM
586
587 # BSS Termination Duration with TSF=0 and Duration=10
4fe798bd 588 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
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)
4fe798bd 593 dev[0].dump_monitor()
2de01c9d
JM
594
595 # truncated Session Information URL
4fe798bd 596 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
597 req_mode=0x10)
598 hapd.mgmt_tx(req)
73360424 599 expect_ack(hapd)
4fe798bd 600 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
601 req_mode=0x10)
602 req['payload'] += struct.pack("<BBB", 3, 65, 66)
603 hapd.mgmt_tx(req)
73360424 604 expect_ack(hapd)
4fe798bd 605 dev[0].dump_monitor()
2de01c9d
JM
606
607 # Session Information URL
4fe798bd 608 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
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)
4fe798bd 613 dev[0].dump_monitor()
2de01c9d
JM
614
615 # Preferred Candidate List without any entries
4fe798bd 616 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
617 req_mode=0x01, dialog_token=5)
618 hapd.mgmt_tx(req)
ab4ee343 619 resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7)
4fe798bd 620 dev[0].dump_monitor()
2de01c9d
JM
621
622 # Preferred Candidate List with a truncated entry
4fe798bd 623 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
624 req_mode=0x01)
625 req['payload'] += struct.pack("<BB", 52, 1)
626 hapd.mgmt_tx(req)
73360424 627 expect_ack(hapd)
4fe798bd 628 dev[0].dump_monitor()
2de01c9d
JM
629
630 # Preferred Candidate List with a too short entry
4fe798bd 631 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
632 req_mode=0x01, dialog_token=6)
633 req['payload'] += struct.pack("<BB", 52, 0)
634 hapd.mgmt_tx(req)
ab4ee343 635 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
4fe798bd 636 dev[0].dump_monitor()
2de01c9d
JM
637
638 # Preferred Candidate List with a non-matching entry
4fe798bd 639 req = bss_tm_req(addr, apdev[0]['bssid'],
2de01c9d
JM
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)
ab4ee343 645 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
4fe798bd 646 dev[0].dump_monitor()
d8e0013e
JM
647
648 # Preferred Candidate List with a truncated subelement
4fe798bd 649 req = bss_tm_req(addr, apdev[0]['bssid'],
d8e0013e
JM
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)
ab4ee343 656 resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7)
4fe798bd 657 dev[0].dump_monitor()
d8e0013e
JM
658
659 # Preferred Candidate List with lots of invalid optional subelements
4fe798bd 660 req = bss_tm_req(addr, apdev[0]['bssid'],
d8e0013e
JM
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)
ab4ee343 674 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
4fe798bd 675 dev[0].dump_monitor()
d8e0013e
JM
676
677 # Preferred Candidate List with lots of valid optional subelements (twice)
4fe798bd 678 req = bss_tm_req(addr, apdev[0]['bssid'],
d8e0013e
JM
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)
ab4ee343 700 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
4fe798bd 701 dev[0].dump_monitor()
519c3f70 702
f1e26f89 703 # Preferred Candidate List followed by vendor element
4fe798bd 704 req = bss_tm_req(addr, apdev[0]['bssid'],
f1e26f89
JM
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)
4fe798bd 713 dev[0].dump_monitor()
f1e26f89 714
9fd6804d 715@remote_compatible
519c3f70
JM
716def test_wnm_bss_keep_alive(dev, apdev):
717 """WNM keep-alive"""
718 params = { "ssid": "test-wnm",
719 "ap_max_inactivity": "1" }
8b8a1864 720 hapd = hostapd.add_ap(apdev[0], params)
519c3f70 721
e61f9087 722 addr = dev[0].p2p_interface_addr()
519c3f70 723 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
e61f9087
JM
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")
13f8d51e
JM
747
748def test_wnm_bss_tm(dev, apdev):
749 """WNM BSS Transition Management"""
750 try:
9d7fdac5
JM
751 hapd = None
752 hapd2 = None
13f8d51e
JM
753 params = { "ssid": "test-wnm",
754 "country_code": "FI",
df4733df 755 "ieee80211d": "1",
13f8d51e
JM
756 "hw_mode": "g",
757 "channel": "1",
758 "bss_transition": "1" }
8b8a1864 759 hapd = hostapd.add_ap(apdev[0], params)
13f8d51e
JM
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",
df4733df 766 "ieee80211d": "1",
13f8d51e
JM
767 "hw_mode": "a",
768 "channel": "36",
769 "bss_transition": "1" }
8b8a1864 770 hapd2 = hostapd.add_ap(apdev[1], params)
13f8d51e
JM
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")
c01de219 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"):
13f8d51e
JM
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)
5f35a5e2 820 dev[0].wait_connected(timeout=15, error="No reassociation seen")
13f8d51e
JM
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)
481fecef
JM
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)
13f8d51e
JM
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:
bc6e3288 860 raise Exception("Unexpected reassociation")
13f8d51e 861 finally:
3a259f07 862 clear_regdom_state(dev, hapd, hapd2)
8cc9bc07 863
d58f4c64
JM
864def 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,
5cf0930f 886 "BSS_TM_REQ " + addr + " url=" + 256*'a',
d58f4c64
JM
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
5cf0930f
JM
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
d58f4c64
JM
907def 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
13a17a77
JM
929def test_wnm_bss_tm_scan_not_needed(dev, apdev):
930 """WNM BSS Transition Management and scan not needed"""
2ca502dc
JM
931 run_wnm_bss_tm_scan_not_needed(dev, apdev)
932
933def 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
937def 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
941def 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
946def 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
951def 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"):
13a17a77
JM
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" }
8b8a1864 963 hapd = hostapd.add_ap(apdev[0], params)
13a17a77
JM
964
965 params = { "ssid": "test-wnm",
966 "country_code": "FI",
967 "ieee80211d": "1",
2ca502dc
JM
968 "hw_mode": hwmode,
969 "channel": channel,
13a17a77 970 "bss_transition": "1" }
2ca502dc
JM
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
8b8a1864 978 hapd2 = hostapd.add_ap(apdev[1], params)
13a17a77 979
2ca502dc 980 dev[0].scan_for_bss(apdev[1]['bssid'], freq)
13a17a77
JM
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")
2ca502dc 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):
13a17a77
JM
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:
3a259f07 1008 clear_regdom_state(dev, hapd, hapd2)
13a17a77
JM
1009
1010def 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" }
8b8a1864 1021 hapd = hostapd.add_ap(apdev[0], params)
13a17a77
JM
1022
1023 params = { "ssid": "test-wnm",
1024 "country_code": "FI",
1025 "ieee80211d": "1",
1026 "hw_mode": "a",
1027 "channel": "36",
1028 "bss_transition": "1" }
8b8a1864 1029 hapd2 = hostapd.add_ap(apdev[1], params)
13a17a77
JM
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:
3a259f07 1061 clear_regdom_state(dev, hapd, hapd2)
13a17a77 1062
622bc51f
JM
1063def 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")
0e947f32
JM
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
622bc51f
JM
1111 dev[0].dump_monitor()
1112 finally:
3a259f07 1113 clear_regdom_state(dev, hapd, hapd2)
622bc51f 1114
133a8b9d 1115def start_wnm_tm(ap, country, dev, country3=None):
8cc9bc07
JM
1116 params = { "ssid": "test-wnm",
1117 "country_code": country,
1118 "ieee80211d": "1",
1119 "hw_mode": "g",
1120 "channel": "1",
1121 "bss_transition": "1" }
133a8b9d
JM
1122 if country3 is not None:
1123 params["country3"] = country3
afc26df2 1124 hapd = hostapd.add_ap(ap, params)
8cc9bc07
JM
1125 id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1126 dev.dump_monitor()
1127 dev.set_network(id, "scan_freq", "")
1128 return hapd, id
1129
1130def stop_wnm_tm(hapd, dev):
1131 dev.request("DISCONNECT")
1132 try:
1133 dev.wait_disconnected()
1134 except:
1135 pass
1136 if hapd:
1137 hapd.request("DISABLE")
1138 subprocess.call(['iw', 'reg', 'set', '00'])
1139 dev.flush_scan_cache()
1140
1141def wnm_bss_tm_check(hapd, dev, data):
1142 addr = dev.p2p_interface_addr()
1143 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " " + data):
1144 raise Exception("BSS_TM_REQ command failed")
1145 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
1146 if ev is None:
1147 raise Exception("No scan started")
1148 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
1149 if ev is None:
1150 raise Exception("Scan did not complete")
1151
1152 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1153 if ev is None:
1154 raise Exception("No BSS Transition Management Response")
1155 if "status_code=7" not in ev:
1156 raise Exception("Unexpected response: " + ev)
1157
1158def test_wnm_bss_tm_country_us(dev, apdev):
1159 """WNM BSS Transition Management (US)"""
1160 try:
1161 hapd = None
1162 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
1163
1164 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1165 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")
1166
1167 # Make the test take less time by limiting full scans
1168 dev[0].set_network(id, "scan_freq", "2412")
1169 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1170 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")
1171
1172 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1173 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")
1174 finally:
1175 stop_wnm_tm(hapd, dev[0])
1176
1177def test_wnm_bss_tm_country_fi(dev, apdev):
1178 """WNM BSS Transition Management (FI)"""
1179 addr = dev[0].p2p_interface_addr()
1180 try:
1181 hapd = None
1182 hapd, id = start_wnm_tm(apdev[0], "FI", dev[0])
1183
1184 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1185 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")
1186
1187 # Make the test take less time by limiting full scans
1188 dev[0].set_network(id, "scan_freq", "2412")
1189 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1190 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")
1191
1192 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1193 wnm_bss_tm_check(hapd, dev[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
1194 finally:
1195 stop_wnm_tm(hapd, dev[0])
1196
1197def test_wnm_bss_tm_country_jp(dev, apdev):
1198 """WNM BSS Transition Management (JP)"""
1199 addr = dev[0].p2p_interface_addr()
1200 try:
1201 hapd = None
1202 hapd, id = start_wnm_tm(apdev[0], "JP", dev[0])
1203
1204 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1205 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")
1206
1207 # Make the test take less time by limiting full scans
1208 dev[0].set_network(id, "scan_freq", "2412")
1209 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1210 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")
1211 finally:
1212 stop_wnm_tm(hapd, dev[0])
1213
1214def test_wnm_bss_tm_country_cn(dev, apdev):
1215 """WNM BSS Transition Management (CN)"""
1216 addr = dev[0].p2p_interface_addr()
1217 try:
1218 hapd = None
1219 hapd, id = start_wnm_tm(apdev[0], "CN", dev[0])
1220
1221 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1222 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")
1223
1224 # Make the test take less time by limiting full scans
1225 dev[0].set_network(id, "scan_freq", "2412")
1226 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1227 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")
1228 finally:
1229 stop_wnm_tm(hapd, dev[0])
1230
1231def test_wnm_bss_tm_global(dev, apdev):
1232 """WNM BSS Transition Management (global)"""
133a8b9d
JM
1233 run_wnm_bss_tm_global(dev, apdev, "XX", None)
1234
1235def test_wnm_bss_tm_global4(dev, apdev):
1236 """WNM BSS Transition Management (global; indicate table E-4)"""
1237 run_wnm_bss_tm_global(dev, apdev, "FI", "0x04")
1238
1239def run_wnm_bss_tm_global(dev, apdev, country, country3):
8cc9bc07
JM
1240 addr = dev[0].p2p_interface_addr()
1241 try:
1242 hapd = None
133a8b9d 1243 hapd, id = start_wnm_tm(apdev[0], country, dev[0], country3=country3)
8cc9bc07
JM
1244
1245 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1246 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")
1247
1248 # Make the test take less time by limiting full scans
1249 dev[0].set_network(id, "scan_freq", "2412")
1250 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1251 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")
1252
1253 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1254 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")
1255 finally:
1256 stop_wnm_tm(hapd, dev[0])
c4082f78 1257
56153620
JM
1258def test_wnm_bss_tm_op_class_0(dev, apdev):
1259 """WNM BSS Transition Management with invalid operating class"""
1260 try:
1261 hapd = None
1262 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
1263
1264 logger.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
1265 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")
1266 finally:
1267 stop_wnm_tm(hapd, dev[0])
1268
ee4b99e7
JM
1269def test_wnm_bss_tm_rsn(dev, apdev):
1270 """WNM BSS Transition Management with RSN"""
1271 try:
1272 hapd = None
1273 hapd2 = None
1274 params = hostapd.wpa2_params(ssid="test-wnm", passphrase="zxcvbnm,.-")
1275 params["country_code"] = "FI"
1276 params["ieee80211d"] = "1"
1277 params["hw_mode"] = "g"
1278 params["channel"] = "1"
1279 params["bss_transition"] = "1"
1280 hapd = hostapd.add_ap(apdev[0], params)
1281
1282 params = hostapd.wpa2_params(ssid="test-wnm", passphrase="zxcvbnm,.-")
1283 params["country_code"] = "FI"
1284 params["ieee80211d"] = "1"
1285 params["hw_mode"] = "a"
1286 params["channel"] = "36"
1287 params["bss_transition"] = "1"
1288 hapd2 = hostapd.add_ap(apdev[1], params)
1289
1290 dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
1291
1292 id = dev[0].connect("test-wnm", psk="zxcvbnm,.-",
1293 bssid=apdev[0]['bssid'], scan_freq="2412")
1294 dev[0].set_network(id, "scan_freq", "")
1295 dev[0].set_network(id, "bssid", "")
1296
1297 addr = dev[0].own_addr()
1298 dev[0].dump_monitor()
1299
1300 time.sleep(0.5)
1301 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1302 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"):
1303 raise Exception("BSS_TM_REQ command failed")
1304 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1305 if ev is None:
1306 raise Exception("No BSS Transition Management Response")
1307 if "status_code=0" not in ev:
1308 raise Exception("BSS transition request was not accepted: " + ev)
1309 if "target_bssid=" + apdev[1]['bssid'] not in ev:
1310 raise Exception("Unexpected target BSS: " + ev)
1311 dev[0].wait_connected(timeout=15, error="No reassociation seen")
1312 if apdev[1]['bssid'] not in ev:
1313 raise Exception("Unexpected reassociation target: " + ev)
1314 finally:
3a259f07 1315 clear_regdom_state(dev, hapd, hapd2)
ee4b99e7 1316
c4082f78
JM
1317def test_wnm_action_proto(dev, apdev):
1318 """WNM Action protocol testing"""
1319 params = { "ssid": "test-wnm" }
8823178c 1320 params['wnm_sleep_mode'] = '1'
8b8a1864 1321 hapd = hostapd.add_ap(apdev[0], params)
c4082f78
JM
1322 bssid = apdev[0]['bssid']
1323 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
8823178c
JM
1324 dev[0].request("WNM_SLEEP enter")
1325 time.sleep(0.1)
c4082f78
JM
1326 hapd.set("ext_mgmt_frame_handling", "1")
1327
1328 msg = {}
1329 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1330 msg['da'] = dev[0].own_addr()
1331 msg['sa'] = bssid
1332 msg['bssid'] = bssid
1333
1334 dialog_token = 1
1335
1336 logger.debug("Unexpected WNM-Notification Response")
1337 # Note: This is actually not registered for user space processing in
1338 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
1339 # it to wpa_supplicant.
1340 msg['payload'] = struct.pack("<BBBB",
1341 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_RESP,
1342 dialog_token, 0)
1343 hapd.mgmt_tx(msg)
1344 expect_ack(hapd)
1345
1346 logger.debug("Truncated WNM-Notification Request (no Type field)")
1347 msg['payload'] = struct.pack("<BBB",
1348 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1349 dialog_token)
1350 hapd.mgmt_tx(msg)
1351 expect_ack(hapd)
1352
1353 logger.debug("WFA WNM-Notification Request with truncated IE (min)")
1354 msg['payload'] = struct.pack("<BBBBBB",
1355 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1356 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 1)
1357 hapd.mgmt_tx(msg)
1358 expect_ack(hapd)
1359
1360 logger.debug("WFA WNM-Notification Request with truncated IE (max)")
1361 msg['payload'] = struct.pack("<BBBBBB",
1362 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1363 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 255)
1364 hapd.mgmt_tx(msg)
1365 expect_ack(hapd)
1366
1367 logger.debug("WFA WNM-Notification Request with too short IE")
1368 msg['payload'] = struct.pack("<BBBBBB",
1369 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1370 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 0)
1371 hapd.mgmt_tx(msg)
1372 expect_ack(hapd)
1373
1374 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
1375 msg['payload'] = struct.pack(">BBBBBBLB",
1376 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1377 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
1378 0x506f9a00, 1)
1379 hapd.mgmt_tx(msg)
1380 expect_ack(hapd)
1381
1382 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
1383 msg['payload'] = struct.pack(">BBBBBBLBB",
1384 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1385 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 6,
1386 0x506f9a00, 1, 0)
1387 hapd.mgmt_tx(msg)
1388 expect_ack(hapd)
1389
1390 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
1391 msg['payload'] = struct.pack(">BBBBBBLB",
1392 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1393 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
1394 0x506f9a00, 0xff)
1395 hapd.mgmt_tx(msg)
1396 expect_ack(hapd)
1397
1398 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
1399 msg['payload'] = struct.pack(">BBBBBBLBHB",
1400 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1401 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
1402 0x506f9a01, 0, 0, 1)
1403 hapd.mgmt_tx(msg)
1404 expect_ack(hapd)
1405
1406 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
1407 msg['payload'] = struct.pack(">BBBBBBLBHB",
1408 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1409 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
1410 0x506f9a01, 0, 0, 0xff)
1411 hapd.mgmt_tx(msg)
1412 expect_ack(hapd)
1413
1414 logger.debug("WFA WNM-Notification Request with unsupported IE")
1415 msg['payload'] = struct.pack("<BBBBBBL",
1416 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1417 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 4, 0)
1418 hapd.mgmt_tx(msg)
1419 expect_ack(hapd)
1420
1421 logger.debug("WNM-Notification Request with unknown WNM-Notification type 0")
1422 msg['payload'] = struct.pack("<BBBB",
1423 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1424 dialog_token, WNM_NOTIF_TYPE_FW_UPGRADE)
1425 hapd.mgmt_tx(msg)
1426 expect_ack(hapd)
1427
1428 logger.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
1429 msg['payload'] = struct.pack("<BB",
1430 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP)
1431 hapd.mgmt_tx(msg)
1432 expect_ack(hapd)
1433
1434 logger.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
1435 msg['payload'] = struct.pack("<BBB",
1436 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0)
1437 hapd.mgmt_tx(msg)
1438 expect_ack(hapd)
1439
1440 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
1441 msg['payload'] = struct.pack("<BBBH",
1442 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1443 1)
1444 hapd.mgmt_tx(msg)
1445 expect_ack(hapd)
1446
1447 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1448 msg['payload'] = struct.pack("<BBBH",
1449 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1450 0xffff)
1451 hapd.mgmt_tx(msg)
1452 expect_ack(hapd)
1453
1454 logger.debug("WNM Sleep Mode Response - truncated IE header")
1455 msg['payload'] = struct.pack("<BBBHB",
1456 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1457 0, 0)
1458 hapd.mgmt_tx(msg)
1459 expect_ack(hapd)
1460
1461 logger.debug("WNM Sleep Mode Response - truncated IE")
1462 msg['payload'] = struct.pack("<BBBHBB",
1463 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1464 0, 0, 1)
1465 hapd.mgmt_tx(msg)
1466 expect_ack(hapd)
1467
1468 logger.debug("WNM Sleep Mode Response - Empty TFS Response")
1469 msg['payload'] = struct.pack("<BBBHBB",
1470 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1471 0, WLAN_EID_TFS_RESP, 0)
1472 hapd.mgmt_tx(msg)
1473 expect_ack(hapd)
1474
1475 logger.debug("WNM Sleep Mode Response - EID 0 not recognized")
1476 msg['payload'] = struct.pack("<BBBHBB",
1477 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1478 0, 0, 0)
1479 hapd.mgmt_tx(msg)
1480 expect_ack(hapd)
1481
1482 logger.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1483 msg['payload'] = struct.pack("<BBBHBBBB",
1484 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1485 0, WLAN_EID_WNMSLEEP, 0, WLAN_EID_TFS_RESP, 0)
1486 hapd.mgmt_tx(msg)
1487 expect_ack(hapd)
1488
1489 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1490 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1491 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1492 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1493 WNM_STATUS_SLEEP_ACCEPT, 0,
1494 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(exit, deny key) 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_EXIT,
1502 WNM_STATUS_DENIED_KEY, 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(enter, 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_ENTER,
1511 WNM_STATUS_DENIED_KEY, 0,
1512 WLAN_EID_TFS_RESP, 0)
1513 hapd.mgmt_tx(msg)
1514 expect_ack(hapd)
1515
9fd6804d 1516@remote_compatible
c4082f78
JM
1517def test_wnm_action_proto_pmf(dev, apdev):
1518 """WNM Action protocol testing (PMF enabled)"""
1519 ssid = "test-wnm-pmf"
1520 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1521 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1522 params["ieee80211w"] = "2"
8823178c 1523 params['wnm_sleep_mode'] = '1'
8b8a1864 1524 hapd = hostapd.add_ap(apdev[0], params)
c4082f78
JM
1525 bssid = apdev[0]['bssid']
1526 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
1527 proto="WPA2", ieee80211w="2", scan_freq="2412")
8823178c
JM
1528 dev[0].request("WNM_SLEEP enter")
1529 time.sleep(0.1)
c4082f78
JM
1530 hapd.set("ext_mgmt_frame_handling", "1")
1531
1532 msg = {}
1533 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1534 msg['da'] = dev[0].own_addr()
1535 msg['sa'] = bssid
1536 msg['bssid'] = bssid
1537
1538 logger.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1539 keydata = struct.pack("<BB", 0, 1)
1540 msg['payload'] = struct.pack("<BBBH",
1541 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1542 len(keydata))
1543 msg['payload'] += keydata
1544 msg['payload'] += struct.pack("<BBBBHBB",
1545 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1546 WNM_STATUS_SLEEP_ACCEPT, 0,
1547 WLAN_EID_TFS_RESP, 0)
1548 hapd.mgmt_tx(msg)
1549 expect_ack(hapd)
1550
1551 logger.debug("WNM Sleep Mode Response - Too short GTK subelem")
1552 keydata = struct.pack("<BB", WNM_SLEEP_SUBELEM_GTK, 0)
1553 msg['payload'] = struct.pack("<BBBH",
1554 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1555 len(keydata))
1556 msg['payload'] += keydata
1557 msg['payload'] += struct.pack("<BBBBHBB",
1558 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1559 WNM_STATUS_SLEEP_ACCEPT, 0,
1560 WLAN_EID_TFS_RESP, 0)
1561 hapd.mgmt_tx(msg)
1562 expect_ack(hapd)
1563
1564 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1565 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1566 0, 17, 0, 0, 0, 0, 0, 0)
1567 msg['payload'] = struct.pack("<BBBH",
1568 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1569 len(keydata))
1570 msg['payload'] += keydata
1571 msg['payload'] += struct.pack("<BBBBHBB",
1572 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1573 WNM_STATUS_SLEEP_ACCEPT, 0,
1574 WLAN_EID_TFS_RESP, 0)
1575 hapd.mgmt_tx(msg)
1576 expect_ack(hapd)
1577
1578 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1579 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1580 0, 0, 0, 0, 0, 0, 0, 0)
1581 msg['payload'] = struct.pack("<BBBH",
1582 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1583 len(keydata))
1584 msg['payload'] += keydata
1585 msg['payload'] += struct.pack("<BBBBHBB",
1586 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1587 WNM_STATUS_SLEEP_ACCEPT, 0,
1588 WLAN_EID_TFS_RESP, 0)
1589 hapd.mgmt_tx(msg)
1590 expect_ack(hapd)
1591
1592 logger.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1593 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1594 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1595 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1596 keydata += struct.pack("<BB", WNM_SLEEP_SUBELEM_IGTK, 0)
1597 msg['payload'] = struct.pack("<BBBH",
1598 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1599 len(keydata))
1600 msg['payload'] += keydata
1601 msg['payload'] += struct.pack("<BBBBHBB",
1602 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1603 WNM_STATUS_SLEEP_ACCEPT, 0,
1604 WLAN_EID_TFS_RESP, 0)
1605 hapd.mgmt_tx(msg)
1606 expect_ack(hapd)
1607
1608 logger.debug("WNM Sleep Mode Response - Unknown subelem")
1609 keydata = struct.pack("<BB", 255, 0)
1610 msg['payload'] = struct.pack("<BBBH",
1611 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1612 len(keydata))
1613 msg['payload'] += keydata
1614 msg['payload'] += struct.pack("<BBBBHBB",
1615 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1616 WNM_STATUS_SLEEP_ACCEPT, 0,
1617 WLAN_EID_TFS_RESP, 0)
1618 hapd.mgmt_tx(msg)
1619 expect_ack(hapd)
63a19e56 1620
9fd6804d 1621@remote_compatible
63a19e56
JM
1622def test_wnm_action_proto_no_pmf(dev, apdev):
1623 """WNM Action protocol testing (PMF disabled)"""
1624 ssid = "test-wnm-no-pmf"
1625 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
8823178c 1626 params['wnm_sleep_mode'] = '1'
8b8a1864 1627 hapd = hostapd.add_ap(apdev[0], params)
63a19e56
JM
1628 bssid = apdev[0]['bssid']
1629 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1630 proto="WPA2", ieee80211w="0", scan_freq="2412")
8823178c
JM
1631 dev[0].request("WNM_SLEEP enter")
1632 time.sleep(0.1)
63a19e56 1633 hapd.set("ext_mgmt_frame_handling", "1")
e22aa2f6
JM
1634 hapd.dump_monitor()
1635 dev[0].request("WNM_SLEEP exit")
1636 ev = hapd.wait_event(['MGMT-RX'], timeout=5)
1637 if ev is None:
1638 raise Exception("WNM-Sleep Mode Request not seen")
63a19e56
JM
1639
1640 msg = {}
1641 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1642 msg['da'] = dev[0].own_addr()
1643 msg['sa'] = bssid
1644 msg['bssid'] = bssid
1645
1646 logger.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1647 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1648 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1649 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1650 keydata += struct.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK, 2 + 6 + 16, 0,
1651 0x10203040, 0x5060,
1652 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1653 msg['payload'] = struct.pack("<BBBH",
1654 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1655 len(keydata))
1656 msg['payload'] += keydata
1657 msg['payload'] += struct.pack("<BBBBHBB",
1658 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1659 WNM_STATUS_SLEEP_ACCEPT, 0,
1660 WLAN_EID_TFS_RESP, 0)
1661 hapd.mgmt_tx(msg)
1662 expect_ack(hapd)
1663
1664 ev = dev[0].wait_event(["WNM: Ignore Key Data"], timeout=5)
1665 if ev is None:
1666 raise Exception("Key Data not ignored")
85cc109e
AS
1667
1668def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev):
1669 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1670 ssid = "test-wnm-mbo"
1671 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
d9037169 1672 params['bss_transition'] = "1"
8b8a1864 1673 hapd = hostapd.add_ap(apdev[0], params)
85cc109e
AS
1674 bssid = apdev[0]['bssid']
1675 if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
0663ae22 1676 raise Exception("Failed to set STA as cellular data capable")
85cc109e
AS
1677
1678 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1679 proto="WPA2", ieee80211w="0", scan_freq="2412")
1680
1681 logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1682 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"):
0663ae22 1683 raise Exception("BSS transition management succeeded unexpectedly")
85cc109e
AS
1684
1685 logger.debug("BTM request with invalid MBO transition reason code")
1686 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"):
0663ae22 1687 raise Exception("BSS transition management succeeded unexpectedly")
85cc109e
AS
1688
1689 logger.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1690 if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
0663ae22 1691 raise Exception("BSS transition management command failed")
85cc109e
AS
1692
1693 ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1694 if ev is None or "preference=1" not in ev:
0663ae22 1695 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
85cc109e
AS
1696
1697 ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1698 if ev is None or "reason=3" not in ev:
0663ae22 1699 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
85cc109e 1700
9a6e2a5e
AO
1701 t0 = datetime.now()
1702
85cc109e
AS
1703 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1704 if ev is None:
0663ae22 1705 raise Exception("No BSS Transition Management Response")
85cc109e 1706 if dev[0].own_addr() not in ev:
0663ae22 1707 raise Exception("Unexpected BSS Transition Management Response address")
85cc109e
AS
1708
1709 ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1710 if ev is None:
0663ae22 1711 raise Exception("Station did not disconnect although disassoc imminent was set")
85cc109e
AS
1712
1713 # Set the scan interval to make dev[0] look for connections
1714 if 'OK' not in dev[0].request("SCAN_INTERVAL 1"):
0663ae22 1715 raise Exception("Failed to set scan interval")
85cc109e 1716
9a6e2a5e
AO
1717 # Wait until connected
1718 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 10)
1719 if ev is None:
1720 raise Exception("Station did not connect")
1721
85cc109e 1722 # Make sure no connection is made during the retry delay
9a6e2a5e
AO
1723 time_diff = datetime.now() - t0
1724 if time_diff.total_seconds() < 5:
0663ae22 1725 raise Exception("Station connected before assoc retry delay was over")
85cc109e 1726
85cc109e 1727 if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
0663ae22 1728 raise Exception("Failed to set STA as cellular data not-capable")
c24c144f 1729
9fd6804d 1730@remote_compatible
c24c144f
JM
1731def test_wnm_bss_transition_mgmt_query(dev, apdev):
1732 """WNM BSS Transition Management query"""
1733 params = { "ssid": "test-wnm",
1734 "bss_transition": "1" }
8b8a1864 1735 hapd = hostapd.add_ap(apdev[0], params)
c24c144f 1736 params = { "ssid": "another" }
8b8a1864 1737 hapd2 = hostapd.add_ap(apdev[1], params)
c24c144f
JM
1738
1739 dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
1740 dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
1741
1742 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1743 dev[0].request("WNM_BSS_QUERY 0 list")
1744
1745 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
1746 timeout=5)
1747 if ev is None:
1748 raise Exception("No BSS Transition Management Request frame seen")
1749
1750 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1751 if ev is None:
1752 raise Exception("No BSS Transition Management Response frame seen")
b495500f 1753
9fd6804d 1754@remote_compatible
b495500f
JM
1755def test_wnm_bss_tm_security_mismatch(dev, apdev):
1756 """WNM BSS Transition Management and security mismatch"""
1757 params = { "ssid": "test-wnm",
1758 "wpa": "2",
1759 "wpa_key_mgmt": "WPA-PSK",
1760 "rsn_pairwise": "CCMP",
1761 "wpa_passphrase": "12345678",
1762 "hw_mode": "g",
1763 "channel": "1",
1764 "bss_transition": "1" }
8b8a1864 1765 hapd = hostapd.add_ap(apdev[0], params)
b495500f
JM
1766
1767 params = { "ssid": "test-wnm",
1768 "hw_mode": "g",
1769 "channel": "11",
1770 "bss_transition": "1" }
8b8a1864 1771 hapd2 = hostapd.add_ap(apdev[1], params)
b495500f
JM
1772
1773 dev[0].scan_for_bss(apdev[1]['bssid'], 2462)
1774
1775 id = dev[0].connect("test-wnm", psk="12345678",
1776 bssid=apdev[0]['bssid'], scan_freq="2412")
1777 dev[0].set_network(id, "scan_freq", "")
1778 dev[0].set_network(id, "bssid", "")
1779
1780 addr = dev[0].own_addr()
1781 dev[0].dump_monitor()
1782
1783 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1784 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"):
1785 raise Exception("BSS_TM_REQ command failed")
1786 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1787 if ev is None:
1788 raise Exception("No BSS Transition Management Response")
1789 if "status_code=7" not in ev:
1790 raise Exception("Unexpected BSS transition request response: " + ev)
fb915d50
JM
1791
1792def test_wnm_bss_tm_connect_cmd(dev, apdev):
1793 """WNM BSS Transition Management and cfg80211 connect command"""
1794 params = { "ssid": "test-wnm",
1795 "hw_mode": "g",
1796 "channel": "1",
1797 "bss_transition": "1" }
8b8a1864 1798 hapd = hostapd.add_ap(apdev[0], params)
fb915d50
JM
1799
1800 params = { "ssid": "test-wnm",
1801 "hw_mode": "g",
1802 "channel": "11",
1803 "bss_transition": "1" }
8b8a1864 1804 hapd2 = hostapd.add_ap(apdev[1], params)
fb915d50
JM
1805
1806 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1807 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1808
1809 wpas.scan_for_bss(apdev[1]['bssid'], 2462)
1810
1811 id = wpas.connect("test-wnm", key_mgmt="NONE",
1812 bssid=apdev[0]['bssid'], scan_freq="2412")
1813 wpas.set_network(id, "scan_freq", "")
1814 wpas.set_network(id, "bssid", "")
1815
1816 addr = wpas.own_addr()
1817 wpas.dump_monitor()
1818
1819 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1820 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"):
1821 raise Exception("BSS_TM_REQ command failed")
1822 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1823 if ev is None:
1824 raise Exception("No BSS Transition Management Response")
1825 if "status_code=0" not in ev:
1826 raise Exception("BSS transition request was not accepted: " + ev)
1827 if "target_bssid=" + apdev[1]['bssid'] not in ev:
1828 raise Exception("Unexpected target BSS: " + ev)
1829 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
1830 "CTRL-EVENT-DISCONNECTED"], timeout=10)
1831 if ev is None:
1832 raise Exception("No reassociation seen")
1833 if "CTRL-EVENT-DISCONNECTED" in ev:
0ed5e946 1834 raise Exception("Unexpected disconnection reported")
fb915d50
JM
1835 if apdev[1]['bssid'] not in ev:
1836 raise Exception("Unexpected reassociation target: " + ev)
7084c4d4
JM
1837
1838def test_wnm_bss_tm_reject(dev, apdev):
1839 """WNM BSS Transition Management request getting rejected"""
1840 try:
1841 hapd = None
1842 params = { "ssid": "test-wnm",
1843 "country_code": "FI",
1844 "ieee80211d": "1",
1845 "hw_mode": "g",
1846 "channel": "1",
1847 "bss_transition": "1" }
1848 hapd = hostapd.add_ap(apdev[0], params)
1849
1850 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1851 addr = dev[0].own_addr()
1852 dev[0].dump_monitor()
1853
1854 if "OK" not in dev[0].request("SET reject_btm_req_reason 123"):
1855 raise Exception("Failed to set reject_btm_req_reason")
1856
1857 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " disassoc_timer=1"):
1858 raise Exception("BSS_TM_REQ command failed")
1859 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1860 if ev is None:
1861 raise Exception("No BSS Transition Management Response")
1862 if addr not in ev:
1863 raise Exception("Unexpected BSS Transition Management Response address")
1864 if "status_code=123" not in ev:
1865 raise Exception("Unexpected BSS Transition Management Response status: " + ev)
1866 dev[0].wait_disconnected()
1867 finally:
1868 dev[0].request("DISCONNECT")
1869 if hapd:
1870 hapd.request("DISABLE")
1871 subprocess.call(['iw', 'reg', 'set', '00'])
1872 dev[0].flush_scan_cache()
5cf2f7b3
JM
1873
1874def test_wnm_bss_tm_ap_proto(dev, apdev):
1875 """WNM BSS TM - protocol testing for AP message parsing"""
1876 params = { "ssid": "test-wnm", "bss_transition": "1" }
1877 hapd = hostapd.add_ap(apdev[0], params)
1878 bssid = hapd.own_addr()
1879 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1880 addr = dev[0].own_addr()
1881
1882 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
1883 hapd.set("ext_mgmt_frame_handling", "1")
1884 tests = [ "0a",
1885 "0a06",
1886 "0a0601",
1887 "0a060100",
1888 "0a080000",
1889 "0a08000000",
1890 "0a080000001122334455",
1891 "0a08000000112233445566",
1892 "0a08000000112233445566112233445566778899",
1893 "0a08ffffff",
1894 "0a08ffffff112233445566778899",
1895 "0a1a",
1896 "0a1a00",
1897 "0a1a0000",
1898 "0aff" ]
1899 for t in tests:
1900 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1901 raise Exception("MGMT_RX_PROCESS failed")
1902
1903 hapd.set("ext_mgmt_frame_handling", "0")
be607ceb
AS
1904
1905def test_wnm_bss_transition_mgmt_query_with_unknown_candidates(dev, apdev):
1906 """WNM BSS Transition Management query with unknown candidates"""
1907 params = { "ssid": "test-wnm",
1908 "bss_transition": "1" }
1909 hapd = hostapd.add_ap(apdev[0], params)
1910
1911 dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
1912
1913 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1914 dev[0].request("WNM_BSS_QUERY 0 neighbor=00:11:22:33:44:55,0,81,1,4")
1915
1916 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
1917 timeout=5)
1918 if ev is None:
1919 raise Exception("No BSS Transition Management Request frame seen")
1920
1921 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1922 if ev is None:
1923 raise Exception("No BSS Transition Management Response frame seen")
5fb016a2
JM
1924
1925def test_wnm_time_adv_without_time_zone(dev, apdev):
1926 """WNM Time Advertisement without time zone configuration"""
1927 params = { "ssid": "test-wnm",
1928 "time_advertisement": "2" }
1929 hostapd.add_ap(apdev[0], params)
1930
1931 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
21895884
JM
1932
1933def test_wnm_coloc_intf_reporting(dev, apdev):
1934 """WNM Collocated Interference Reporting"""
1935 params = { "ssid": "test-wnm",
1936 "coloc_intf_reporting": "1" }
1937 hapd = hostapd.add_ap(apdev[0], params)
1938
1939 no_intf = struct.pack("<BBBBBLLLLH", 96, 21, 0, 127, 0x0f, 0, 0, 0, 0, 0)
1940
1941 try:
1942 dev[0].set("coloc_intf_reporting", "1")
1943 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1944 addr = dev[0].own_addr()
1945 if "OK" not in hapd.request("COLOC_INTF_REQ %s 1 5" % addr):
1946 raise Exception("Could not send Collocated Interference Request")
1947 ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2)
1948 if ev is None:
1949 raise Exception("No Collocated Interference Request frame seen")
1950 vals = ev.split(' ')
1951 if vals[2] != '1' or vals[3] != '5':
1952 raise Exception("Unexpected request values: " + ev)
1953 dev[0].set("coloc_intf_elems", binascii.hexlify(no_intf))
1954 ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1)
1955 if ev is None:
1956 raise Exception("No Collocated Interference Report frame seen")
1957 if addr + " 1 " + binascii.hexlify(no_intf) not in ev:
1958 raise Exception("Unexpected report values: " + ev)
1959
1960 if "OK" not in hapd.request("COLOC_INTF_REQ %s 0 0" % addr):
1961 raise Exception("Could not send Collocated Interference Request")
1962 ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2)
1963 if ev is None:
1964 raise Exception("No Collocated Interference Request frame seen")
1965 vals = ev.split(' ')
1966 if vals[2] != '0' or vals[3] != '0':
1967 raise Exception("Unexpected request values: " + ev)
1968
1969 res = dev[0].request("COLOC_INTF_REPORT " + binascii.hexlify(no_intf))
1970 if "OK" not in res:
1971 raise Exception("Could not send unsolicited report")
1972 ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1)
1973 if ev is None:
1974 raise Exception("No Collocated Interference Report frame seen")
1975 if addr + " 0 " + binascii.hexlify(no_intf) not in ev:
1976 raise Exception("Unexpected report values: " + ev)
1977 finally:
1978 dev[0].set("coloc_intf_reporting", "0")
1979 dev[0].set("coloc_intf_elems", "")