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)
59 def wlantest_setup(hapd):
63 wt.add_passphrase("12345678")
64 wt.add_wepkey("68656c6c6f")
66 def wlantest_tdls_packet_counters(bssid, addr0, addr1):
68 dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1)
69 inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1)
70 ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1)
71 inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1)
72 return [dl,inv_dl,ap,inv_ap]
74 def tdls_check_dl(sta0, sta1, bssid, addr0, addr1):
76 wt.tdls_clear(bssid, addr0, addr1)
77 hwsim_utils.test_connectivity_sta(sta0, sta1)
78 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
80 raise Exception("No valid frames through direct link")
82 raise Exception("Invalid frames through direct link")
84 raise Exception("Unexpected frames through AP path")
86 raise Exception("Invalid frames through AP path")
88 def tdls_check_ap(sta0, sta1, bssid, addr0, addr1):
90 wt.tdls_clear(bssid, addr0, addr1);
91 hwsim_utils.test_connectivity_sta(sta0, sta1)
92 [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
94 raise Exception("Unexpected frames through direct link")
96 raise Exception("Invalid frames through direct link")
98 raise Exception("No valid frames through AP path")
100 raise Exception("Invalid frames through AP path")
102 def check_connectivity(sta0, sta1, hapd):
103 hwsim_utils.test_connectivity_sta(sta0, sta1)
104 hwsim_utils.test_connectivity(sta0, hapd)
105 hwsim_utils.test_connectivity(sta1, hapd)
107 def setup_tdls(sta0, sta1, hapd, reverse=False, expect_fail=False):
108 logger.info("Setup TDLS")
109 check_connectivity(sta0, sta1, hapd)
110 bssid = hapd.own_addr()
111 addr0 = sta0.p2p_interface_addr()
112 addr1 = sta1.p2p_interface_addr()
114 wt.tdls_clear(bssid, addr0, addr1);
115 wt.tdls_clear(bssid, addr1, addr0);
116 sta0.tdls_setup(addr1)
119 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
122 addr1 = sta0.p2p_interface_addr()
123 addr0 = sta1.p2p_interface_addr()
124 conf = wt.get_tdls_counter("setup_conf_ok", bssid, addr0, addr1);
126 raise Exception("No TDLS Setup Confirm (success) seen")
127 tdls_check_dl(sta0, sta1, bssid, addr0, addr1)
128 check_connectivity(sta0, sta1, hapd)
130 def teardown_tdls(sta0, sta1, hapd, responder=False, wildcard=False):
131 logger.info("Teardown TDLS")
132 check_connectivity(sta0, sta1, hapd)
133 bssid = hapd.own_addr()
134 addr0 = sta0.p2p_interface_addr()
135 addr1 = sta1.p2p_interface_addr()
137 sta1.tdls_teardown(addr0)
139 sta0.tdls_teardown("*")
141 sta0.tdls_teardown(addr1)
144 teardown = wt.get_tdls_counter("teardown", bssid, addr0, addr1);
146 raise Exception("No TDLS Setup Teardown seen")
147 tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
148 check_connectivity(sta0, sta1, hapd)
150 def check_tdls_link(sta0, sta1, connected=True):
151 addr0 = sta0.own_addr()
152 addr1 = sta1.own_addr()
153 status0 = sta0.tdls_link_status(addr1).rstrip()
154 status1 = sta1.tdls_link_status(addr0).rstrip()
155 logger.info("%s: %s" % (sta0.ifname, status0))
156 logger.info("%s: %s" % (sta1.ifname, status1))
157 if status0 != status1:
158 raise Exception("TDLS link status differs between stations")
159 if "status: connected" in status0:
161 raise Exception("Expected TDLS link status NOT to be connected")
164 raise Exception("Expected TDLS link status to be connected")
166 def test_ap_tdls_discovery(dev, apdev):
167 """WPA2-PSK AP and two stations using TDLS discovery"""
168 hapd = start_ap_wpa2_psk(apdev[0])
170 connect_2sta_wpa2_psk(dev, hapd)
171 dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr())
174 def test_ap_wpa2_tdls(dev, apdev):
175 """WPA2-PSK AP and two stations using TDLS"""
176 hapd = start_ap_wpa2_psk(apdev[0])
178 connect_2sta_wpa2_psk(dev, hapd)
179 setup_tdls(dev[0], dev[1], hapd)
180 teardown_tdls(dev[0], dev[1], hapd)
181 setup_tdls(dev[1], dev[0], hapd)
182 #teardown_tdls(dev[0], dev[1], hapd)
184 def test_ap_wpa2_tdls_concurrent_init(dev, apdev):
185 """Concurrent TDLS setup initiation"""
186 hapd = start_ap_wpa2_psk(apdev[0])
188 connect_2sta_wpa2_psk(dev, hapd)
189 dev[0].request("SET tdls_testing 0x80")
190 setup_tdls(dev[1], dev[0], hapd, reverse=True)
192 def test_ap_wpa2_tdls_concurrent_init2(dev, apdev):
193 """Concurrent TDLS setup initiation (reverse)"""
194 hapd = start_ap_wpa2_psk(apdev[0])
196 connect_2sta_wpa2_psk(dev, hapd)
197 dev[1].request("SET tdls_testing 0x80")
198 setup_tdls(dev[0], dev[1], hapd)
200 def test_ap_wpa2_tdls_decline_resp(dev, apdev):
201 """Decline TDLS Setup Response"""
202 hapd = start_ap_wpa2_psk(apdev[0])
204 connect_2sta_wpa2_psk(dev, hapd)
205 dev[1].request("SET tdls_testing 0x200")
206 setup_tdls(dev[1], dev[0], hapd, expect_fail=True)
208 def test_ap_wpa2_tdls_long_lifetime(dev, apdev):
209 """TDLS with long TPK lifetime"""
210 hapd = start_ap_wpa2_psk(apdev[0])
212 connect_2sta_wpa2_psk(dev, hapd)
213 dev[1].request("SET tdls_testing 0x40")
214 setup_tdls(dev[1], dev[0], hapd)
216 def test_ap_wpa2_tdls_long_frame(dev, apdev):
217 """TDLS with long setup/teardown frames"""
218 hapd = start_ap_wpa2_psk(apdev[0])
220 connect_2sta_wpa2_psk(dev, hapd)
221 dev[0].request("SET tdls_testing 0x1")
222 dev[1].request("SET tdls_testing 0x1")
223 setup_tdls(dev[1], dev[0], hapd)
224 teardown_tdls(dev[1], dev[0], hapd)
225 setup_tdls(dev[0], dev[1], hapd)
227 def test_ap_wpa2_tdls_reneg(dev, apdev):
228 """Renegotiate TDLS link"""
229 hapd = start_ap_wpa2_psk(apdev[0])
231 connect_2sta_wpa2_psk(dev, hapd)
232 setup_tdls(dev[1], dev[0], hapd)
233 setup_tdls(dev[0], dev[1], hapd)
235 def test_ap_wpa2_tdls_wrong_lifetime_resp(dev, apdev):
236 """Incorrect TPK lifetime in TDLS Setup Response"""
237 hapd = start_ap_wpa2_psk(apdev[0])
239 connect_2sta_wpa2_psk(dev, hapd)
240 dev[1].request("SET tdls_testing 0x10")
241 setup_tdls(dev[0], dev[1], hapd, expect_fail=True)
243 def test_ap_wpa2_tdls_diff_rsnie(dev, apdev):
244 """TDLS with different RSN IEs"""
245 hapd = start_ap_wpa2_psk(apdev[0])
247 connect_2sta_wpa2_psk(dev, hapd)
248 dev[1].request("SET tdls_testing 0x2")
249 setup_tdls(dev[1], dev[0], hapd)
250 teardown_tdls(dev[1], dev[0], hapd)
252 def test_ap_wpa2_tdls_wrong_tpk_m2_mic(dev, apdev):
253 """Incorrect MIC in TDLS Setup Response"""
254 hapd = start_ap_wpa2_psk(apdev[0])
256 connect_2sta_wpa2_psk(dev, hapd)
257 dev[0].request("SET tdls_testing 0x800")
258 addr0 = dev[0].p2p_interface_addr()
259 dev[1].tdls_setup(addr0)
262 def test_ap_wpa2_tdls_wrong_tpk_m3_mic(dev, apdev):
263 """Incorrect MIC in TDLS Setup Confirm"""
264 hapd = start_ap_wpa2_psk(apdev[0])
266 connect_2sta_wpa2_psk(dev, hapd)
267 dev[1].request("SET tdls_testing 0x800")
268 addr0 = dev[0].p2p_interface_addr()
269 dev[1].tdls_setup(addr0)
272 def test_ap_wpa_tdls(dev, apdev):
273 """WPA-PSK AP and two stations using TDLS"""
274 skip_with_fips(dev[0])
275 hapd = hostapd.add_ap(apdev[0],
276 hostapd.wpa_params(ssid="test-wpa-psk",
277 passphrase="12345678"))
279 connect_2sta_wpa_psk(dev, hapd)
280 setup_tdls(dev[0], dev[1], hapd)
281 teardown_tdls(dev[0], dev[1], hapd)
282 setup_tdls(dev[1], dev[0], hapd)
284 def test_ap_wpa_mixed_tdls(dev, apdev):
285 """WPA+WPA2-PSK AP and two stations using TDLS"""
286 skip_with_fips(dev[0])
287 hapd = hostapd.add_ap(apdev[0],
288 hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk",
289 passphrase="12345678"))
291 connect_2sta_wpa_psk_mixed(dev, hapd)
292 setup_tdls(dev[0], dev[1], hapd)
293 teardown_tdls(dev[0], dev[1], hapd)
294 setup_tdls(dev[1], dev[0], hapd)
296 def test_ap_wep_tdls(dev, apdev):
297 """WEP AP and two stations using TDLS"""
298 hapd = hostapd.add_ap(apdev[0],
299 { "ssid": "test-wep", "wep_key0": '"hello"' })
301 connect_2sta_wep(dev, hapd)
302 setup_tdls(dev[0], dev[1], hapd)
303 teardown_tdls(dev[0], dev[1], hapd)
304 setup_tdls(dev[1], dev[0], hapd)
306 def test_ap_open_tdls(dev, apdev):
307 """Open AP and two stations using TDLS"""
308 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
310 connect_2sta_open(dev, hapd)
311 setup_tdls(dev[0], dev[1], hapd)
312 teardown_tdls(dev[0], dev[1], hapd)
313 setup_tdls(dev[1], dev[0], hapd)
314 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
316 def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev):
317 """TDLS failure due to BSSID mismatch"""
319 ssid = "test-wpa2-psk"
320 passphrase = "12345678"
321 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
322 params['bridge'] = 'ap-br0'
323 hapd = hostapd.add_ap(apdev[0], params)
324 hostapd.add_ap(apdev[1], params)
326 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
327 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
328 dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
329 bssid=apdev[0]['bssid'])
330 dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
331 bssid=apdev[1]['bssid'])
332 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
333 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
334 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
336 addr0 = dev[0].p2p_interface_addr()
337 dev[1].tdls_setup(addr0)
339 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
341 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
342 subprocess.call(['brctl', 'delbr', 'ap-br0'])
344 def test_ap_wpa2_tdls_responder_teardown(dev, apdev):
345 """TDLS teardown from responder with WPA2-PSK AP"""
346 hapd = start_ap_wpa2_psk(apdev[0])
348 connect_2sta_wpa2_psk(dev, hapd)
349 setup_tdls(dev[0], dev[1], hapd)
350 teardown_tdls(dev[0], dev[1], hapd, responder=True)
352 def test_ap_open_tdls_vht(dev, apdev):
353 """Open AP and two stations using TDLS"""
354 params = { "ssid": "test-open",
355 "country_code": "DE",
362 "vht_oper_chwidth": "0",
363 "vht_oper_centr_freq_seg0_idx": "0" }
365 hapd = hostapd.add_ap(apdev[0], params)
367 connect_2sta_open(dev, hapd, scan_freq="5180")
368 setup_tdls(dev[0], dev[1], hapd)
369 teardown_tdls(dev[0], dev[1], hapd)
370 setup_tdls(dev[1], dev[0], hapd)
371 teardown_tdls(dev[1], dev[0], hapd, wildcard=True)
373 dev[0].request("DISCONNECT")
374 dev[1].request("DISCONNECT")
376 hapd.request("DISABLE")
377 subprocess.call(['iw', 'reg', 'set', '00'])
378 dev[0].flush_scan_cache()
379 dev[1].flush_scan_cache()
381 def test_ap_open_tdls_vht80(dev, apdev):
382 """Open AP and two stations using TDLS with VHT 80"""
383 params = { "ssid": "test-open",
384 "country_code": "US",
387 "ht_capab": "[HT40+]",
391 "vht_oper_chwidth": "1",
392 "vht_oper_centr_freq_seg0_idx": "42" }
395 hapd = hostapd.add_ap(apdev[0], params)
397 connect_2sta_open(dev, hapd, scan_freq="5180")
398 sig = dev[0].request("SIGNAL_POLL").splitlines()
399 if "WIDTH=80 MHz" not in sig:
400 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
401 setup_tdls(dev[0], dev[1], hapd)
403 check_connectivity(dev[0], dev[1], hapd)
405 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
406 stdout=subprocess.PIPE)
407 res = cmd.stdout.read()
409 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
411 if isinstance(e, Exception) and str(e) == "AP startup failed":
412 if not vht_supported():
413 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
416 dev[0].request("DISCONNECT")
417 dev[1].request("DISCONNECT")
419 hapd.request("DISABLE")
420 subprocess.call(['iw', 'reg', 'set', '00'])
421 dev[0].flush_scan_cache()
422 dev[1].flush_scan_cache()
424 def test_ap_open_tdls_vht80plus80(dev, apdev):
425 """Open AP and two stations using TDLS with VHT 80+80"""
426 params = { "ssid": "test-open",
427 "country_code": "US",
430 "ht_capab": "[HT40+]",
434 "vht_oper_chwidth": "3",
435 "vht_oper_centr_freq_seg0_idx": "42",
436 "vht_oper_centr_freq_seg1_idx": "155" }
439 hapd = hostapd.add_ap(apdev[0], params)
441 connect_2sta_open(dev, hapd, scan_freq="5180")
442 sig = dev[0].request("SIGNAL_POLL").splitlines()
443 if "FREQUENCY=5180" not in sig:
444 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
445 if "WIDTH=80+80 MHz" not in sig:
446 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
447 if "CENTER_FRQ1=5210" not in sig:
448 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
449 if "CENTER_FRQ2=5775" not in sig:
450 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
451 setup_tdls(dev[0], dev[1], hapd)
453 check_connectivity(dev[0], dev[1], hapd)
455 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
456 stdout=subprocess.PIPE)
457 res = cmd.stdout.read()
459 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
461 if isinstance(e, Exception) and str(e) == "AP startup failed":
462 if not vht_supported():
463 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
466 dev[0].request("DISCONNECT")
467 dev[1].request("DISCONNECT")
469 hapd.request("DISABLE")
470 subprocess.call(['iw', 'reg', 'set', '00'])
471 dev[0].flush_scan_cache()
472 dev[1].flush_scan_cache()
474 def test_ap_open_tdls_vht160(dev, apdev):
475 """Open AP and two stations using TDLS with VHT 160"""
476 params = { "ssid": "test-open",
477 "country_code": "ZA",
480 "ht_capab": "[HT40-]",
483 "vht_oper_chwidth": "2",
484 "vht_oper_centr_freq_seg0_idx": "114" }
487 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
488 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
490 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
491 reg = cmd.stdout.readlines()
493 if "5490" in r and "DFS" in r:
494 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
495 raise Exception("AP setup timed out")
497 connect_2sta_open(dev, hapd, scan_freq="5520")
498 sig = dev[0].request("SIGNAL_POLL").splitlines()
499 if "WIDTH=160 MHz" not in sig:
500 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
501 setup_tdls(dev[0], dev[1], hapd)
503 check_connectivity(dev[0], dev[1], hapd)
505 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
506 stdout=subprocess.PIPE)
507 res = cmd.stdout.read()
509 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
511 if isinstance(e, Exception) and str(e) == "AP startup failed":
512 if not vht_supported():
513 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
516 dev[0].request("DISCONNECT")
517 dev[1].request("DISCONNECT")
519 hapd.request("DISABLE")
520 subprocess.call(['iw', 'reg', 'set', '00'])
521 dev[0].flush_scan_cache()
522 dev[1].flush_scan_cache()
524 def test_tdls_chan_switch(dev, apdev):
525 """Open AP and two stations using TDLS"""
526 flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
527 if flags & 0x800000000 == 0:
528 raise HwsimSkip("Driver does not support TDLS channel switching")
530 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
531 connect_2sta_open(dev, hapd)
532 setup_tdls(dev[0], dev[1], hapd)
533 if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
534 raise Exception("Failed to enable TDLS channel switching")
535 if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
536 raise Exception("Could not disable TDLS channel switching")
537 if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
538 raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
540 def test_ap_tdls_link_status(dev, apdev):
541 """Check TDLS link status between two stations"""
542 hapd = start_ap_wpa2_psk(apdev[0])
544 connect_2sta_wpa2_psk(dev, hapd)
545 check_tdls_link(dev[0], dev[1], connected=False)
546 setup_tdls(dev[0], dev[1], hapd)
547 check_tdls_link(dev[0], dev[1], connected=True)
548 teardown_tdls(dev[0], dev[1], hapd)
549 check_tdls_link(dev[0], dev[1], connected=False)
550 if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
551 raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")