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