]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_open.py
tests: AP with open mode and wpa_supplicant ENABLE/DISABLE_NETWORK
[thirdparty/hostap.git] / tests / hwsim / test_ap_open.py
1 # Open mode AP tests
2 # Copyright (c) 2014, Qualcomm Atheros, Inc.
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import logging
8 logger = logging.getLogger()
9 import struct
10 import subprocess
11 import time
12 import os
13
14 import hostapd
15 import hwsim_utils
16 from tshark import run_tshark
17 from utils import alloc_fail
18 from wpasupplicant import WpaSupplicant
19
20 def test_ap_open(dev, apdev):
21 """AP with open mode (no security) configuration"""
22 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
23 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
24 bg_scan_period="0")
25 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
26 if ev is None:
27 raise Exception("No connection event received from hostapd")
28 hwsim_utils.test_connectivity(dev[0], hapd)
29
30 dev[0].request("DISCONNECT")
31 ev = hapd.wait_event([ "AP-STA-DISCONNECTED" ], timeout=5)
32 if ev is None:
33 raise Exception("No disconnection event received from hostapd")
34
35 def test_ap_open_packet_loss(dev, apdev):
36 """AP with open mode configuration and large packet loss"""
37 params = { "ssid": "open",
38 "ignore_probe_probability": "0.5",
39 "ignore_auth_probability": "0.5",
40 "ignore_assoc_probability": "0.5",
41 "ignore_reassoc_probability": "0.5" }
42 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
43 for i in range(0, 3):
44 dev[i].connect("open", key_mgmt="NONE", scan_freq="2412",
45 wait_connect=False)
46 for i in range(0, 3):
47 dev[i].wait_connected(timeout=20)
48
49 def test_ap_open_unknown_action(dev, apdev):
50 """AP with open mode configuration and unknown Action frame"""
51 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
52 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
53 bssid = apdev[0]['bssid']
54 cmd = "MGMT_TX {} {} freq=2412 action=765432".format(bssid, bssid)
55 if "FAIL" in dev[0].request(cmd):
56 raise Exception("Could not send test Action frame")
57 ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
58 if ev is None:
59 raise Exception("Timeout on MGMT-TX-STATUS")
60 if "result=SUCCESS" not in ev:
61 raise Exception("AP did not ack Action frame")
62
63 def test_ap_open_invalid_wmm_action(dev, apdev):
64 """AP with open mode configuration and invalid WMM Action frame"""
65 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
66 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
67 bssid = apdev[0]['bssid']
68 cmd = "MGMT_TX {} {} freq=2412 action=1100".format(bssid, bssid)
69 if "FAIL" in dev[0].request(cmd):
70 raise Exception("Could not send test Action frame")
71 ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
72 if ev is None or "result=SUCCESS" not in ev:
73 raise Exception("AP did not ack Action frame")
74
75 def test_ap_open_reconnect_on_inactivity_disconnect(dev, apdev):
76 """Reconnect to open mode AP after inactivity related disconnection"""
77 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
78 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
79 hapd.request("DEAUTHENTICATE " + dev[0].p2p_interface_addr() + " reason=4")
80 dev[0].wait_disconnected(timeout=5)
81 dev[0].wait_connected(timeout=2, error="Timeout on reconnection")
82
83 def test_ap_open_assoc_timeout(dev, apdev):
84 """AP timing out association"""
85 ssid = "test"
86 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
87 dev[0].scan(freq="2412")
88 hapd.set("ext_mgmt_frame_handling", "1")
89 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
90 wait_connect=False)
91 for i in range(0, 10):
92 req = hapd.mgmt_rx()
93 if req is None:
94 raise Exception("MGMT RX wait timed out")
95 if req['subtype'] == 11:
96 break
97 req = None
98 if not req:
99 raise Exception("Authentication frame not received")
100
101 resp = {}
102 resp['fc'] = req['fc']
103 resp['da'] = req['sa']
104 resp['sa'] = req['da']
105 resp['bssid'] = req['bssid']
106 resp['payload'] = struct.pack('<HHH', 0, 2, 0)
107 hapd.mgmt_tx(resp)
108
109 assoc = 0
110 for i in range(0, 10):
111 req = hapd.mgmt_rx()
112 if req is None:
113 raise Exception("MGMT RX wait timed out")
114 if req['subtype'] == 0:
115 assoc += 1
116 if assoc == 3:
117 break
118 if assoc != 3:
119 raise Exception("Association Request frames not received: assoc=%d" % assoc)
120 hapd.set("ext_mgmt_frame_handling", "0")
121 dev[0].wait_connected(timeout=15)
122
123 def test_ap_open_id_str(dev, apdev):
124 """AP with open mode and id_str"""
125 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
126 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", id_str="foo",
127 wait_connect=False)
128 ev = dev[0].wait_connected(timeout=10)
129 if "id_str=foo" not in ev:
130 raise Exception("CTRL-EVENT-CONNECT did not have matching id_str: " + ev)
131 if dev[0].get_status_field("id_str") != "foo":
132 raise Exception("id_str mismatch")
133
134 def test_ap_open_select_any(dev, apdev):
135 """AP with open mode and select any network"""
136 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
137 id = dev[0].connect("unknown", key_mgmt="NONE", scan_freq="2412",
138 only_add_network=True)
139 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
140 only_add_network=True)
141 dev[0].select_network(id)
142 ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND",
143 "CTRL-EVENT-CONNECTED"], timeout=10)
144 if ev is None:
145 raise Exception("No result reported")
146 if "CTRL-EVENT-CONNECTED" in ev:
147 raise Exception("Unexpected connection")
148
149 dev[0].select_network("any")
150 dev[0].wait_connected(timeout=10)
151
152 def test_ap_open_unexpected_assoc_event(dev, apdev):
153 """AP with open mode and unexpected association event"""
154 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
155 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
156 dev[0].request("DISCONNECT")
157 dev[0].wait_disconnected(timeout=15)
158 dev[0].dump_monitor()
159 # This will be accepted due to matching network
160 subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
161 apdev[0]['bssid']])
162 dev[0].wait_connected(timeout=15)
163 dev[0].dump_monitor()
164
165 dev[0].request("REMOVE_NETWORK all")
166 dev[0].wait_disconnected(timeout=5)
167 dev[0].dump_monitor()
168 # This will result in disconnection due to no matching network
169 subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
170 apdev[0]['bssid']])
171 dev[0].wait_disconnected(timeout=15)
172
173 def test_ap_bss_load(dev, apdev):
174 """AP with open mode (no security) configuration"""
175 hapd = hostapd.add_ap(apdev[0]['ifname'],
176 { "ssid": "open",
177 "bss_load_update_period": "10" })
178 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
179 # this does not really get much useful output with mac80211_hwsim currently,
180 # but run through the channel survey update couple of times
181 for i in range(0, 10):
182 hwsim_utils.test_connectivity(dev[0], hapd)
183 hwsim_utils.test_connectivity(dev[0], hapd)
184 hwsim_utils.test_connectivity(dev[0], hapd)
185 time.sleep(0.15)
186
187 def hapd_out_of_mem(hapd, apdev, count, func):
188 with alloc_fail(hapd, count, func):
189 started = False
190 try:
191 hostapd.add_ap(apdev['ifname'], { "ssid": "open" })
192 started = True
193 except:
194 pass
195 if started:
196 raise Exception("hostapd interface started even with memory allocation failure: " + arg)
197
198 def test_ap_open_out_of_memory(dev, apdev):
199 """hostapd failing to setup interface due to allocation failure"""
200 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
201 hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_alloc_bss_data")
202
203 for i in range(1, 3):
204 hapd_out_of_mem(hapd, apdev[1], i, "hostapd_iface_alloc")
205
206 for i in range(1, 5):
207 hapd_out_of_mem(hapd, apdev[1], i, "hostapd_config_defaults;hostapd_config_alloc")
208
209 hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_config_alloc")
210
211 hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_driver_init")
212
213 for i in range(1, 4):
214 hapd_out_of_mem(hapd, apdev[1], i, "=wpa_driver_nl80211_drv_init")
215
216 # eloop_register_read_sock() call from i802_init()
217 hapd_out_of_mem(hapd, apdev[1], 1, "eloop_sock_table_add_sock;eloop_register_sock;?eloop_register_read_sock;=i802_init")
218
219 # verify that a new interface can still be added when memory allocation does
220 # not fail
221 hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
222
223 def test_bssid_black_white_list(dev, apdev):
224 """BSSID black/white list"""
225 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
226 hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
227
228 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
229 bssid_whitelist=apdev[1]['bssid'])
230 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
231 bssid_blacklist=apdev[1]['bssid'])
232 dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
233 bssid_whitelist="00:00:00:00:00:00/00:00:00:00:00:00",
234 bssid_blacklist=apdev[1]['bssid'])
235 if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
236 raise Exception("dev[0] connected to unexpected AP")
237 if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
238 raise Exception("dev[1] connected to unexpected AP")
239 if dev[2].get_status_field('bssid') != apdev[0]['bssid']:
240 raise Exception("dev[2] connected to unexpected AP")
241 dev[0].request("REMOVE_NETWORK all")
242 dev[1].request("REMOVE_NETWORK all")
243 dev[2].request("REMOVE_NETWORK all")
244
245 dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
246 bssid_whitelist="00:00:00:00:00:00", wait_connect=False)
247 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
248 bssid_whitelist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
249 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
250 bssid_blacklist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
251 if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
252 raise Exception("dev[0] connected to unexpected AP")
253 if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
254 raise Exception("dev[1] connected to unexpected AP")
255 dev[0].request("REMOVE_NETWORK all")
256 dev[1].request("REMOVE_NETWORK all")
257 ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
258 if ev is not None:
259 raise Exception("Unexpected dev[2] connectin")
260 dev[2].request("REMOVE_NETWORK all")
261
262 def test_ap_open_wpas_in_bridge(dev, apdev):
263 """Open mode AP and wpas interface in a bridge"""
264 br_ifname='sta-br0'
265 ifname='wlan5'
266 try:
267 _test_ap_open_wpas_in_bridge(dev, apdev)
268 finally:
269 subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
270 subprocess.call(['brctl', 'delif', br_ifname, ifname])
271 subprocess.call(['brctl', 'delbr', br_ifname])
272 subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
273
274 def _test_ap_open_wpas_in_bridge(dev, apdev):
275 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
276
277 br_ifname='sta-br0'
278 ifname='wlan5'
279 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
280 # First, try a failure case of adding an interface
281 try:
282 wpas.interface_add(ifname, br_ifname=br_ifname)
283 raise Exception("Interface addition succeeded unexpectedly")
284 except Exception, e:
285 if "Failed to add" in str(e):
286 logger.info("Ignore expected interface_add failure due to missing bridge interface: " + str(e))
287 else:
288 raise
289
290 # Next, add the bridge interface and add the interface again
291 subprocess.call(['brctl', 'addbr', br_ifname])
292 subprocess.call(['brctl', 'setfd', br_ifname, '0'])
293 subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
294 subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
295 subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
296 wpas.interface_add(ifname, br_ifname=br_ifname)
297
298 wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
299
300 def test_ap_open_start_disabled(dev, apdev):
301 """AP with open mode and beaconing disabled"""
302 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
303 "start_disabled": "1" })
304 bssid = apdev[0]['bssid']
305
306 dev[0].flush_scan_cache()
307 dev[0].scan(freq=2412, only_new=True)
308 if dev[0].get_bss(bssid) is not None:
309 raise Exception("AP was seen beaconing")
310 if "OK" not in hapd.request("RELOAD"):
311 raise Exception("RELOAD failed")
312 dev[0].scan_for_bss(bssid, freq=2412)
313 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
314
315 def test_ap_open_start_disabled2(dev, apdev):
316 """AP with open mode and beaconing disabled (2)"""
317 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
318 "start_disabled": "1" })
319 bssid = apdev[0]['bssid']
320
321 dev[0].flush_scan_cache()
322 dev[0].scan(freq=2412, only_new=True)
323 if dev[0].get_bss(bssid) is not None:
324 raise Exception("AP was seen beaconing")
325 if "OK" not in hapd.request("UPDATE_BEACON"):
326 raise Exception("UPDATE_BEACON failed")
327 dev[0].scan_for_bss(bssid, freq=2412)
328 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
329 if "OK" not in hapd.request("UPDATE_BEACON"):
330 raise Exception("UPDATE_BEACON failed")
331 dev[0].request("DISCONNECT")
332 dev[0].wait_disconnected()
333 dev[0].request("RECONNECT")
334 dev[0].wait_connected()
335
336 def test_ap_open_ifdown(dev, apdev):
337 """AP with open mode and external ifconfig down"""
338 params = { "ssid": "open",
339 "ap_max_inactivity": "1" }
340 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
341 bssid = apdev[0]['bssid']
342
343 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
344 dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
345 subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'down'])
346 ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=10)
347 if ev is None:
348 raise Exception("Timeout on AP-STA-DISCONNECTED (1)")
349 ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=5)
350 if ev is None:
351 raise Exception("Timeout on AP-STA-DISCONNECTED (2)")
352 ev = hapd.wait_event(["INTERFACE-DISABLED"], timeout=5)
353 if ev is None:
354 raise Exception("No INTERFACE-DISABLED event")
355 # The following wait tests beacon loss detection in mac80211 on dev0.
356 # dev1 is used to test stopping of AP side functionality on client polling.
357 dev[1].request("REMOVE_NETWORK all")
358 subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'up'])
359 dev[0].wait_disconnected()
360 dev[1].wait_disconnected()
361 ev = hapd.wait_event(["INTERFACE-ENABLED"], timeout=10)
362 if ev is None:
363 raise Exception("No INTERFACE-ENABLED event")
364 dev[0].wait_connected()
365 hwsim_utils.test_connectivity(dev[0], hapd)
366
367 def test_ap_open_disconnect_in_ps(dev, apdev, params):
368 """Disconnect with the client in PS to regression-test a kernel bug"""
369 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
370 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
371 bg_scan_period="0")
372 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
373 if ev is None:
374 raise Exception("No connection event received from hostapd")
375
376 time.sleep(0.2)
377 hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_MANUAL_POLL)
378 try:
379 # inject some traffic
380 sa = hapd.own_addr()
381 da = dev[0].own_addr()
382 hapd.request('DATA_TEST_CONFIG 1')
383 hapd.request('DATA_TEST_TX {} {} 0'.format(da, sa))
384 hapd.request('DATA_TEST_CONFIG 0')
385
386 # let the AP send couple of Beacon frames
387 time.sleep(0.3)
388
389 # disconnect - with traffic pending - shouldn't cause kernel warnings
390 dev[0].request("DISCONNECT")
391 finally:
392 hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_DISABLED)
393
394 time.sleep(0.2)
395 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
396 "wlan_mgt.tim.partial_virtual_bitmap",
397 ["wlan_mgt.tim.partial_virtual_bitmap"])
398 if out is not None:
399 state = 0
400 for l in out.splitlines():
401 pvb = int(l, 16)
402 if pvb > 0 and state == 0:
403 state = 1
404 elif pvb == 0 and state == 1:
405 state = 2
406 if state != 2:
407 raise Exception("Didn't observe TIM bit getting set and unset (state=%d)" % state)
408
409 def test_ap_open_select_network(dev, apdev):
410 """Open mode connection and SELECT_NETWORK to change network"""
411 hapd1 = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
412 bssid1 = apdev[0]['bssid']
413 hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open2" })
414 bssid2 = apdev[1]['bssid']
415
416 id1 = dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
417 only_add_network=True)
418 id2 = dev[0].connect("open2", key_mgmt="NONE", scan_freq="2412")
419 hwsim_utils.test_connectivity(dev[0], hapd2)
420
421 dev[0].select_network(id1)
422 dev[0].wait_connected()
423 res = dev[0].request("BLACKLIST")
424 if bssid1 in res or bssid2 in res:
425 raise Exception("Unexpected blacklist entry")
426 hwsim_utils.test_connectivity(dev[0], hapd1)
427
428 dev[0].select_network(id2)
429 dev[0].wait_connected()
430 hwsim_utils.test_connectivity(dev[0], hapd2)
431 res = dev[0].request("BLACKLIST")
432 if bssid1 in res or bssid2 in res:
433 raise Exception("Unexpected blacklist entry(2)")
434
435 def test_ap_open_disable_enable(dev, apdev):
436 """AP with open mode getting disabled and re-enabled"""
437 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
438 dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
439 bg_scan_period="0")
440
441 for i in range(2):
442 hapd.request("DISABLE")
443 dev[0].wait_disconnected()
444 hapd.request("ENABLE")
445 dev[0].wait_connected()
446 hwsim_utils.test_connectivity(dev[0], hapd)
447
448 def sta_enable_disable(dev, bssid):
449 dev.scan_for_bss(bssid, freq=2412)
450 work_id = dev.request("RADIO_WORK add block-work")
451 ev = dev.wait_event(["EXT-RADIO-WORK-START"])
452 if ev is None:
453 raise Exception("Timeout while waiting radio work to start")
454 id = dev.connect("open", key_mgmt="NONE", scan_freq="2412",
455 only_add_network=True)
456 dev.request("ENABLE_NETWORK %d" % id)
457 if "connect@" not in dev.request("RADIO_WORK show"):
458 raise Exception("connect radio work missing")
459 dev.request("DISABLE_NETWORK %d" % id)
460 dev.request("RADIO_WORK done " + work_id)
461
462 ok = False
463 for i in range(30):
464 if "connect@" not in dev.request("RADIO_WORK show"):
465 ok = True
466 break
467 time.sleep(0.1)
468 if not ok:
469 raise Exception("connect radio work not completed")
470 ev = dev.wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
471 if ev is not None:
472 raise Exception("Unexpected connection")
473 dev.request("DISCONNECT")
474
475 def test_ap_open_sta_enable_disable(dev, apdev):
476 """AP with open mode and wpa_supplicant ENABLE/DISABLE_NETWORK"""
477 hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
478 bssid = apdev[0]['bssid']
479
480 sta_enable_disable(dev[0], bssid)
481
482 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
483 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
484 sta_enable_disable(wpas, bssid)