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.
9 logger = logging.getLogger()
13 from hostapd import HostapdGlobal
14 from hostapd import Hostapd
16 from utils import HwsimSkip, skip_with_fips
17 from wlantest import Wlantest
18 from test_ap_vht import vht_supported
20 def start_ap_wpa2_psk(ap):
21 params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
22 return hostapd.add_ap(ap, params)
24 def connectivity(dev, hapd):
25 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
26 hwsim_utils.test_connectivity(dev[0], hapd)
27 hwsim_utils.test_connectivity(dev[1], hapd)
29 def connect_2sta(dev, ssid, hapd):
30 dev[0].connect(ssid, psk="12345678", scan_freq="2412")
31 dev[1].connect(ssid, psk="12345678", scan_freq="2412")
32 connectivity(dev, hapd)
34 def connect_2sta_wpa2_psk(dev, hapd):
35 connect_2sta(dev, "test-wpa2-psk", hapd)
37 def connect_2sta_wpa_psk(dev, hapd):
38 connect_2sta(dev, "test-wpa-psk", hapd)
40 def connect_2sta_wpa_psk_mixed(dev, hapd):
41 dev[0].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA",
43 dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2",
45 connectivity(dev, hapd)
47 def connect_2sta_wep(dev, hapd):
48 dev[0].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
50 dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
52 connectivity(dev, hapd)
54 def connect_2sta_open(dev, hapd, scan_freq="2412"):
55 dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
56 dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
57 connectivity(dev, hapd)
62 wt.add_passphrase("12345678")
63 wt.add_wepkey("68656c6c6f")
65 def wlantest_tdls_packet_counters(bssid, addr0, addr1):
67 dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1)
68 inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1)
69 ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1)
70 inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1)
71 return [dl,inv_dl,ap,inv_ap]
73 def tdls_check_dl(sta0, sta1, bssid, addr0, addr1):
75 wt.tdls_clear(bssid, addr0, addr1)
76 hwsim_utils.test_connectivity_sta(sta0, sta1)
77 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
79 raise Exception("No valid frames through direct link")
81 raise Exception("Invalid frames through direct link")
83 raise Exception("Unexpected frames through AP path")
85 raise Exception("Invalid frames through AP path")
87 def tdls_check_ap(sta0, sta1, bssid, addr0, addr1):
89 wt.tdls_clear(bssid, addr0, addr1);
90 hwsim_utils.test_connectivity_sta(sta0, sta1)
91 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
93 raise Exception("Unexpected frames through direct link")
95 raise Exception("Invalid frames through direct link")
97 raise Exception("No valid frames through AP path")
99 raise Exception("Invalid frames through AP path")
101 def check_connectivity(sta0, sta1, hapd):
102 hwsim_utils.test_connectivity_sta(sta0, sta1)
103 hwsim_utils.test_connectivity(sta0, hapd)
104 hwsim_utils.test_connectivity(sta1, hapd)
106 def setup_tdls(sta0, sta1, hapd, reverse=False, expect_fail=False):
107 logger.info("Setup TDLS")
108 check_connectivity(sta0, sta1, hapd)
109 bssid = hapd.own_addr()
110 addr0 = sta0.p2p_interface_addr()
111 addr1 = sta1.p2p_interface_addr()
113 wt.tdls_clear(bssid, addr0, addr1);
114 wt.tdls_clear(bssid, addr1, addr0);
115 sta0.tdls_setup(addr1)
118 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
121 addr1 = sta0.p2p_interface_addr()
122 addr0 = sta1.p2p_interface_addr()
123 conf = wt.get_tdls_counter("setup_conf_ok", bssid, addr0, addr1);
125 raise Exception("No TDLS Setup Confirm (success) seen")
126 tdls_check_dl(sta0, sta1, bssid, addr0, addr1)
127 check_connectivity(sta0, sta1, hapd)
129 def teardown_tdls(sta0, sta1, hapd, responder=False, wildcard=False):
130 logger.info("Teardown TDLS")
131 check_connectivity(sta0, sta1, hapd)
132 bssid = hapd.own_addr()
133 addr0 = sta0.p2p_interface_addr()
134 addr1 = sta1.p2p_interface_addr()
136 sta1.tdls_teardown(addr0)
138 sta0.tdls_teardown("*")
140 sta0.tdls_teardown(addr1)
143 teardown = wt.get_tdls_counter("teardown", bssid, addr0, addr1);
145 raise Exception("No TDLS Setup Teardown seen")
146 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
147 check_connectivity(sta0, sta1, hapd)
149 def check_tdls_link(sta0, sta1, connected=True):
150 addr0 = sta0.own_addr()
151 addr1 = sta1.own_addr()
152 status0 = sta0.tdls_link_status(addr1).rstrip()
153 status1 = sta1.tdls_link_status(addr0).rstrip()
154 logger.info("%s: %s" % (sta0.ifname, status0))
155 logger.info("%s: %s" % (sta1.ifname, status1))
156 if status0 != status1:
157 raise Exception("TDLS link status differs between stations")
158 if "status: connected" in status0:
160 raise Exception("Expected TDLS link status NOT to be connected")
163 raise Exception("Expected TDLS link status to be connected")
165 def test_ap_tdls_discovery(dev, apdev):
166 """WPA2-PSK AP and two stations using TDLS discovery"""
167 hapd = start_ap_wpa2_psk(apdev[0])
169 connect_2sta_wpa2_psk(dev, hapd)
170 dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr())
173 def test_ap_wpa2_tdls(dev, apdev):
174 """WPA2-PSK AP and two stations using TDLS"""
175 hapd = start_ap_wpa2_psk(apdev[0])
177 connect_2sta_wpa2_psk(dev, hapd)
178 setup_tdls(dev[0], dev[1], hapd)
179 teardown_tdls(dev[0], dev[1], hapd)
180 setup_tdls(dev[1], dev[0], hapd)
181 #teardown_tdls(dev[0], dev[1], hapd)
183 def test_ap_wpa2_tdls_concurrent_init(dev, apdev):
184 """Concurrent TDLS setup initiation"""
185 hapd = start_ap_wpa2_psk(apdev[0])
187 connect_2sta_wpa2_psk(dev, hapd)
188 dev[0].request("SET tdls_testing 0x80")
189 setup_tdls(dev[1], dev[0], hapd, reverse=True)
191 def test_ap_wpa2_tdls_concurrent_init2(dev, apdev):
192 """Concurrent TDLS setup initiation (reverse)"""
193 hapd = start_ap_wpa2_psk(apdev[0])
195 connect_2sta_wpa2_psk(dev, hapd)
196 dev[1].request("SET tdls_testing 0x80")
197 setup_tdls(dev[0], dev[1], hapd)
199 def test_ap_wpa2_tdls_decline_resp(dev, apdev):
200 """Decline TDLS Setup Response"""
201 hapd = start_ap_wpa2_psk(apdev[0])
203 connect_2sta_wpa2_psk(dev, hapd)
204 dev[1].request("SET tdls_testing 0x200")
205 setup_tdls(dev[1], dev[0], hapd, expect_fail=True)
207 def test_ap_wpa2_tdls_long_lifetime(dev, apdev):
208 """TDLS with long TPK lifetime"""
209 hapd = start_ap_wpa2_psk(apdev[0])
211 connect_2sta_wpa2_psk(dev, hapd)
212 dev[1].request("SET tdls_testing 0x40")
213 setup_tdls(dev[1], dev[0], hapd)
215 def test_ap_wpa2_tdls_long_frame(dev, apdev):
216 """TDLS with long setup/teardown frames"""
217 hapd = start_ap_wpa2_psk(apdev[0])
219 connect_2sta_wpa2_psk(dev, hapd)
220 dev[0].request("SET tdls_testing 0x1")
221 dev[1].request("SET tdls_testing 0x1")
222 setup_tdls(dev[1], dev[0], hapd)
223 teardown_tdls(dev[1], dev[0], hapd)
224 setup_tdls(dev[0], dev[1], hapd)
226 def test_ap_wpa2_tdls_reneg(dev, apdev):
227 """Renegotiate TDLS link"""
228 hapd = start_ap_wpa2_psk(apdev[0])
230 connect_2sta_wpa2_psk(dev, hapd)
231 setup_tdls(dev[1], dev[0], hapd)
232 setup_tdls(dev[0], dev[1], hapd)
234 def test_ap_wpa2_tdls_wrong_lifetime_resp(dev, apdev):
235 """Incorrect TPK lifetime in TDLS Setup Response"""
236 hapd = start_ap_wpa2_psk(apdev[0])
238 connect_2sta_wpa2_psk(dev, hapd)
239 dev[1].request("SET tdls_testing 0x10")
240 setup_tdls(dev[0], dev[1], hapd, expect_fail=True)
242 def test_ap_wpa2_tdls_diff_rsnie(dev, apdev):
243 """TDLS with different RSN IEs"""
244 hapd = start_ap_wpa2_psk(apdev[0])
246 connect_2sta_wpa2_psk(dev, hapd)
247 dev[1].request("SET tdls_testing 0x2")
248 setup_tdls(dev[1], dev[0], hapd)
249 teardown_tdls(dev[1], dev[0], hapd)
251 def test_ap_wpa2_tdls_wrong_tpk_m2_mic(dev, apdev):
252 """Incorrect MIC in TDLS Setup Response"""
253 hapd = start_ap_wpa2_psk(apdev[0])
255 connect_2sta_wpa2_psk(dev, hapd)
256 dev[0].request("SET tdls_testing 0x800")
257 addr0 = dev[0].p2p_interface_addr()
258 dev[1].tdls_setup(addr0)
261 def test_ap_wpa2_tdls_wrong_tpk_m3_mic(dev, apdev):
262 """Incorrect MIC in TDLS Setup Confirm"""
263 hapd = start_ap_wpa2_psk(apdev[0])
265 connect_2sta_wpa2_psk(dev, hapd)
266 dev[1].request("SET tdls_testing 0x800")
267 addr0 = dev[0].p2p_interface_addr()
268 dev[1].tdls_setup(addr0)
271 def test_ap_wpa_tdls(dev, apdev):
272 """WPA-PSK AP and two stations using TDLS"""
273 skip_with_fips(dev[0])
274 hapd = hostapd.add_ap(apdev[0],
275 hostapd.wpa_params(ssid="test-wpa-psk",
276 passphrase="12345678"))
278 connect_2sta_wpa_psk(dev, hapd)
279 setup_tdls(dev[0], dev[1], hapd)
280 teardown_tdls(dev[0], dev[1], hapd)
281 setup_tdls(dev[1], dev[0], hapd)
283 def test_ap_wpa_mixed_tdls(dev, apdev):
284 """WPA+WPA2-PSK AP and two stations using TDLS"""
285 skip_with_fips(dev[0])
286 hapd = hostapd.add_ap(apdev[0],
287 hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk",
288 passphrase="12345678"))
290 connect_2sta_wpa_psk_mixed(dev, hapd)
291 setup_tdls(dev[0], dev[1], hapd)
292 teardown_tdls(dev[0], dev[1], hapd)
293 setup_tdls(dev[1], dev[0], hapd)
295 def test_ap_wep_tdls(dev, apdev):
296 """WEP AP and two stations using TDLS"""
297 hapd = hostapd.add_ap(apdev[0],
298 { "ssid": "test-wep", "wep_key0": '"hello"' })
300 connect_2sta_wep(dev, hapd)
301 setup_tdls(dev[0], dev[1], hapd)
302 teardown_tdls(dev[0], dev[1], hapd)
303 setup_tdls(dev[1], dev[0], hapd)
305 def test_ap_open_tdls(dev, apdev):
306 """Open AP and two stations using TDLS"""
307 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
309 connect_2sta_open(dev, hapd)
310 setup_tdls(dev[0], dev[1], hapd)
311 teardown_tdls(dev[0], dev[1], hapd)
312 setup_tdls(dev[1], dev[0], hapd)
313 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
315 def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev):
316 """TDLS failure due to BSSID mismatch"""
318 ssid = "test-wpa2-psk"
319 passphrase = "12345678"
320 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
321 params['bridge'] = 'ap-br0'
322 hapd = hostapd.add_ap(apdev[0], params)
323 hostapd.add_ap(apdev[1], params)
325 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
326 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
327 dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
328 bssid=apdev[0]['bssid'])
329 dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
330 bssid=apdev[1]['bssid'])
331 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
332 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
333 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
335 addr0 = dev[0].p2p_interface_addr()
336 dev[1].tdls_setup(addr0)
338 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
340 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
341 subprocess.call(['brctl', 'delbr', 'ap-br0'])
343 def test_ap_wpa2_tdls_responder_teardown(dev, apdev):
344 """TDLS teardown from responder with WPA2-PSK AP"""
345 hapd = start_ap_wpa2_psk(apdev[0])
347 connect_2sta_wpa2_psk(dev, hapd)
348 setup_tdls(dev[0], dev[1], hapd)
349 teardown_tdls(dev[0], dev[1], hapd, responder=True)
351 def test_ap_open_tdls_vht(dev, apdev):
352 """Open AP and two stations using TDLS"""
353 params = { "ssid": "test-open",
354 "country_code": "DE",
361 "vht_oper_chwidth": "0",
362 "vht_oper_centr_freq_seg0_idx": "0" }
364 hapd = hostapd.add_ap(apdev[0], params)
366 connect_2sta_open(dev, hapd, scan_freq="5180")
367 setup_tdls(dev[0], dev[1], hapd)
368 teardown_tdls(dev[0], dev[1], hapd)
369 setup_tdls(dev[1], dev[0], hapd)
370 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
372 dev[0].request("DISCONNECT")
373 dev[1].request("DISCONNECT")
375 hapd.request("DISABLE")
376 subprocess.call(['iw', 'reg', 'set', '00'])
377 dev[0].flush_scan_cache()
378 dev[1].flush_scan_cache()
380 def test_ap_open_tdls_vht80(dev, apdev):
381 """Open AP and two stations using TDLS with VHT 80"""
382 params = { "ssid": "test-open",
383 "country_code": "US",
386 "ht_capab": "[HT40+]",
390 "vht_oper_chwidth": "1",
391 "vht_oper_centr_freq_seg0_idx": "42" }
394 hapd = hostapd.add_ap(apdev[0], params)
396 connect_2sta_open(dev, hapd, scan_freq="5180")
397 sig = dev[0].request("SIGNAL_POLL").splitlines()
398 if "WIDTH=80 MHz" not in sig:
399 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
400 setup_tdls(dev[0], dev[1], hapd)
402 check_connectivity(dev[0], dev[1], hapd)
404 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
405 stdout=subprocess.PIPE)
406 res = cmd.stdout.read()
408 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
410 if isinstance(e, Exception) and str(e) == "AP startup failed":
411 if not vht_supported():
412 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
415 dev[0].request("DISCONNECT")
416 dev[1].request("DISCONNECT")
418 hapd.request("DISABLE")
419 subprocess.call(['iw', 'reg', 'set', '00'])
420 dev[0].flush_scan_cache()
421 dev[1].flush_scan_cache()
423 def test_ap_open_tdls_vht80plus80(dev, apdev):
424 """Open AP and two stations using TDLS with VHT 80+80"""
425 params = { "ssid": "test-open",
426 "country_code": "US",
429 "ht_capab": "[HT40+]",
433 "vht_oper_chwidth": "3",
434 "vht_oper_centr_freq_seg0_idx": "42",
435 "vht_oper_centr_freq_seg1_idx": "155" }
438 hapd = hostapd.add_ap(apdev[0], params)
440 connect_2sta_open(dev, hapd, scan_freq="5180")
441 sig = dev[0].request("SIGNAL_POLL").splitlines()
442 if "FREQUENCY=5180" not in sig:
443 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
444 if "WIDTH=80+80 MHz" not in sig:
445 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
446 if "CENTER_FRQ1=5210" not in sig:
447 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
448 if "CENTER_FRQ2=5775" not in sig:
449 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
450 setup_tdls(dev[0], dev[1], hapd)
452 check_connectivity(dev[0], dev[1], hapd)
454 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
455 stdout=subprocess.PIPE)
456 res = cmd.stdout.read()
458 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
460 if isinstance(e, Exception) and str(e) == "AP startup failed":
461 if not vht_supported():
462 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
465 dev[0].request("DISCONNECT")
466 dev[1].request("DISCONNECT")
468 hapd.request("DISABLE")
469 subprocess.call(['iw', 'reg', 'set', '00'])
470 dev[0].flush_scan_cache()
471 dev[1].flush_scan_cache()
473 def test_ap_open_tdls_vht160(dev, apdev):
474 """Open AP and two stations using TDLS with VHT 160"""
475 params = { "ssid": "test-open",
476 "country_code": "ZA",
479 "ht_capab": "[HT40-]",
482 "vht_oper_chwidth": "2",
483 "vht_oper_centr_freq_seg0_idx": "114" }
486 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
487 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
489 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
490 reg = cmd.stdout.readlines()
492 if "5490" in r and "DFS" in r:
493 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
494 raise Exception("AP setup timed out")
496 connect_2sta_open(dev, hapd, scan_freq="5520")
497 sig = dev[0].request("SIGNAL_POLL").splitlines()
498 if "WIDTH=160 MHz" not in sig:
499 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
500 setup_tdls(dev[0], dev[1], hapd)
502 check_connectivity(dev[0], dev[1], hapd)
504 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
505 stdout=subprocess.PIPE)
506 res = cmd.stdout.read()
508 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
510 if isinstance(e, Exception) and str(e) == "AP startup failed":
511 if not vht_supported():
512 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
515 dev[0].request("DISCONNECT")
516 dev[1].request("DISCONNECT")
518 hapd.request("DISABLE")
519 subprocess.call(['iw', 'reg', 'set', '00'])
520 dev[0].flush_scan_cache()
521 dev[1].flush_scan_cache()
523 def test_tdls_chan_switch(dev, apdev):
524 """Open AP and two stations using TDLS"""
525 flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
526 if flags & 0x800000000 == 0:
527 raise HwsimSkip("Driver does not support TDLS channel switching")
529 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
530 connect_2sta_open(dev, hapd)
531 setup_tdls(dev[0], dev[1], hapd)
532 if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
533 raise Exception("Failed to enable TDLS channel switching")
534 if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
535 raise Exception("Could not disable TDLS channel switching")
536 if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
537 raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
539 def test_ap_tdls_link_status(dev, apdev):
540 """Check TDLS link status between two stations"""
541 hapd = start_ap_wpa2_psk(apdev[0])
543 connect_2sta_wpa2_psk(dev, hapd)
544 check_tdls_link(dev[0], dev[1], connected=False)
545 setup_tdls(dev[0], dev[1], hapd)
546 check_tdls_link(dev[0], dev[1], connected=True)
547 teardown_tdls(dev[0], dev[1], hapd)
548 check_tdls_link(dev[0], dev[1], connected=False)
549 if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
550 raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")