Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / tests / hwsim / test_ap_tdls.py
1 # TDLS tests
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import time
8 import logging
9 logger = logging.getLogger()
10 import subprocess
11
12 import hwsim_utils
13 from hostapd import HostapdGlobal
14 from hostapd import Hostapd
15 import hostapd
16 from utils import HwsimSkip, skip_with_fips
17 from wlantest import Wlantest
18
19 def start_ap_wpa2_psk(ifname):
20     params = hostapd.wpa2_params(ssid="test-wpa2-psk", passphrase="12345678")
21     return hostapd.add_ap(ifname, params)
22
23 def connectivity(dev, hapd):
24     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
25     hwsim_utils.test_connectivity(dev[0], hapd)
26     hwsim_utils.test_connectivity(dev[1], hapd)
27
28 def connect_2sta(dev, ssid, hapd):
29     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
30     dev[1].connect(ssid, psk="12345678", scan_freq="2412")
31     connectivity(dev, hapd)
32
33 def connect_2sta_wpa2_psk(dev, hapd):
34     connect_2sta(dev, "test-wpa2-psk", hapd)
35
36 def connect_2sta_wpa_psk(dev, hapd):
37     connect_2sta(dev, "test-wpa-psk", hapd)
38
39 def connect_2sta_wpa_psk_mixed(dev, hapd):
40     dev[0].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA",
41                    scan_freq="2412")
42     dev[1].connect("test-wpa-mixed-psk", psk="12345678", proto="WPA2",
43                    scan_freq="2412")
44     connectivity(dev, hapd)
45
46 def connect_2sta_wep(dev, hapd):
47     dev[0].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
48                    scan_freq="2412")
49     dev[1].connect("test-wep", key_mgmt="NONE", wep_key0='"hello"',
50                    scan_freq="2412")
51     connectivity(dev, hapd)
52
53 def connect_2sta_open(dev, hapd, scan_freq="2412"):
54     dev[0].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
55     dev[1].connect("test-open", key_mgmt="NONE", scan_freq=scan_freq)
56     connectivity(dev, hapd)
57
58 def wlantest_setup():
59     wt = Wlantest()
60     wt.flush()
61     wt.add_passphrase("12345678")
62     wt.add_wepkey("68656c6c6f")
63
64 def wlantest_tdls_packet_counters(bssid, addr0, addr1):
65     wt = Wlantest()
66     dl = wt.get_tdls_counter("valid_direct_link", bssid, addr0, addr1)
67     inv_dl = wt.get_tdls_counter("invalid_direct_link", bssid, addr0, addr1)
68     ap = wt.get_tdls_counter("valid_ap_path", bssid, addr0, addr1)
69     inv_ap = wt.get_tdls_counter("invalid_ap_path", bssid, addr0, addr1)
70     return [dl,inv_dl,ap,inv_ap]
71
72 def tdls_check_dl(sta0, sta1, bssid, addr0, addr1):
73     wt = Wlantest()
74     wt.tdls_clear(bssid, addr0, addr1)
75     hwsim_utils.test_connectivity_sta(sta0, sta1)
76     [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
77     if dl == 0:
78         raise Exception("No valid frames through direct link")
79     if inv_dl > 0:
80         raise Exception("Invalid frames through direct link")
81     if ap > 0:
82         raise Exception("Unexpected frames through AP path")
83     if inv_ap > 0:
84         raise Exception("Invalid frames through AP path")
85
86 def tdls_check_ap(sta0, sta1, bssid, addr0, addr1):
87     wt = Wlantest()
88     wt.tdls_clear(bssid, addr0, addr1);
89     hwsim_utils.test_connectivity_sta(sta0, sta1)
90     [dl,inv_dl,ap,inv_ap] = wlantest_tdls_packet_counters(bssid, addr0, addr1)
91     if dl > 0:
92         raise Exception("Unexpected frames through direct link")
93     if inv_dl > 0:
94         raise Exception("Invalid frames through direct link")
95     if ap == 0:
96         raise Exception("No valid frames through AP path")
97     if inv_ap > 0:
98         raise Exception("Invalid frames through AP path")
99
100 def check_connectivity(sta0, sta1, hapd):
101     hwsim_utils.test_connectivity_sta(sta0, sta1)
102     hwsim_utils.test_connectivity(sta0, hapd)
103     hwsim_utils.test_connectivity(sta1, hapd)
104
105 def setup_tdls(sta0, sta1, ap, reverse=False, expect_fail=False):
106     logger.info("Setup TDLS")
107     hapd = hostapd.Hostapd(ap['ifname'])
108     check_connectivity(sta0, sta1, hapd)
109     bssid = ap['bssid']
110     addr0 = sta0.p2p_interface_addr()
111     addr1 = sta1.p2p_interface_addr()
112     wt = Wlantest()
113     wt.tdls_clear(bssid, addr0, addr1);
114     wt.tdls_clear(bssid, addr1, addr0);
115     sta0.tdls_setup(addr1)
116     time.sleep(1)
117     if expect_fail:
118         tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
119         return
120     if reverse:
121         addr1 = sta0.p2p_interface_addr()
122         addr0 = sta1.p2p_interface_addr()
123     conf = wt.get_tdls_counter("setup_conf_ok", bssid, addr0, addr1);
124     if conf == 0:
125         raise Exception("No TDLS Setup Confirm (success) seen")
126     tdls_check_dl(sta0, sta1, bssid, addr0, addr1)
127     check_connectivity(sta0, sta1, hapd)
128
129 def teardown_tdls(sta0, sta1, ap, responder=False, wildcard=False):
130     logger.info("Teardown TDLS")
131     hapd = hostapd.Hostapd(ap['ifname'])
132     check_connectivity(sta0, sta1, hapd)
133     bssid = ap['bssid']
134     addr0 = sta0.p2p_interface_addr()
135     addr1 = sta1.p2p_interface_addr()
136     if responder:
137         sta1.tdls_teardown(addr0)
138     elif wildcard:
139         sta0.tdls_teardown("*")
140     else:
141         sta0.tdls_teardown(addr1)
142     time.sleep(1)
143     wt = Wlantest()
144     teardown = wt.get_tdls_counter("teardown", bssid, addr0, addr1);
145     if teardown == 0:
146         raise Exception("No TDLS Setup Teardown seen")
147     tdls_check_ap(sta0, sta1, bssid, addr0, addr1)
148     check_connectivity(sta0, sta1, hapd)
149
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:
160         if not connected:
161             raise Exception("Expected TDLS link status NOT to be connected")
162     else:
163         if connected:
164             raise Exception("Expected TDLS link status to be connected")
165
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]['ifname'])
169     wlantest_setup()
170     connect_2sta_wpa2_psk(dev, hapd)
171     dev[0].request("TDLS_DISCOVER " + dev[1].p2p_interface_addr())
172     time.sleep(0.2)
173
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]['ifname'])
177     wlantest_setup()
178     connect_2sta_wpa2_psk(dev, hapd)
179     setup_tdls(dev[0], dev[1], apdev[0])
180     teardown_tdls(dev[0], dev[1], apdev[0])
181     setup_tdls(dev[1], dev[0], apdev[0])
182     #teardown_tdls(dev[0], dev[1], apdev[0])
183
184 def test_ap_wpa2_tdls_concurrent_init(dev, apdev):
185     """Concurrent TDLS setup initiation"""
186     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
187     wlantest_setup()
188     connect_2sta_wpa2_psk(dev, hapd)
189     dev[0].request("SET tdls_testing 0x80")
190     setup_tdls(dev[1], dev[0], apdev[0], reverse=True)
191
192 def test_ap_wpa2_tdls_concurrent_init2(dev, apdev):
193     """Concurrent TDLS setup initiation (reverse)"""
194     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
195     wlantest_setup()
196     connect_2sta_wpa2_psk(dev, hapd)
197     dev[1].request("SET tdls_testing 0x80")
198     setup_tdls(dev[0], dev[1], apdev[0])
199
200 def test_ap_wpa2_tdls_decline_resp(dev, apdev):
201     """Decline TDLS Setup Response"""
202     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
203     wlantest_setup()
204     connect_2sta_wpa2_psk(dev, hapd)
205     dev[1].request("SET tdls_testing 0x200")
206     setup_tdls(dev[1], dev[0], apdev[0], expect_fail=True)
207
208 def test_ap_wpa2_tdls_long_lifetime(dev, apdev):
209     """TDLS with long TPK lifetime"""
210     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
211     wlantest_setup()
212     connect_2sta_wpa2_psk(dev, hapd)
213     dev[1].request("SET tdls_testing 0x40")
214     setup_tdls(dev[1], dev[0], apdev[0])
215
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]['ifname'])
219     wlantest_setup()
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], apdev[0])
224     teardown_tdls(dev[1], dev[0], apdev[0])
225     setup_tdls(dev[0], dev[1], apdev[0])
226
227 def test_ap_wpa2_tdls_reneg(dev, apdev):
228     """Renegotiate TDLS link"""
229     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
230     wlantest_setup()
231     connect_2sta_wpa2_psk(dev, hapd)
232     setup_tdls(dev[1], dev[0], apdev[0])
233     setup_tdls(dev[0], dev[1], apdev[0])
234
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]['ifname'])
238     wlantest_setup()
239     connect_2sta_wpa2_psk(dev, hapd)
240     dev[1].request("SET tdls_testing 0x10")
241     setup_tdls(dev[0], dev[1], apdev[0], expect_fail=True)
242
243 def test_ap_wpa2_tdls_diff_rsnie(dev, apdev):
244     """TDLS with different RSN IEs"""
245     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
246     wlantest_setup()
247     connect_2sta_wpa2_psk(dev, hapd)
248     dev[1].request("SET tdls_testing 0x2")
249     setup_tdls(dev[1], dev[0], apdev[0])
250     teardown_tdls(dev[1], dev[0], apdev[0])
251
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]['ifname'])
255     wlantest_setup()
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)
260     time.sleep(1)
261
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]['ifname'])
265     wlantest_setup()
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)
270     time.sleep(1)
271
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]['ifname'],
276                           hostapd.wpa_params(ssid="test-wpa-psk",
277                                              passphrase="12345678"))
278     wlantest_setup()
279     connect_2sta_wpa_psk(dev, hapd)
280     setup_tdls(dev[0], dev[1], apdev[0])
281     teardown_tdls(dev[0], dev[1], apdev[0])
282     setup_tdls(dev[1], dev[0], apdev[0])
283
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]['ifname'],
288                           hostapd.wpa_mixed_params(ssid="test-wpa-mixed-psk",
289                                                    passphrase="12345678"))
290     wlantest_setup()
291     connect_2sta_wpa_psk_mixed(dev, hapd)
292     setup_tdls(dev[0], dev[1], apdev[0])
293     teardown_tdls(dev[0], dev[1], apdev[0])
294     setup_tdls(dev[1], dev[0], apdev[0])
295
296 def test_ap_wep_tdls(dev, apdev):
297     """WEP AP and two stations using TDLS"""
298     hapd = hostapd.add_ap(apdev[0]['ifname'],
299                           { "ssid": "test-wep", "wep_key0": '"hello"' })
300     wlantest_setup()
301     connect_2sta_wep(dev, hapd)
302     setup_tdls(dev[0], dev[1], apdev[0])
303     teardown_tdls(dev[0], dev[1], apdev[0])
304     setup_tdls(dev[1], dev[0], apdev[0])
305
306 def test_ap_open_tdls(dev, apdev):
307     """Open AP and two stations using TDLS"""
308     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-open" })
309     wlantest_setup()
310     connect_2sta_open(dev, hapd)
311     setup_tdls(dev[0], dev[1], apdev[0])
312     teardown_tdls(dev[0], dev[1], apdev[0])
313     setup_tdls(dev[1], dev[0], apdev[0])
314     teardown_tdls(dev[1], dev[0], apdev[0], wildcard=True)
315
316 def test_ap_wpa2_tdls_bssid_mismatch(dev, apdev):
317     """TDLS failure due to BSSID mismatch"""
318     try:
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]['ifname'], params)
324         hostapd.add_ap(apdev[1]['ifname'], params)
325         wlantest_setup()
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")
335
336         addr0 = dev[0].p2p_interface_addr()
337         dev[1].tdls_setup(addr0)
338         time.sleep(1)
339         hwsim_utils.test_connectivity_sta(dev[0], dev[1])
340     finally:
341         subprocess.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'])
342         subprocess.call(['brctl', 'delbr', 'ap-br0'])
343
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]['ifname'])
347     wlantest_setup()
348     connect_2sta_wpa2_psk(dev, hapd)
349     setup_tdls(dev[0], dev[1], apdev[0])
350     teardown_tdls(dev[0], dev[1], apdev[0], responder=True)
351
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",
356                "hw_mode": "a",
357                "channel": "36",
358                "ieee80211n": "1",
359                "ieee80211ac": "1",
360                "ht_capab": "",
361                "vht_capab": "",
362                "vht_oper_chwidth": "0",
363                "vht_oper_centr_freq_seg0_idx": "0" }
364     try:
365         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
366         wlantest_setup()
367         connect_2sta_open(dev, hapd, scan_freq="5180")
368         setup_tdls(dev[0], dev[1], apdev[0])
369         teardown_tdls(dev[0], dev[1], apdev[0])
370         setup_tdls(dev[1], dev[0], apdev[0])
371         teardown_tdls(dev[1], dev[0], apdev[0], wildcard=True)
372     finally:
373         dev[0].request("DISCONNECT")
374         dev[1].request("DISCONNECT")
375         if hapd:
376             hapd.request("DISABLE")
377         subprocess.call(['iw', 'reg', 'set', '00'])
378         dev[0].flush_scan_cache()
379         dev[1].flush_scan_cache()
380
381 def test_tdls_chan_switch(dev, apdev):
382     """Open AP and two stations using TDLS"""
383     flags = int(dev[0].get_driver_status_field('capa.flags'), 16)
384     if flags & 0x800000000 == 0:
385         raise HwsimSkip("Driver does not support TDLS channel switching")
386
387     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "test-open" })
388     connect_2sta_open(dev, hapd)
389     setup_tdls(dev[0], dev[1], apdev[0])
390     if "OK" not in dev[0].request("TDLS_CHAN_SWITCH " + dev[1].own_addr() + " 81 2462"):
391         raise Exception("Failed to enable TDLS channel switching")
392     if "OK" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
393         raise Exception("Could not disable TDLS channel switching")
394     if "FAIL" not in dev[0].request("TDLS_CANCEL_CHAN_SWITCH " + dev[1].own_addr()):
395         raise Exception("TDLS_CANCEL_CHAN_SWITCH accepted even though channel switching was already disabled")
396
397 def test_ap_tdls_link_status(dev, apdev):
398     """Check TDLS link status between two stations"""
399     hapd = start_ap_wpa2_psk(apdev[0]['ifname'])
400     wlantest_setup()
401     connect_2sta_wpa2_psk(dev, hapd)
402     check_tdls_link(dev[0], dev[1], connected=False)
403     setup_tdls(dev[0], dev[1], apdev[0])
404     check_tdls_link(dev[0], dev[1], connected=True)
405     teardown_tdls(dev[0], dev[1], apdev[0])
406     check_tdls_link(dev[0], dev[1], connected=False)
407     if "FAIL" not in dev[0].request("TDLS_LINK_STATUS foo"):
408         raise Exception("Unexpected TDLS_LINK_STATUS response for invalid argument")