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.
7 from remotehost import remote_compatible
10 logger = logging.getLogger()
14 from hostapd import HostapdGlobal
15 from hostapd import Hostapd
17 from utils import HwsimSkip, skip_with_fips
18 from wlantest import Wlantest
19 from test_ap_vht import vht_supported
21 def start_ap_wpa2_psk(ap):
22 params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
23 return hostapd.add_ap(ap, params)
25 def connectivity(dev, hapd):
26 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
27 hwsim_utils.test_connectivity(dev[0], hapd)
28 hwsim_utils.test_connectivity(dev[1], hapd)
30 def connect_2sta(dev, ssid, hapd):
31 dev[0].connect(ssid, psk="12345678", scan_freq="2412")
32 dev[1].connect(ssid, psk="12345678", scan_freq="2412")
33 connectivity(dev, hapd)
35 def connect_2sta_wpa2_psk(dev, hapd):
36 connect_2sta(dev, "test-wpa2-psk", hapd)
38 def connect_2sta_wpa_psk(dev, hapd):
39 connect_2sta(dev, "test-wpa-psk", hapd)
41 def connect_2sta_wpa_psk_mixed(dev, hapd):
42 dev[0].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA",
44 dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2",
46 connectivity(dev, hapd)
48 def connect_2sta_wep(dev, hapd):
49 dev[0].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
51 dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
53 connectivity(dev, hapd)
55 def connect_2sta_open(dev, hapd, scan_freq="2412"):
56 dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
57 dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
58 connectivity(dev, hapd)
60 def wlantest_setup(hapd):
64 wt.add_passphrase("12345678")
65 wt.add_wepkey("68656c6c6f")
67 def wlantest_tdls_packet_counters(bssid, addr0, addr1):
69 dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1)
70 inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1)
71 ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1)
72 inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1)
73 return [dl,inv_dl,ap,inv_ap]
75 def tdls_check_dl(sta0, sta1, bssid, addr0, addr1):
77 wt.tdls_clear(bssid, addr0, addr1)
78 hwsim_utils.test_connectivity_sta(sta0, sta1)
79 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
81 raise Exception("No valid frames through direct link")
83 raise Exception("Invalid frames through direct link")
85 raise Exception("Unexpected frames through AP path")
87 raise Exception("Invalid frames through AP path")
89 def tdls_check_ap(sta0, sta1, bssid, addr0, addr1):
91 wt.tdls_clear(bssid, addr0, addr1)
92 hwsim_utils.test_connectivity_sta(sta0, sta1)
93 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
95 raise Exception("Unexpected frames through direct link")
97 raise Exception("Invalid frames through direct link")
99 raise Exception("No valid frames through AP path")
101 raise Exception("Invalid frames through AP path")
103 def check_connectivity(sta0, sta1, hapd):
104 hwsim_utils.test_connectivity_sta(sta0, sta1)
105 hwsim_utils.test_connectivity(sta0, hapd)
106 hwsim_utils.test_connectivity(sta1, hapd)
108 def setup_tdls(sta0, sta1, hapd, reverse=False, expect_fail=False):
109 logger.info("Setup TDLS")
110 check_connectivity(sta0, sta1, hapd)
111 bssid = hapd.own_addr()
112 addr0 = sta0.p2p_interface_addr()
113 addr1 = sta1.p2p_interface_addr()
115 wt.tdls_clear(bssid, addr0, addr1)
116 wt.tdls_clear(bssid, addr1, addr0)
117 sta0.tdls_setup(addr1)
120 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
123 addr1 = sta0.p2p_interface_addr()
124 addr0 = sta1.p2p_interface_addr()
125 conf = wt.get_tdls_counter("setup_conf_ok", bssid, addr0, addr1)
127 raise Exception("No TDLS Setup Confirm (success) seen")
128 tdls_check_dl(sta0, sta1, bssid, addr0, addr1)
129 check_connectivity(sta0, sta1, hapd)
131 def teardown_tdls(sta0, sta1, hapd, responder=False, wildcard=False):
132 logger.info("Teardown TDLS")
133 check_connectivity(sta0, sta1, hapd)
134 bssid = hapd.own_addr()
135 addr0 = sta0.p2p_interface_addr()
136 addr1 = sta1.p2p_interface_addr()
138 sta1.tdls_teardown(addr0)
140 sta0.tdls_teardown("*")
142 sta0.tdls_teardown(addr1)
145 teardown = wt.get_tdls_counter("teardown", bssid, addr0, addr1)
147 raise Exception("No TDLS Setup Teardown seen")
148 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
149 check_connectivity(sta0, sta1, hapd)
151 def check_tdls_link(sta0, sta1, connected=True):
152 addr0 = sta0.own_addr()
153 addr1 = sta1.own_addr()
154 status0 = sta0.tdls_link_status(addr1).rstrip()
155 status1 = sta1.tdls_link_status(addr0).rstrip()
156 logger.info("%s: %s" % (sta0.ifname, status0))
157 logger.info("%s: %s" % (sta1.ifname, status1))
158 if status0 != status1:
159 raise Exception("TDLS link status differs between stations")
160 if "status: connected" in status0:
162 raise Exception("Expected TDLS link status NOT to be connected")
165 raise Exception("Expected TDLS link status to be connected")
168 def test_ap_tdls_discovery(dev, apdev):
169 """WPA2-PSK AP and two stations using TDLS discovery"""
170 hapd = start_ap_wpa2_psk(apdev[0])
172 connect_2sta_wpa2_psk(dev, hapd)
173 dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr())
176 def test_ap_wpa2_tdls(dev, apdev):
177 """WPA2-PSK AP and two stations using TDLS"""
178 hapd = start_ap_wpa2_psk(apdev[0])
180 connect_2sta_wpa2_psk(dev, hapd)
181 setup_tdls(dev[0], dev[1], hapd)
182 teardown_tdls(dev[0], dev[1], hapd)
183 setup_tdls(dev[1], dev[0], hapd)
184 #teardown_tdls(dev[0], dev[1], hapd)
186 def test_ap_wpa2_tdls_concurrent_init(dev, apdev):
187 """Concurrent TDLS setup initiation"""
188 hapd = start_ap_wpa2_psk(apdev[0])
190 connect_2sta_wpa2_psk(dev, hapd)
191 dev[0].request("SET tdls_testing 0x80")
192 setup_tdls(dev[1], dev[0], hapd, reverse=True)
194 def test_ap_wpa2_tdls_concurrent_init2(dev, apdev):
195 """Concurrent TDLS setup initiation (reverse)"""
196 hapd = start_ap_wpa2_psk(apdev[0])
198 connect_2sta_wpa2_psk(dev, hapd)
199 dev[1].request("SET tdls_testing 0x80")
200 setup_tdls(dev[0], dev[1], hapd)
202 def test_ap_wpa2_tdls_decline_resp(dev, apdev):
203 """Decline TDLS Setup Response"""
204 hapd = start_ap_wpa2_psk(apdev[0])
206 connect_2sta_wpa2_psk(dev, hapd)
207 dev[1].request("SET tdls_testing 0x200")
208 setup_tdls(dev[1], dev[0], hapd, expect_fail=True)
210 def test_ap_wpa2_tdls_long_lifetime(dev, apdev):
211 """TDLS with long TPK lifetime"""
212 hapd = start_ap_wpa2_psk(apdev[0])
214 connect_2sta_wpa2_psk(dev, hapd)
215 dev[1].request("SET tdls_testing 0x40")
216 setup_tdls(dev[1], dev[0], hapd)
218 def test_ap_wpa2_tdls_long_frame(dev, apdev):
219 """TDLS with long setup/teardown frames"""
220 hapd = start_ap_wpa2_psk(apdev[0])
222 connect_2sta_wpa2_psk(dev, hapd)
223 dev[0].request("SET tdls_testing 0x1")
224 dev[1].request("SET tdls_testing 0x1")
225 setup_tdls(dev[1], dev[0], hapd)
226 teardown_tdls(dev[1], dev[0], hapd)
227 setup_tdls(dev[0], dev[1], hapd)
229 def test_ap_wpa2_tdls_reneg(dev, apdev):
230 """Renegotiate TDLS link"""
231 hapd = start_ap_wpa2_psk(apdev[0])
233 connect_2sta_wpa2_psk(dev, hapd)
234 setup_tdls(dev[1], dev[0], hapd)
235 setup_tdls(dev[0], dev[1], hapd)
237 def test_ap_wpa2_tdls_wrong_lifetime_resp(dev, apdev):
238 """Incorrect TPK lifetime in TDLS Setup Response"""
239 hapd = start_ap_wpa2_psk(apdev[0])
241 connect_2sta_wpa2_psk(dev, hapd)
242 dev[1].request("SET tdls_testing 0x10")
243 setup_tdls(dev[0], dev[1], hapd, expect_fail=True)
245 def test_ap_wpa2_tdls_diff_rsnie(dev, apdev):
246 """TDLS with different RSN IEs"""
247 hapd = start_ap_wpa2_psk(apdev[0])
249 connect_2sta_wpa2_psk(dev, hapd)
250 dev[1].request("SET tdls_testing 0x2")
251 setup_tdls(dev[1], dev[0], hapd)
252 teardown_tdls(dev[1], dev[0], hapd)
254 def test_ap_wpa2_tdls_wrong_tpk_m2_mic(dev, apdev):
255 """Incorrect MIC in TDLS Setup Response"""
256 hapd = start_ap_wpa2_psk(apdev[0])
258 connect_2sta_wpa2_psk(dev, hapd)
259 dev[0].request("SET tdls_testing 0x800")
260 addr0 = dev[0].p2p_interface_addr()
261 dev[1].tdls_setup(addr0)
264 def test_ap_wpa2_tdls_wrong_tpk_m3_mic(dev, apdev):
265 """Incorrect MIC in TDLS Setup Confirm"""
266 hapd = start_ap_wpa2_psk(apdev[0])
268 connect_2sta_wpa2_psk(dev, hapd)
269 dev[1].request("SET tdls_testing 0x800")
270 addr0 = dev[0].p2p_interface_addr()
271 dev[1].tdls_setup(addr0)
274 def test_ap_wpa_tdls(dev, apdev):
275 """WPA-PSK AP and two stations using TDLS"""
276 skip_with_fips(dev[0])
277 hapd = hostapd.add_ap(apdev[0],
278 hostapd.wpa_params(ssid="test-wpa-psk",
279 passphrase="12345678"))
281 connect_2sta_wpa_psk(dev, hapd)
282 setup_tdls(dev[0], dev[1], hapd)
283 teardown_tdls(dev[0], dev[1], hapd)
284 setup_tdls(dev[1], dev[0], hapd)
286 def test_ap_wpa_mixed_tdls(dev, apdev):
287 """WPA+WPA2-PSK AP and two stations using TDLS"""
288 skip_with_fips(dev[0])
289 hapd = hostapd.add_ap(apdev[0],
290 hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk",
291 passphrase="12345678"))
293 connect_2sta_wpa_psk_mixed(dev, hapd)
294 setup_tdls(dev[0], dev[1], hapd)
295 teardown_tdls(dev[0], dev[1], hapd)
296 setup_tdls(dev[1], dev[0], hapd)
298 def test_ap_wep_tdls(dev, apdev):
299 """WEP AP and two stations using TDLS"""
300 hapd = hostapd.add_ap(apdev[0],
301 { "ssid": "test-wep", "wep_key0": '"hello"' })
303 connect_2sta_wep(dev, hapd)
304 setup_tdls(dev[0], dev[1], hapd)
305 teardown_tdls(dev[0], dev[1], hapd)
306 setup_tdls(dev[1], dev[0], hapd)
308 def test_ap_open_tdls(dev, apdev):
309 """Open AP and two stations using TDLS"""
310 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
312 connect_2sta_open(dev, hapd)
313 setup_tdls(dev[0], dev[1], hapd)
314 teardown_tdls(dev[0], dev[1], hapd)
315 setup_tdls(dev[1], dev[0], hapd)
316 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
318 def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev):
319 """TDLS failure due to BSSID mismatch"""
321 ssid = "test-wpa2-psk"
322 passphrase = "12345678"
323 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
324 params['bridge'] = 'ap-br0'
325 hapd = hostapd.add_ap(apdev[0], params)
326 hostapd.add_ap(apdev[1], params)
328 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
329 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
330 dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
331 bssid=apdev[0]['bssid'])
332 dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
333 bssid=apdev[1]['bssid'])
334 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
335 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
336 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
338 addr0 = dev[0].p2p_interface_addr()
339 dev[1].tdls_setup(addr0)
341 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
343 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
344 subprocess.call(['brctl', 'delbr', 'ap-br0'])
346 def test_ap_wpa2_tdls_responder_teardown(dev, apdev):
347 """TDLS teardown from responder with WPA2-PSK AP"""
348 hapd = start_ap_wpa2_psk(apdev[0])
350 connect_2sta_wpa2_psk(dev, hapd)
351 setup_tdls(dev[0], dev[1], hapd)
352 teardown_tdls(dev[0], dev[1], hapd, responder=True)
354 def test_ap_open_tdls_vht(dev, apdev):
355 """Open AP and two stations using TDLS"""
356 params = { "ssid": "test-open",
357 "country_code": "DE",
364 "vht_oper_chwidth": "0",
365 "vht_oper_centr_freq_seg0_idx": "0" }
368 hapd = hostapd.add_ap(apdev[0], params)
370 connect_2sta_open(dev, hapd, scan_freq="5180")
371 setup_tdls(dev[0], dev[1], hapd)
372 teardown_tdls(dev[0], dev[1], hapd)
373 setup_tdls(dev[1], dev[0], hapd)
374 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
376 dev[0].request("DISCONNECT")
377 dev[1].request("DISCONNECT")
379 hapd.request("DISABLE")
380 subprocess.call(['iw', 'reg', 'set', '00'])
381 dev[0].flush_scan_cache()
382 dev[1].flush_scan_cache()
384 def test_ap_open_tdls_vht80(dev, apdev):
385 """Open AP and two stations using TDLS with VHT 80"""
386 params = { "ssid": "test-open",
387 "country_code": "US",
390 "ht_capab": "[HT40+]",
394 "vht_oper_chwidth": "1",
395 "vht_oper_centr_freq_seg0_idx": "42" }
398 hapd = hostapd.add_ap(apdev[0], params)
400 connect_2sta_open(dev, hapd, scan_freq="5180")
401 sig = dev[0].request("SIGNAL_POLL").splitlines()
402 if "WIDTH=80 MHz" not in sig:
403 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
404 setup_tdls(dev[0], dev[1], hapd)
406 check_connectivity(dev[0], dev[1], hapd)
408 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
409 stdout=subprocess.PIPE)
410 res = cmd.stdout.read()
412 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
414 if isinstance(e, Exception) and str(e) == "AP startup failed":
415 if not vht_supported():
416 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
419 dev[0].request("DISCONNECT")
420 dev[1].request("DISCONNECT")
422 hapd.request("DISABLE")
423 subprocess.call(['iw', 'reg', 'set', '00'])
424 dev[0].flush_scan_cache()
425 dev[1].flush_scan_cache()
427 def test_ap_open_tdls_vht80plus80(dev, apdev):
428 """Open AP and two stations using TDLS with VHT 80+80"""
429 params = { "ssid": "test-open",
430 "country_code": "US",
433 "ht_capab": "[HT40+]",
437 "vht_oper_chwidth": "3",
438 "vht_oper_centr_freq_seg0_idx": "42",
439 "vht_oper_centr_freq_seg1_idx": "155" }
442 hapd = hostapd.add_ap(apdev[0], params)
444 connect_2sta_open(dev, hapd, scan_freq="5180")
445 sig = dev[0].request("SIGNAL_POLL").splitlines()
446 if "FREQUENCY=5180" not in sig:
447 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
448 if "WIDTH=80+80 MHz" not in sig:
449 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
450 if "CENTER_FRQ1=5210" not in sig:
451 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
452 if "CENTER_FRQ2=5775" not in sig:
453 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
454 setup_tdls(dev[0], dev[1], hapd)
456 check_connectivity(dev[0], dev[1], hapd)
458 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
459 stdout=subprocess.PIPE)
460 res = cmd.stdout.read()
462 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
464 if isinstance(e, Exception) and str(e) == "AP startup failed":
465 if not vht_supported():
466 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
469 dev[0].request("DISCONNECT")
470 dev[1].request("DISCONNECT")
472 hapd.request("DISABLE")
473 subprocess.call(['iw', 'reg', 'set', '00'])
474 dev[0].flush_scan_cache()
475 dev[1].flush_scan_cache()
477 def test_ap_open_tdls_vht160(dev, apdev):
478 """Open AP and two stations using TDLS with VHT 160"""
479 params = { "ssid": "test-open",
480 "country_code": "ZA",
483 "ht_capab": "[HT40-]",
486 "vht_oper_chwidth": "2",
487 "vht_oper_centr_freq_seg0_idx": "114" }
490 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
491 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
493 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
494 reg = cmd.stdout.readlines()
496 if "5490" in r and "DFS" in r:
497 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
498 raise Exception("AP setup timed out")
500 connect_2sta_open(dev, hapd, scan_freq="5520")
501 sig = dev[0].request("SIGNAL_POLL").splitlines()
502 if "WIDTH=160 MHz" not in sig:
503 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
504 setup_tdls(dev[0], dev[1], hapd)
506 check_connectivity(dev[0], dev[1], hapd)
508 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
509 stdout=subprocess.PIPE)
510 res = cmd.stdout.read()
512 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
514 if isinstance(e, Exception) and str(e) == "AP startup failed":
515 if not vht_supported():
516 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
519 dev[0].request("DISCONNECT")
520 dev[1].request("DISCONNECT")
522 hapd.request("DISABLE")
523 subprocess.call(['iw', 'reg', 'set', '00'])
524 dev[0].flush_scan_cache()
525 dev[1].flush_scan_cache()
527 def test_tdls_chan_switch(dev, apdev):
528 """Open AP and two stations using TDLS"""
529 flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
530 if flags & 0x800000000 == 0:
531 raise HwsimSkip("Driver does not support TDLS channel switching")
533 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
535 connect_2sta_open(dev, hapd)
536 setup_tdls(dev[0], dev[1], hapd)
537 if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
538 raise Exception("Failed to enable TDLS channel switching")
539 if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
540 raise Exception("Could not disable TDLS channel switching")
541 if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
542 raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
544 def test_ap_tdls_link_status(dev, apdev):
545 """Check TDLS link status between two stations"""
546 hapd = start_ap_wpa2_psk(apdev[0])
548 connect_2sta_wpa2_psk(dev, hapd)
549 check_tdls_link(dev[0], dev[1], connected=False)
550 setup_tdls(dev[0], dev[1], hapd)
551 check_tdls_link(dev[0], dev[1], connected=True)
552 teardown_tdls(dev[0], dev[1], hapd)
553 check_tdls_link(dev[0], dev[1], connected=False)
554 if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
555 raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")