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