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