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, ap, reverse=False, expect_fail=False):
107 logger.info("Setup TDLS")
108 hapd = hostapd.Hostapd(ap['ifname'])
109 check_connectivity(sta0, sta1, hapd)
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, ap, responder=False, wildcard=False):
131 logger.info("Teardown TDLS")
132 hapd = hostapd.Hostapd(ap['ifname'])
133 check_connectivity(sta0, sta1, hapd)
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")
167 def test_ap_tdls_discovery(dev, apdev):
168 """WPA2-PSK AP and two stations using TDLS discovery"""
169 hapd = start_ap_wpa2_psk(apdev[0])
171 connect_2sta_wpa2_psk(dev, hapd)
172 dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr())
175 def test_ap_wpa2_tdls(dev, apdev):
176 """WPA2-PSK AP and two stations using TDLS"""
177 hapd = start_ap_wpa2_psk(apdev[0])
179 connect_2sta_wpa2_psk(dev, hapd)
180 setup_tdls(dev[0], dev[1], apdev[0])
181 teardown_tdls(dev[0], dev[1], apdev[0])
182 setup_tdls(dev[1], dev[0], apdev[0])
183 #teardown_tdls(dev[0], dev[1], apdev[0])
185 def test_ap_wpa2_tdls_concurrent_init(dev, apdev):
186 """Concurrent TDLS setup initiation"""
187 hapd = start_ap_wpa2_psk(apdev[0])
189 connect_2sta_wpa2_psk(dev, hapd)
190 dev[0].request("SET tdls_testing 0x80")
191 setup_tdls(dev[1], dev[0], apdev[0], reverse=True)
193 def test_ap_wpa2_tdls_concurrent_init2(dev, apdev):
194 """Concurrent TDLS setup initiation (reverse)"""
195 hapd = start_ap_wpa2_psk(apdev[0])
197 connect_2sta_wpa2_psk(dev, hapd)
198 dev[1].request("SET tdls_testing 0x80")
199 setup_tdls(dev[0], dev[1], apdev[0])
201 def test_ap_wpa2_tdls_decline_resp(dev, apdev):
202 """Decline TDLS Setup Response"""
203 hapd = start_ap_wpa2_psk(apdev[0])
205 connect_2sta_wpa2_psk(dev, hapd)
206 dev[1].request("SET tdls_testing 0x200")
207 setup_tdls(dev[1], dev[0], apdev[0], expect_fail=True)
209 def test_ap_wpa2_tdls_long_lifetime(dev, apdev):
210 """TDLS with long TPK lifetime"""
211 hapd = start_ap_wpa2_psk(apdev[0])
213 connect_2sta_wpa2_psk(dev, hapd)
214 dev[1].request("SET tdls_testing 0x40")
215 setup_tdls(dev[1], dev[0], apdev[0])
217 def test_ap_wpa2_tdls_long_frame(dev, apdev):
218 """TDLS with long setup/teardown frames"""
219 hapd = start_ap_wpa2_psk(apdev[0])
221 connect_2sta_wpa2_psk(dev, hapd)
222 dev[0].request("SET tdls_testing 0x1")
223 dev[1].request("SET tdls_testing 0x1")
224 setup_tdls(dev[1], dev[0], apdev[0])
225 teardown_tdls(dev[1], dev[0], apdev[0])
226 setup_tdls(dev[0], dev[1], apdev[0])
228 def test_ap_wpa2_tdls_reneg(dev, apdev):
229 """Renegotiate TDLS link"""
230 hapd = start_ap_wpa2_psk(apdev[0])
232 connect_2sta_wpa2_psk(dev, hapd)
233 setup_tdls(dev[1], dev[0], apdev[0])
234 setup_tdls(dev[0], dev[1], apdev[0])
236 def test_ap_wpa2_tdls_wrong_lifetime_resp(dev, apdev):
237 """Incorrect TPK lifetime in TDLS Setup Response"""
238 hapd = start_ap_wpa2_psk(apdev[0])
240 connect_2sta_wpa2_psk(dev, hapd)
241 dev[1].request("SET tdls_testing 0x10")
242 setup_tdls(dev[0], dev[1], apdev[0], expect_fail=True)
244 def test_ap_wpa2_tdls_diff_rsnie(dev, apdev):
245 """TDLS with different RSN IEs"""
246 hapd = start_ap_wpa2_psk(apdev[0])
248 connect_2sta_wpa2_psk(dev, hapd)
249 dev[1].request("SET tdls_testing 0x2")
250 setup_tdls(dev[1], dev[0], apdev[0])
251 teardown_tdls(dev[1], dev[0], apdev[0])
253 def test_ap_wpa2_tdls_wrong_tpk_m2_mic(dev, apdev):
254 """Incorrect MIC in TDLS Setup Response"""
255 hapd = start_ap_wpa2_psk(apdev[0])
257 connect_2sta_wpa2_psk(dev, hapd)
258 dev[0].request("SET tdls_testing 0x800")
259 addr0 = dev[0].p2p_interface_addr()
260 dev[1].tdls_setup(addr0)
263 def test_ap_wpa2_tdls_wrong_tpk_m3_mic(dev, apdev):
264 """Incorrect MIC in TDLS Setup Confirm"""
265 hapd = start_ap_wpa2_psk(apdev[0])
267 connect_2sta_wpa2_psk(dev, hapd)
268 dev[1].request("SET tdls_testing 0x800")
269 addr0 = dev[0].p2p_interface_addr()
270 dev[1].tdls_setup(addr0)
273 def test_ap_wpa_tdls(dev, apdev):
274 """WPA-PSK AP and two stations using TDLS"""
275 skip_with_fips(dev[0])
276 hapd = hostapd.add_ap(apdev[0],
277 hostapd.wpa_params(ssid="test-wpa-psk",
278 passphrase="12345678"))
280 connect_2sta_wpa_psk(dev, hapd)
281 setup_tdls(dev[0], dev[1], apdev[0])
282 teardown_tdls(dev[0], dev[1], apdev[0])
283 setup_tdls(dev[1], dev[0], apdev[0])
285 def test_ap_wpa_mixed_tdls(dev, apdev):
286 """WPA+WPA2-PSK AP and two stations using TDLS"""
287 skip_with_fips(dev[0])
288 hapd = hostapd.add_ap(apdev[0],
289 hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk",
290 passphrase="12345678"))
292 connect_2sta_wpa_psk_mixed(dev, hapd)
293 setup_tdls(dev[0], dev[1], apdev[0])
294 teardown_tdls(dev[0], dev[1], apdev[0])
295 setup_tdls(dev[1], dev[0], apdev[0])
297 def test_ap_wep_tdls(dev, apdev):
298 """WEP AP and two stations using TDLS"""
299 hapd = hostapd.add_ap(apdev[0],
300 { "ssid": "test-wep", "wep_key0": '"hello"' })
302 connect_2sta_wep(dev, hapd)
303 setup_tdls(dev[0], dev[1], apdev[0])
304 teardown_tdls(dev[0], dev[1], apdev[0])
305 setup_tdls(dev[1], dev[0], apdev[0])
307 def test_ap_open_tdls(dev, apdev):
308 """Open AP and two stations using TDLS"""
309 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
311 connect_2sta_open(dev, hapd)
312 setup_tdls(dev[0], dev[1], apdev[0])
313 teardown_tdls(dev[0], dev[1], apdev[0])
314 setup_tdls(dev[1], dev[0], apdev[0])
315 teardown_tdls(dev[1], dev[0], apdev[0], wildcard=True)
317 def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev):
318 """TDLS failure due to BSSID mismatch"""
320 ssid = "test-wpa2-psk"
321 passphrase = "12345678"
322 params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
323 params['bridge'] = 'ap-br0'
324 hapd = hostapd.add_ap(apdev[0], params)
325 hostapd.add_ap(apdev[1], params)
327 subprocess.call(['brctl', 'setfd', 'ap-br0', '0'])
328 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
329 dev[0].connect(ssid, psk=passphrase, scan_freq="2412",
330 bssid=apdev[0]['bssid'])
331 dev[1].connect(ssid, psk=passphrase, scan_freq="2412",
332 bssid=apdev[1]['bssid'])
333 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
334 hwsim_utils.test_connectivity_iface(dev[0], hapd, "ap-br0")
335 hwsim_utils.test_connectivity_iface(dev[1], hapd, "ap-br0")
337 addr0 = dev[0].p2p_interface_addr()
338 dev[1].tdls_setup(addr0)
340 hwsim_utils.test_connectivity_sta(dev[0], dev[1])
342 subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
343 subprocess.call(['brctl', 'delbr', 'ap-br0'])
345 def test_ap_wpa2_tdls_responder_teardown(dev, apdev):
346 """TDLS teardown from responder with WPA2-PSK AP"""
347 hapd = start_ap_wpa2_psk(apdev[0])
349 connect_2sta_wpa2_psk(dev, hapd)
350 setup_tdls(dev[0], dev[1], apdev[0])
351 teardown_tdls(dev[0], dev[1], apdev[0], responder=True)
353 def test_ap_open_tdls_vht(dev, apdev):
354 """Open AP and two stations using TDLS"""
355 params = { "ssid": "test-open",
356 "country_code": "DE",
363 "vht_oper_chwidth": "0",
364 "vht_oper_centr_freq_seg0_idx": "0" }
366 hapd = hostapd.add_ap(apdev[0], params)
368 connect_2sta_open(dev, hapd, scan_freq="5180")
369 setup_tdls(dev[0], dev[1], apdev[0])
370 teardown_tdls(dev[0], dev[1], apdev[0])
371 setup_tdls(dev[1], dev[0], apdev[0])
372 teardown_tdls(dev[1], dev[0], apdev[0], wildcard=True)
374 dev[0].request("DISCONNECT")
375 dev[1].request("DISCONNECT")
377 hapd.request("DISABLE")
378 subprocess.call(['iw', 'reg', 'set', '00'])
379 dev[0].flush_scan_cache()
380 dev[1].flush_scan_cache()
382 def test_ap_open_tdls_vht80(dev, apdev):
383 """Open AP and two stations using TDLS with VHT 80"""
384 params = { "ssid": "test-open",
385 "country_code": "US",
388 "ht_capab": "[HT40+]",
392 "vht_oper_chwidth": "1",
393 "vht_oper_centr_freq_seg0_idx": "42" }
396 hapd = hostapd.add_ap(apdev[0], params)
398 connect_2sta_open(dev, hapd, scan_freq="5180")
399 sig = dev[0].request("SIGNAL_POLL").splitlines()
400 if "WIDTH=80 MHz" not in sig:
401 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
402 setup_tdls(dev[0], dev[1], apdev[0])
404 check_connectivity(dev[0], dev[1], hapd)
406 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
407 stdout=subprocess.PIPE)
408 res = cmd.stdout.read()
410 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
412 if isinstance(e, Exception) and str(e) == "AP startup failed":
413 if not vht_supported():
414 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
417 dev[0].request("DISCONNECT")
418 dev[1].request("DISCONNECT")
420 hapd.request("DISABLE")
421 subprocess.call(['iw', 'reg', 'set', '00'])
422 dev[0].flush_scan_cache()
423 dev[1].flush_scan_cache()
425 def test_ap_open_tdls_vht80plus80(dev, apdev):
426 """Open AP and two stations using TDLS with VHT 80+80"""
427 params = { "ssid": "test-open",
428 "country_code": "US",
431 "ht_capab": "[HT40+]",
435 "vht_oper_chwidth": "3",
436 "vht_oper_centr_freq_seg0_idx": "42",
437 "vht_oper_centr_freq_seg1_idx": "155" }
440 hapd = hostapd.add_ap(apdev[0], params)
442 connect_2sta_open(dev, hapd, scan_freq="5180")
443 sig = dev[0].request("SIGNAL_POLL").splitlines()
444 if "FREQUENCY=5180" not in sig:
445 raise Exception("Unexpected SIGNAL_POLL value(1): " + str(sig))
446 if "WIDTH=80+80 MHz" not in sig:
447 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
448 if "CENTER_FRQ1=5210" not in sig:
449 raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig))
450 if "CENTER_FRQ2=5775" not in sig:
451 raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig))
452 setup_tdls(dev[0], dev[1], apdev[0])
454 check_connectivity(dev[0], dev[1], hapd)
456 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
457 stdout=subprocess.PIPE)
458 res = cmd.stdout.read()
460 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
462 if isinstance(e, Exception) and str(e) == "AP startup failed":
463 if not vht_supported():
464 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
467 dev[0].request("DISCONNECT")
468 dev[1].request("DISCONNECT")
470 hapd.request("DISABLE")
471 subprocess.call(['iw', 'reg', 'set', '00'])
472 dev[0].flush_scan_cache()
473 dev[1].flush_scan_cache()
475 def test_ap_open_tdls_vht160(dev, apdev):
476 """Open AP and two stations using TDLS with VHT 160"""
477 params = { "ssid": "test-open",
478 "country_code": "ZA",
481 "ht_capab": "[HT40-]",
484 "vht_oper_chwidth": "2",
485 "vht_oper_centr_freq_seg0_idx": "114" }
488 hapd = hostapd.add_ap(apdev[0], params, wait_enabled=False)
489 ev = hapd.wait_event(["AP-ENABLED"], timeout=2)
491 cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE)
492 reg = cmd.stdout.readlines()
494 if "5490" in r and "DFS" in r:
495 raise HwsimSkip("ZA regulatory rule did not have DFS requirement removed")
496 raise Exception("AP setup timed out")
498 connect_2sta_open(dev, hapd, scan_freq="5520")
499 sig = dev[0].request("SIGNAL_POLL").splitlines()
500 if "WIDTH=160 MHz" not in sig:
501 raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig))
502 setup_tdls(dev[0], dev[1], apdev[0])
504 check_connectivity(dev[0], dev[1], hapd)
506 cmd = subprocess.Popen(['iw', dev[0].ifname, 'station', 'dump'],
507 stdout=subprocess.PIPE)
508 res = cmd.stdout.read()
510 logger.info("Station dump on dev[%d]:\n%s" % (i, res))
512 if isinstance(e, Exception) and str(e) == "AP startup failed":
513 if not vht_supported():
514 raise HwsimSkip("80/160 MHz channel not supported in regulatory information")
517 dev[0].request("DISCONNECT")
518 dev[1].request("DISCONNECT")
520 hapd.request("DISABLE")
521 subprocess.call(['iw', 'reg', 'set', '00'])
522 dev[0].flush_scan_cache()
523 dev[1].flush_scan_cache()
525 def test_tdls_chan_switch(dev, apdev):
526 """Open AP and two stations using TDLS"""
527 flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
528 if flags & 0x800000000 == 0:
529 raise HwsimSkip("Driver does not support TDLS channel switching")
531 hapd = hostapd.add_ap(apdev[0], { "ssid": "test-open" })
532 connect_2sta_open(dev, hapd)
533 setup_tdls(dev[0], dev[1], apdev[0])
534 if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
535 raise Exception("Failed to enable TDLS channel switching")
536 if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
537 raise Exception("Could not disable TDLS channel switching")
538 if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
539 raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
541 def test_ap_tdls_link_status(dev, apdev):
542 """Check TDLS link status between two stations"""
543 hapd = start_ap_wpa2_psk(apdev[0])
545 connect_2sta_wpa2_psk(dev, hapd)
546 check_tdls_link(dev[0], dev[1], connected=False)
547 setup_tdls(dev[0], dev[1], apdev[0])
548 check_tdls_link(dev[0], dev[1], connected=True)
549 teardown_tdls(dev[0], dev[1], apdev[0])
550 check_tdls_link(dev[0], dev[1], connected=False)
551 if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
552 raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")