2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
11 logger
= logging
.getLogger()
15 from wpasupplicant
import WpaSupplicant
16 from utils
import alloc_fail
, wait_fail_trigger
17 from wlantest
import Wlantest
19 def test_wnm_bss_transition_mgmt(dev
, apdev
):
20 """WNM BSS Transition Management"""
21 params
= { "ssid": "test-wnm",
22 "time_advertisement": "2",
24 "wnm_sleep_mode": "1",
25 "bss_transition": "1" }
26 hostapd
.add_ap(apdev
[0], params
)
28 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
29 dev
[0].request("WNM_BSS_QUERY 0")
31 def test_wnm_disassoc_imminent(dev
, apdev
):
32 """WNM Disassociation Imminent"""
33 params
= { "ssid": "test-wnm",
34 "time_advertisement": "2",
36 "wnm_sleep_mode": "1",
37 "bss_transition": "1" }
38 hostapd
.add_ap(apdev
[0], params
)
39 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
41 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
42 addr
= dev
[0].p2p_interface_addr()
43 hapd
.request("DISASSOC_IMMINENT " + addr
+ " 10")
44 ev
= dev
[0].wait_event(["WNM: Disassociation Imminent"])
46 raise Exception("Timeout while waiting for disassociation imminent")
47 if "Disassociation Timer 10" not in ev
:
48 raise Exception("Unexpected disassociation imminent contents")
49 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
51 raise Exception("Timeout while waiting for re-connection scan")
53 def test_wnm_ess_disassoc_imminent(dev
, apdev
):
54 """WNM ESS Disassociation Imminent"""
55 params
= { "ssid": "test-wnm",
56 "time_advertisement": "2",
58 "wnm_sleep_mode": "1",
59 "bss_transition": "1" }
60 hostapd
.add_ap(apdev
[0], params
)
61 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
63 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
64 addr
= dev
[0].p2p_interface_addr()
65 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
66 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
68 raise Exception("Timeout while waiting for ESS disassociation imminent")
69 if "0 1024 http://example.com/session-info" not in ev
:
70 raise Exception("Unexpected ESS disassociation imminent message contents")
71 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
73 raise Exception("Timeout while waiting for re-connection scan")
75 def test_wnm_ess_disassoc_imminent_pmf(dev
, apdev
):
76 """WNM ESS Disassociation Imminent"""
77 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
78 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256";
79 params
["ieee80211w"] = "2";
80 params
["bss_transition"] = "1"
81 hostapd
.add_ap(apdev
[0], params
)
82 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
84 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
85 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
86 addr
= dev
[0].p2p_interface_addr()
87 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
88 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
90 raise Exception("Timeout while waiting for ESS disassociation imminent")
91 if "1 1024 http://example.com/session-info" not in ev
:
92 raise Exception("Unexpected ESS disassociation imminent message contents")
93 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
95 raise Exception("Timeout while waiting for re-connection scan")
97 def check_wnm_sleep_mode_enter_exit(hapd
, dev
, interval
=None, tfs_req
=None):
98 addr
= dev
.p2p_interface_addr()
99 sta
= hapd
.get_sta(addr
)
100 if "[WNM_SLEEP_MODE]" in sta
['flags']:
101 raise Exception("Station unexpectedly in WNM-Sleep Mode")
103 logger
.info("Going to WNM Sleep Mode")
105 if interval
is not None:
106 extra
+= " interval=" + str(interval
)
108 extra
+= " tfs_req=" + tfs_req
109 if "OK" not in dev
.request("WNM_SLEEP enter" + extra
):
110 raise Exception("WNM_SLEEP failed")
114 sta
= hapd
.get_sta(addr
)
115 if "[WNM_SLEEP_MODE]" in sta
['flags']:
119 raise Exception("Station failed to enter WNM-Sleep Mode")
121 logger
.info("Waking up from WNM Sleep Mode")
123 dev
.request("WNM_SLEEP exit")
126 sta
= hapd
.get_sta(addr
)
127 if "[WNM_SLEEP_MODE]" not in sta
['flags']:
131 raise Exception("Station failed to exit WNM-Sleep Mode")
133 def test_wnm_sleep_mode_open(dev
, apdev
):
134 """WNM Sleep Mode - open"""
135 params
= { "ssid": "test-wnm",
136 "time_advertisement": "2",
138 "wnm_sleep_mode": "1",
139 "bss_transition": "1" }
140 hostapd
.add_ap(apdev
[0], params
)
141 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
143 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
144 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
146 raise Exception("No connection event received from hostapd")
147 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
148 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], interval
=100)
149 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], tfs_req
="5b17010001130e110000071122334455661122334455661234")
152 "exit tfs_req=123 interval=10",
153 "enter tfs_req=qq interval=10" ]
155 if "FAIL" not in dev
[0].request("WNM_SLEEP " + cmd
):
156 raise Exception("Invalid WNM_SLEEP accepted")
158 def test_wnm_sleep_mode_rsn(dev
, apdev
):
159 """WNM Sleep Mode - RSN"""
160 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
161 params
["time_advertisement"] = "2"
162 params
["time_zone"] = "EST5"
163 params
["wnm_sleep_mode"] = "1"
164 params
["bss_transition"] = "1"
165 hostapd
.add_ap(apdev
[0], params
)
166 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
168 dev
[0].connect("test-wnm-rsn", psk
="12345678", scan_freq
="2412")
169 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
171 raise Exception("No connection event received from hostapd")
172 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
174 def test_wnm_sleep_mode_ap_oom(dev
, apdev
):
175 """WNM Sleep Mode - AP side OOM"""
176 params
= { "ssid": "test-wnm",
177 "wnm_sleep_mode": "1" }
178 hapd
= hostapd
.add_ap(apdev
[0], params
)
180 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
181 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
183 raise Exception("No connection event received from hostapd")
184 with
alloc_fail(hapd
, 1, "ieee802_11_send_wnmsleep_resp"):
185 dev
[0].request("WNM_SLEEP enter")
186 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
187 with
alloc_fail(hapd
, 2, "ieee802_11_send_wnmsleep_resp"):
188 dev
[0].request("WNM_SLEEP exit")
189 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
191 def test_wnm_sleep_mode_rsn_pmf(dev
, apdev
):
192 """WNM Sleep Mode - RSN with PMF"""
195 wt
.add_passphrase("12345678")
196 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
197 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256";
198 params
["ieee80211w"] = "2";
199 params
["time_advertisement"] = "2"
200 params
["time_zone"] = "EST5"
201 params
["wnm_sleep_mode"] = "1"
202 params
["bss_transition"] = "1"
203 hostapd
.add_ap(apdev
[0], params
)
204 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
206 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
207 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
208 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
210 raise Exception("No connection event received from hostapd")
211 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
213 MGMT_SUBTYPE_ACTION
= 13
214 ACTION_CATEG_WNM
= 10
215 WNM_ACT_BSS_TM_REQ
= 7
216 WNM_ACT_BSS_TM_RESP
= 8
217 WNM_ACT_SLEEP_MODE_REQ
= 16
218 WNM_ACT_SLEEP_MODE_RESP
= 17
219 WNM_ACT_NOTIFICATION_REQ
= 26
220 WNM_ACT_NOTIFICATION_RESP
= 27
221 WNM_NOTIF_TYPE_FW_UPGRADE
= 0
222 WNM_NOTIF_TYPE_WFA
= 1
223 WLAN_EID_TFS_RESP
= 92
224 WLAN_EID_WNMSLEEP
= 93
225 WNM_SLEEP_MODE_ENTER
= 0
226 WNM_SLEEP_MODE_EXIT
= 1
227 WNM_STATUS_SLEEP_ACCEPT
= 0
228 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE
= 1
229 WNM_STATUS_DENIED_ACTION
= 2
230 WNM_STATUS_DENIED_TMP
= 3
231 WNM_STATUS_DENIED_KEY
= 4
232 WNM_STATUS_DENIED_OTHER_WNM_SERVICE
= 5
233 WNM_SLEEP_SUBELEM_GTK
= 0
234 WNM_SLEEP_SUBELEM_IGTK
= 1
236 def bss_tm_req(dst
, src
, dialog_token
=1, req_mode
=0, disassoc_timer
=0,
237 validity_interval
=1):
239 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
243 msg
['payload'] = struct
.pack("<BBBBHB",
244 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
245 dialog_token
, req_mode
, disassoc_timer
,
249 def rx_bss_tm_resp(hapd
, expect_dialog
=None, expect_status
=None):
250 for i
in range(0, 100):
251 resp
= hapd
.mgmt_rx()
253 raise Exception("No BSS TM Response received")
254 if resp
['subtype'] == MGMT_SUBTYPE_ACTION
:
257 raise Exception("Not an Action frame")
258 payload
= resp
['payload']
259 if len(payload
) < 2 + 3:
260 raise Exception("Too short payload")
261 (category
, action
) = struct
.unpack('BB', payload
[0:2])
262 if category
!= ACTION_CATEG_WNM
or action
!= WNM_ACT_BSS_TM_RESP
:
263 raise Exception("Not a BSS TM Response")
265 (dialog
, status
, bss_term_delay
) = struct
.unpack('BBB', pos
[0:3])
266 resp
['dialog'] = dialog
267 resp
['status'] = status
268 resp
['bss_term_delay'] = bss_term_delay
270 if len(pos
) >= 6 and status
== 0:
271 resp
['target_bssid'] = binascii
.hexlify(pos
[0:6])
273 resp
['candidates'] = pos
274 if expect_dialog
is not None and dialog
!= expect_dialog
:
275 raise Exception("Unexpected dialog token")
276 if expect_status
is not None and status
!= expect_status
:
277 raise Exception("Unexpected status code %d" % status
)
280 def expect_ack(hapd
):
281 ev
= hapd
.wait_event(["MGMT-TX-STATUS"], timeout
=5)
283 raise Exception("Missing TX status")
285 raise Exception("Action frame not acknowledged")
287 def test_wnm_bss_tm_req(dev
, apdev
):
288 """BSS Transition Management Request"""
289 params
= { "ssid": "test-wnm", "bss_transition": "1" }
290 hapd
= hostapd
.add_ap(apdev
[0], params
)
291 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
292 hapd2
= hostapd
.add_ap(apdev
[1], params
)
294 hapd
.set("ext_mgmt_frame_handling", "1")
296 # truncated BSS TM Request
297 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
299 req
['payload'] = struct
.pack("<BBBBH",
300 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
305 # no disassociation and no candidate list
306 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
309 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=2, expect_status
=1)
311 # truncated BSS Termination Duration
312 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
317 # BSS Termination Duration with TSF=0 and Duration=10
318 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
319 req_mode
=0x08, dialog_token
=3)
320 req
['payload'] += struct
.pack("<BBQH", 4, 10, 0, 10)
322 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=3, expect_status
=1)
324 # truncated Session Information URL
325 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
329 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
331 req
['payload'] += struct
.pack("<BBB", 3, 65, 66)
335 # Session Information URL
336 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
337 req_mode
=0x10, dialog_token
=4)
338 req
['payload'] += struct
.pack("<BBB", 2, 65, 66)
340 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=4, expect_status
=0)
342 # Preferred Candidate List without any entries
343 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
344 req_mode
=0x01, dialog_token
=5)
346 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=5, expect_status
=7)
348 # Preferred Candidate List with a truncated entry
349 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
351 req
['payload'] += struct
.pack("<BB", 52, 1)
355 # Preferred Candidate List with a too short entry
356 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
357 req_mode
=0x01, dialog_token
=6)
358 req
['payload'] += struct
.pack("<BB", 52, 0)
360 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
362 # Preferred Candidate List with a non-matching entry
363 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
364 req_mode
=0x01, dialog_token
=6)
365 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13,
369 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
371 # Preferred Candidate List with a truncated subelement
372 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
373 req_mode
=0x01, dialog_token
=7)
374 req
['payload'] += struct
.pack("<BB6BLBBBBB", 52, 13 + 2,
379 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=7, expect_status
=7)
381 # Preferred Candidate List with lots of invalid optional subelements
382 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
383 req_mode
=0x01, dialog_token
=8)
384 subelems
= struct
.pack("<BBHB", 1, 3, 0, 100)
385 subelems
+= struct
.pack("<BBB", 2, 1, 65)
386 subelems
+= struct
.pack("<BB", 3, 0)
387 subelems
+= struct
.pack("<BBQB", 4, 9, 0, 10)
388 subelems
+= struct
.pack("<BBHLB", 5, 7, 0, 0, 0)
389 subelems
+= struct
.pack("<BB", 66, 0)
390 subelems
+= struct
.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
391 subelems
+= struct
.pack("<BB", 71, 0)
392 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
394 0, 81, 1, 7) + subelems
396 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
398 # Preferred Candidate List with lots of valid optional subelements (twice)
399 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
400 req_mode
=0x01, dialog_token
=8)
402 subelems
= struct
.pack("<BBHH", 1, 4, 0, 100)
403 # Condensed Country String
404 subelems
+= struct
.pack("<BBBB", 2, 2, 65, 66)
405 # BSS Transition Candidate Preference
406 subelems
+= struct
.pack("<BBB", 3, 1, 100)
407 # BSS Termination Duration
408 subelems
+= struct
.pack("<BBQH", 4, 10, 0, 10)
410 subelems
+= struct
.pack("<BBHLH", 5, 8, 0, 0, 0)
411 # Measurement Pilot Transmission
412 subelems
+= struct
.pack("<BBBBB", 66, 3, 0, 0, 0)
413 # RM Enabled Capabilities
414 subelems
+= struct
.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
416 subelems
+= struct
.pack("<BBBB", 71, 2, 0, 0)
417 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
) * 2,
419 0, 81, 1, 7) + subelems
+ subelems
421 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
423 # Preferred Candidate List followed by vendor element
424 req
= bss_tm_req(dev
[0].p2p_interface_addr(), apdev
[0]['bssid'],
425 req_mode
=0x01, dialog_token
=8)
427 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
429 0, 81, 1, 7) + subelems
430 req
['payload'] += binascii
.unhexlify("DD0411223344")
432 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
434 def test_wnm_bss_keep_alive(dev
, apdev
):
436 params
= { "ssid": "test-wnm",
437 "ap_max_inactivity": "1" }
438 hapd
= hostapd
.add_ap(apdev
[0], params
)
440 addr
= dev
[0].p2p_interface_addr()
441 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
442 start
= hapd
.get_sta(addr
)
443 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=2)
445 raise Exception("Unexpected disconnection")
446 end
= hapd
.get_sta(addr
)
447 if int(end
['rx_packets']) <= int(start
['rx_packets']):
448 raise Exception("No keep-alive packets received")
450 # Disable client keep-alive so that hostapd will verify connection
452 dev
[0].request("SET no_keep_alive 1")
454 sta
= hapd
.get_sta(addr
)
455 logger
.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta
['timeout_next'], sta
['rx_packets'], sta
['tx_packets']))
456 if i
> 1 and sta
['timeout_next'] != "NULLFUNC POLL" and int(sta
['tx_packets']) > int(end
['tx_packets']):
458 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
460 raise Exception("Unexpected disconnection (client poll expected)")
462 dev
[0].request("SET no_keep_alive 0")
463 if int(sta
['tx_packets']) <= int(end
['tx_packets']):
464 raise Exception("No client poll packet seen")
466 def test_wnm_bss_tm(dev
, apdev
):
467 """WNM BSS Transition Management"""
471 params
= { "ssid": "test-wnm",
472 "country_code": "FI",
476 "bss_transition": "1" }
477 hapd
= hostapd
.add_ap(apdev
[0], params
)
479 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
480 dev
[0].set_network(id, "scan_freq", "")
482 params
= { "ssid": "test-wnm",
483 "country_code": "FI",
487 "bss_transition": "1" }
488 hapd2
= hostapd
.add_ap(apdev
[1], params
)
490 addr
= dev
[0].p2p_interface_addr()
491 dev
[0].dump_monitor()
493 logger
.info("No neighbor list entries")
494 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
):
495 raise Exception("BSS_TM_REQ command failed")
496 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
498 raise Exception("No BSS Transition Management Response")
500 raise Exception("Unexpected BSS Transition Management Response address")
501 if "status_code=0" in ev
:
502 raise Exception("BSS transition accepted unexpectedly")
503 dev
[0].dump_monitor()
505 logger
.info("Neighbor list entry, but not claimed as Preferred Candidate List")
506 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
507 raise Exception("BSS_TM_REQ command failed")
508 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
510 raise Exception("No BSS Transition Management Response")
511 if "status_code=0" in ev
:
512 raise Exception("BSS transition accepted unexpectedly")
513 dev
[0].dump_monitor()
515 logger
.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
516 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"):
517 raise Exception("BSS_TM_REQ command failed")
518 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
520 raise Exception("No BSS Transition Management Response")
521 if "status_code=0" in ev
:
522 raise Exception("BSS transition accepted unexpectedly")
523 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
525 raise Exception("No scan started")
526 dev
[0].dump_monitor()
528 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
529 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"):
530 raise Exception("BSS_TM_REQ command failed")
531 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
533 raise Exception("No BSS Transition Management Response")
534 if "status_code=0" not in ev
:
535 raise Exception("BSS transition request was not accepted: " + ev
)
536 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
537 raise Exception("Unexpected target BSS: " + ev
)
538 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
539 if apdev
[1]['bssid'] not in ev
:
540 raise Exception("Unexpected reassociation target: " + ev
)
541 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
543 raise Exception("Unexpected scan started")
544 dev
[0].dump_monitor()
546 logger
.info("Preferred Candidate List with two matches, no roam needed")
547 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"):
548 raise Exception("BSS_TM_REQ command failed")
549 ev
= hapd2
.wait_event(['BSS-TM-RESP'], timeout
=10)
551 raise Exception("No BSS Transition Management Response")
552 if "status_code=0" not in ev
:
553 raise Exception("BSS transition request was not accepted: " + ev
)
554 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
555 raise Exception("Unexpected target BSS: " + ev
)
556 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
558 raise Exception("Unexpected scan started")
559 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=0.5)
561 raise Exception("Unexpected reassociation");
563 dev
[0].request("DISCONNECT")
565 hapd
.request("DISABLE")
567 hapd2
.request("DISABLE")
568 subprocess
.call(['iw', 'reg', 'set', '00'])
569 dev
[0].flush_scan_cache()
571 def test_wnm_bss_tm_scan_not_needed(dev
, apdev
):
572 """WNM BSS Transition Management and scan not needed"""
573 run_wnm_bss_tm_scan_not_needed(dev
, apdev
)
575 def test_wnm_bss_tm_nei_vht(dev
, apdev
):
576 """WNM BSS Transition Management and VHT neighbor"""
577 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, vht
=True, nei_info
="115,36,9")
579 def test_wnm_bss_tm_nei_11a(dev
, apdev
):
580 """WNM BSS Transition Management and 11a neighbor"""
581 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, nei_info
="115,36,4")
583 def test_wnm_bss_tm_nei_11g(dev
, apdev
):
584 """WNM BSS Transition Management and 11g neighbor"""
585 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='g',
586 channel
='2', freq
=2417, nei_info
="81,2,6")
588 def test_wnm_bss_tm_nei_11b(dev
, apdev
):
589 """WNM BSS Transition Management and 11g neighbor"""
590 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='b',
591 channel
='3', freq
=2422, nei_info
="81,2,5")
593 def run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=True, vht
=False, hwmode
='a',
594 channel
='36', freq
=5180,
595 nei_info
="115,36,7,0301ff"):
599 params
= { "ssid": "test-wnm",
600 "country_code": "FI",
604 "bss_transition": "1" }
605 hapd
= hostapd
.add_ap(apdev
[0], params
)
607 params
= { "ssid": "test-wnm",
608 "country_code": "FI",
612 "bss_transition": "1" }
614 params
['ieee80211n'] = '0'
616 params
['ieee80211ac'] = "1"
617 params
["vht_oper_chwidth"] = "0"
618 params
["vht_oper_centr_freq_seg0_idx"] = "0"
620 hapd2
= hostapd
.add_ap(apdev
[1], params
)
622 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
)
624 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
625 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
626 dev
[0].set_network(id, "scan_freq", "")
627 dev
[0].set_network(id, "bssid", "")
629 addr
= dev
[0].own_addr()
630 dev
[0].dump_monitor()
632 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
633 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000," + nei_info
):
634 raise Exception("BSS_TM_REQ command failed")
635 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
637 raise Exception("No BSS Transition Management Response")
638 if "status_code=0" not in ev
:
639 raise Exception("BSS transition request was not accepted: " + ev
)
640 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
641 raise Exception("Unexpected target BSS: " + ev
)
642 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
643 if apdev
[1]['bssid'] not in ev
:
644 raise Exception("Unexpected reassociation target: " + ev
)
645 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
647 raise Exception("Unexpected scan started")
648 dev
[0].dump_monitor()
650 dev
[0].request("DISCONNECT")
652 hapd
.request("DISABLE")
654 hapd2
.request("DISABLE")
655 subprocess
.call(['iw', 'reg', 'set', '00'])
656 dev
[0].flush_scan_cache()
658 def test_wnm_bss_tm_scan_needed(dev
, apdev
):
659 """WNM BSS Transition Management and scan needed"""
663 params
= { "ssid": "test-wnm",
664 "country_code": "FI",
668 "bss_transition": "1" }
669 hapd
= hostapd
.add_ap(apdev
[0], params
)
671 params
= { "ssid": "test-wnm",
672 "country_code": "FI",
676 "bss_transition": "1" }
677 hapd2
= hostapd
.add_ap(apdev
[1], params
)
679 dev
[0].scan_for_bss(apdev
[1]['bssid'], 5180)
681 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
682 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
683 dev
[0].set_network(id, "scan_freq", "")
684 dev
[0].set_network(id, "bssid", "")
686 addr
= dev
[0].own_addr()
687 dev
[0].dump_monitor()
689 logger
.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
691 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
692 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"):
693 raise Exception("BSS_TM_REQ command failed")
694 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
696 raise Exception("No BSS Transition Management Response")
697 if "status_code=0" not in ev
:
698 raise Exception("BSS transition request was not accepted: " + ev
)
699 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
700 raise Exception("Unexpected target BSS: " + ev
)
701 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
702 if apdev
[1]['bssid'] not in ev
:
703 raise Exception("Unexpected reassociation target: " + ev
)
704 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
706 raise Exception("Unexpected scan started")
707 dev
[0].dump_monitor()
709 dev
[0].request("DISCONNECT")
711 hapd
.request("DISABLE")
713 hapd2
.request("DISABLE")
714 subprocess
.call(['iw', 'reg', 'set', '00'])
715 dev
[0].flush_scan_cache()
717 def start_wnm_tm(ap
, country
, dev
):
718 params
= { "ssid": "test-wnm",
719 "country_code": country
,
723 "bss_transition": "1" }
724 hapd
= hostapd
.add_ap(ap
['ifname'], params
)
725 id = dev
.connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
727 dev
.set_network(id, "scan_freq", "")
730 def stop_wnm_tm(hapd
, dev
):
731 dev
.request("DISCONNECT")
733 dev
.wait_disconnected()
737 hapd
.request("DISABLE")
738 subprocess
.call(['iw', 'reg', 'set', '00'])
739 dev
.flush_scan_cache()
741 def wnm_bss_tm_check(hapd
, dev
, data
):
742 addr
= dev
.p2p_interface_addr()
743 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " " + data
):
744 raise Exception("BSS_TM_REQ command failed")
745 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
747 raise Exception("No scan started")
748 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
750 raise Exception("Scan did not complete")
752 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
754 raise Exception("No BSS Transition Management Response")
755 if "status_code=7" not in ev
:
756 raise Exception("Unexpected response: " + ev
)
758 def test_wnm_bss_tm_country_us(dev
, apdev
):
759 """WNM BSS Transition Management (US)"""
762 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
764 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
765 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")
767 # Make the test take less time by limiting full scans
768 dev
[0].set_network(id, "scan_freq", "2412")
769 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
770 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")
772 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
773 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")
775 stop_wnm_tm(hapd
, dev
[0])
777 def test_wnm_bss_tm_country_fi(dev
, apdev
):
778 """WNM BSS Transition Management (FI)"""
779 addr
= dev
[0].p2p_interface_addr()
782 hapd
, id = start_wnm_tm(apdev
[0], "FI", dev
[0])
784 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
785 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")
787 # Make the test take less time by limiting full scans
788 dev
[0].set_network(id, "scan_freq", "2412")
789 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
790 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")
792 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
793 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
795 stop_wnm_tm(hapd
, dev
[0])
797 def test_wnm_bss_tm_country_jp(dev
, apdev
):
798 """WNM BSS Transition Management (JP)"""
799 addr
= dev
[0].p2p_interface_addr()
802 hapd
, id = start_wnm_tm(apdev
[0], "JP", dev
[0])
804 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
805 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")
807 # Make the test take less time by limiting full scans
808 dev
[0].set_network(id, "scan_freq", "2412")
809 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
810 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")
812 stop_wnm_tm(hapd
, dev
[0])
814 def test_wnm_bss_tm_country_cn(dev
, apdev
):
815 """WNM BSS Transition Management (CN)"""
816 addr
= dev
[0].p2p_interface_addr()
819 hapd
, id = start_wnm_tm(apdev
[0], "CN", dev
[0])
821 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
822 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")
824 # Make the test take less time by limiting full scans
825 dev
[0].set_network(id, "scan_freq", "2412")
826 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
827 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")
829 stop_wnm_tm(hapd
, dev
[0])
831 def test_wnm_bss_tm_global(dev
, apdev
):
832 """WNM BSS Transition Management (global)"""
833 addr
= dev
[0].p2p_interface_addr()
836 hapd
, id = start_wnm_tm(apdev
[0], "XX", dev
[0])
838 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
839 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")
841 # Make the test take less time by limiting full scans
842 dev
[0].set_network(id, "scan_freq", "2412")
843 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
844 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")
846 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
847 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")
849 stop_wnm_tm(hapd
, dev
[0])
851 def test_wnm_bss_tm_op_class_0(dev
, apdev
):
852 """WNM BSS Transition Management with invalid operating class"""
855 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
857 logger
.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
858 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")
860 stop_wnm_tm(hapd
, dev
[0])
862 def test_wnm_action_proto(dev
, apdev
):
863 """WNM Action protocol testing"""
864 params
= { "ssid": "test-wnm" }
865 params
['wnm_sleep_mode'] = '1'
866 hapd
= hostapd
.add_ap(apdev
[0], params
)
867 bssid
= apdev
[0]['bssid']
868 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
869 dev
[0].request("WNM_SLEEP enter")
871 hapd
.set("ext_mgmt_frame_handling", "1")
874 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
875 msg
['da'] = dev
[0].own_addr()
881 logger
.debug("Unexpected WNM-Notification Response")
882 # Note: This is actually not registered for user space processing in
883 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
884 # it to wpa_supplicant.
885 msg
['payload'] = struct
.pack("<BBBB",
886 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_RESP
,
891 logger
.debug("Truncated WNM-Notification Request (no Type field)")
892 msg
['payload'] = struct
.pack("<BBB",
893 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
898 logger
.debug("WFA WNM-Notification Request with truncated IE (min)")
899 msg
['payload'] = struct
.pack("<BBBBBB",
900 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
901 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 1)
905 logger
.debug("WFA WNM-Notification Request with truncated IE (max)")
906 msg
['payload'] = struct
.pack("<BBBBBB",
907 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
908 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 255)
912 logger
.debug("WFA WNM-Notification Request with too short IE")
913 msg
['payload'] = struct
.pack("<BBBBBB",
914 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
915 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 0)
919 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
920 msg
['payload'] = struct
.pack(">BBBBBBLB",
921 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
922 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
927 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
928 msg
['payload'] = struct
.pack(">BBBBBBLBB",
929 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
930 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 6,
935 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
936 msg
['payload'] = struct
.pack(">BBBBBBLB",
937 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
938 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
943 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
944 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
945 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
946 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
951 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
952 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
953 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
954 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
955 0x506f9a01, 0, 0, 0xff)
959 logger
.debug("WFA WNM-Notification Request with unsupported IE")
960 msg
['payload'] = struct
.pack("<BBBBBBL",
961 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
962 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 4, 0)
966 logger
.debug("WNM-Notification Request with unknown WNM-Notification type 0")
967 msg
['payload'] = struct
.pack("<BBBB",
968 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
969 dialog_token
, WNM_NOTIF_TYPE_FW_UPGRADE
)
973 logger
.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
974 msg
['payload'] = struct
.pack("<BB",
975 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
)
979 logger
.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
980 msg
['payload'] = struct
.pack("<BBB",
981 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0)
985 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
986 msg
['payload'] = struct
.pack("<BBBH",
987 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
992 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
993 msg
['payload'] = struct
.pack("<BBBH",
994 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
999 logger
.debug("WNM Sleep Mode Response - truncated IE header")
1000 msg
['payload'] = struct
.pack("<BBBHB",
1001 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1006 logger
.debug("WNM Sleep Mode Response - truncated IE")
1007 msg
['payload'] = struct
.pack("<BBBHBB",
1008 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1013 logger
.debug("WNM Sleep Mode Response - Empty TFS Response")
1014 msg
['payload'] = struct
.pack("<BBBHBB",
1015 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1016 0, WLAN_EID_TFS_RESP
, 0)
1020 logger
.debug("WNM Sleep Mode Response - EID 0 not recognized")
1021 msg
['payload'] = struct
.pack("<BBBHBB",
1022 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1027 logger
.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1028 msg
['payload'] = struct
.pack("<BBBHBBBB",
1029 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1030 0, WLAN_EID_WNMSLEEP
, 0, WLAN_EID_TFS_RESP
, 0)
1034 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1035 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1036 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1037 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1038 WNM_STATUS_SLEEP_ACCEPT
, 0,
1039 WLAN_EID_TFS_RESP
, 0)
1043 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1044 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1045 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1046 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1047 WNM_STATUS_DENIED_KEY
, 0,
1048 WLAN_EID_TFS_RESP
, 0)
1052 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1053 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1054 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1055 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1056 WNM_STATUS_DENIED_KEY
, 0,
1057 WLAN_EID_TFS_RESP
, 0)
1061 def test_wnm_action_proto_pmf(dev
, apdev
):
1062 """WNM Action protocol testing (PMF enabled)"""
1063 ssid
= "test-wnm-pmf"
1064 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1065 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1066 params
["ieee80211w"] = "2"
1067 params
['wnm_sleep_mode'] = '1'
1068 hapd
= hostapd
.add_ap(apdev
[0], params
)
1069 bssid
= apdev
[0]['bssid']
1070 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK-SHA256",
1071 proto
="WPA2", ieee80211w
="2", scan_freq
="2412")
1072 dev
[0].request("WNM_SLEEP enter")
1074 hapd
.set("ext_mgmt_frame_handling", "1")
1077 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1078 msg
['da'] = dev
[0].own_addr()
1080 msg
['bssid'] = bssid
1082 logger
.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1083 keydata
= struct
.pack("<BB", 0, 1)
1084 msg
['payload'] = struct
.pack("<BBBH",
1085 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1087 msg
['payload'] += keydata
1088 msg
['payload'] += struct
.pack("<BBBBHBB",
1089 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1090 WNM_STATUS_SLEEP_ACCEPT
, 0,
1091 WLAN_EID_TFS_RESP
, 0)
1095 logger
.debug("WNM Sleep Mode Response - Too short GTK subelem")
1096 keydata
= struct
.pack("<BB", WNM_SLEEP_SUBELEM_GTK
, 0)
1097 msg
['payload'] = struct
.pack("<BBBH",
1098 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1100 msg
['payload'] += keydata
1101 msg
['payload'] += struct
.pack("<BBBBHBB",
1102 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1103 WNM_STATUS_SLEEP_ACCEPT
, 0,
1104 WLAN_EID_TFS_RESP
, 0)
1108 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1109 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1110 0, 17, 0, 0, 0, 0, 0, 0)
1111 msg
['payload'] = struct
.pack("<BBBH",
1112 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1114 msg
['payload'] += keydata
1115 msg
['payload'] += struct
.pack("<BBBBHBB",
1116 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1117 WNM_STATUS_SLEEP_ACCEPT
, 0,
1118 WLAN_EID_TFS_RESP
, 0)
1122 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1123 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1124 0, 0, 0, 0, 0, 0, 0, 0)
1125 msg
['payload'] = struct
.pack("<BBBH",
1126 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1128 msg
['payload'] += keydata
1129 msg
['payload'] += struct
.pack("<BBBBHBB",
1130 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1131 WNM_STATUS_SLEEP_ACCEPT
, 0,
1132 WLAN_EID_TFS_RESP
, 0)
1136 logger
.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1137 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1138 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1139 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1140 keydata
+= struct
.pack("<BB", WNM_SLEEP_SUBELEM_IGTK
, 0)
1141 msg
['payload'] = struct
.pack("<BBBH",
1142 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1144 msg
['payload'] += keydata
1145 msg
['payload'] += struct
.pack("<BBBBHBB",
1146 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1147 WNM_STATUS_SLEEP_ACCEPT
, 0,
1148 WLAN_EID_TFS_RESP
, 0)
1152 logger
.debug("WNM Sleep Mode Response - Unknown subelem")
1153 keydata
= struct
.pack("<BB", 255, 0)
1154 msg
['payload'] = struct
.pack("<BBBH",
1155 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1157 msg
['payload'] += keydata
1158 msg
['payload'] += struct
.pack("<BBBBHBB",
1159 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1160 WNM_STATUS_SLEEP_ACCEPT
, 0,
1161 WLAN_EID_TFS_RESP
, 0)
1165 def test_wnm_action_proto_no_pmf(dev
, apdev
):
1166 """WNM Action protocol testing (PMF disabled)"""
1167 ssid
= "test-wnm-no-pmf"
1168 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1169 params
['wnm_sleep_mode'] = '1'
1170 hapd
= hostapd
.add_ap(apdev
[0], params
)
1171 bssid
= apdev
[0]['bssid']
1172 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1173 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1174 dev
[0].request("WNM_SLEEP enter")
1176 hapd
.set("ext_mgmt_frame_handling", "1")
1179 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1180 msg
['da'] = dev
[0].own_addr()
1182 msg
['bssid'] = bssid
1184 logger
.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1185 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1186 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1187 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1188 keydata
+= struct
.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK
, 2 + 6 + 16, 0,
1190 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1191 msg
['payload'] = struct
.pack("<BBBH",
1192 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1194 msg
['payload'] += keydata
1195 msg
['payload'] += struct
.pack("<BBBBHBB",
1196 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1197 WNM_STATUS_SLEEP_ACCEPT
, 0,
1198 WLAN_EID_TFS_RESP
, 0)
1202 ev
= dev
[0].wait_event(["WNM: Ignore Key Data"], timeout
=5)
1204 raise Exception("Key Data not ignored")
1206 def test_wnm_bss_tm_req_with_mbo_ie(dev
, apdev
):
1207 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1208 ssid
= "test-wnm-mbo"
1209 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1210 hapd
= hostapd
.add_ap(apdev
[0], params
)
1211 bssid
= apdev
[0]['bssid']
1212 if "OK" not in dev
[0].request("SET mbo_cell_capa 1"):
1213 raise Exception("Failed to set STA as cellular data capable")
1215 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1216 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1218 logger
.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1219 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=3:2:1"):
1220 raise Exception("BSS transition management succeeded unexpectedly")
1222 logger
.debug("BTM request with invalid MBO transition reason code")
1223 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=10:2:1"):
1224 raise Exception("BSS transition management succeeded unexpectedly")
1226 logger
.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1227 if 'OK' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1228 raise Exception("BSS transition management command failed")
1230 ev
= dev
[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1231 if ev
is None or "preference=1" not in ev
:
1232 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1234 ev
= dev
[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1235 if ev
is None or "reason=3" not in ev
:
1236 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1238 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1240 raise Exception("No BSS Transition Management Response")
1241 if dev
[0].own_addr() not in ev
:
1242 raise Exception("Unexpected BSS Transition Management Response address")
1244 ev
= dev
[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1246 raise Exception("Station did not disconnect although disassoc imminent was set")
1248 # Set the scan interval to make dev[0] look for connections
1249 if 'OK' not in dev
[0].request("SCAN_INTERVAL 1"):
1250 raise Exception("Failed to set scan interval")
1252 # Make sure no connection is made during the retry delay
1253 ev
= dev
[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1255 raise Exception("Station connected before assoc retry delay was over")
1257 # After the assoc retry delay is over, we can reconnect
1258 ev
= dev
[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1260 raise Exception("Station did not connect after assoc retry delay is over")
1262 if "OK" not in dev
[0].request("SET mbo_cell_capa 3"):
1263 raise Exception("Failed to set STA as cellular data not-capable")
1265 def test_wnm_bss_transition_mgmt_query(dev
, apdev
):
1266 """WNM BSS Transition Management query"""
1267 params
= { "ssid": "test-wnm",
1268 "bss_transition": "1" }
1269 hapd
= hostapd
.add_ap(apdev
[0], params
)
1270 params
= { "ssid": "another" }
1271 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1273 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2412)
1274 dev
[0].scan_for_bss(apdev
[0]['bssid'], 2412)
1276 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1277 dev
[0].request("WNM_BSS_QUERY 0 list")
1279 ev
= dev
[0].wait_event(["WNM: BSS Transition Management Request"],
1282 raise Exception("No BSS Transition Management Request frame seen")
1284 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
1286 raise Exception("No BSS Transition Management Response frame seen")
1288 def test_wnm_bss_tm_security_mismatch(dev
, apdev
):
1289 """WNM BSS Transition Management and security mismatch"""
1290 params
= { "ssid": "test-wnm",
1292 "wpa_key_mgmt": "WPA-PSK",
1293 "rsn_pairwise": "CCMP",
1294 "wpa_passphrase": "12345678",
1297 "bss_transition": "1" }
1298 hapd
= hostapd
.add_ap(apdev
[0], params
)
1300 params
= { "ssid": "test-wnm",
1303 "bss_transition": "1" }
1304 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1306 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2462)
1308 id = dev
[0].connect("test-wnm", psk
="12345678",
1309 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1310 dev
[0].set_network(id, "scan_freq", "")
1311 dev
[0].set_network(id, "bssid", "")
1313 addr
= dev
[0].own_addr()
1314 dev
[0].dump_monitor()
1316 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1317 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"):
1318 raise Exception("BSS_TM_REQ command failed")
1319 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1321 raise Exception("No BSS Transition Management Response")
1322 if "status_code=7" not in ev
:
1323 raise Exception("Unexpected BSS transition request response: " + ev
)
1325 def test_wnm_bss_tm_connect_cmd(dev
, apdev
):
1326 """WNM BSS Transition Management and cfg80211 connect command"""
1327 params
= { "ssid": "test-wnm",
1330 "bss_transition": "1" }
1331 hapd
= hostapd
.add_ap(apdev
[0], params
)
1333 params
= { "ssid": "test-wnm",
1336 "bss_transition": "1" }
1337 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1339 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1340 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1342 wpas
.scan_for_bss(apdev
[1]['bssid'], 2462)
1344 id = wpas
.connect("test-wnm", key_mgmt
="NONE",
1345 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1346 wpas
.set_network(id, "scan_freq", "")
1347 wpas
.set_network(id, "bssid", "")
1349 addr
= wpas
.own_addr()
1352 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1353 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"):
1354 raise Exception("BSS_TM_REQ command failed")
1355 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1357 raise Exception("No BSS Transition Management Response")
1358 if "status_code=0" not in ev
:
1359 raise Exception("BSS transition request was not accepted: " + ev
)
1360 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1361 raise Exception("Unexpected target BSS: " + ev
)
1362 ev
= wpas
.wait_event(["CTRL-EVENT-CONNECTED",
1363 "CTRL-EVENT-DISCONNECTED"], timeout
=10)
1365 raise Exception("No reassociation seen")
1366 if "CTRL-EVENT-DISCONNECTED" in ev
:
1367 #TODO: Uncomment this once kernel side changes for Connect command
1368 #reassociation are in upstream.
1369 #raise Exception("Unexpected disconnection reported")
1370 logger
.info("Unexpected disconnection reported")
1371 ev
= wpas
.wait_event(["CTRL-EVENT-CONNECTED"], timeout
=10)
1373 raise Exception("No reassociation seen")
1374 if apdev
[1]['bssid'] not in ev
:
1375 raise Exception("Unexpected reassociation target: " + ev
)