test_ap_open.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. import logging
  7. logger = logging.getLogger()
  8. import struct
  9. import subprocess
  10. import time
  11. import os
  12. import hostapd
  13. import hwsim_utils
  14. from tshark import run_tshark
  15. from utils import alloc_fail
  16. from wpasupplicant import WpaSupplicant
  17. def test_ap_open(dev, apdev):
  18. """AP with open mode (no security) configuration"""
  19. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  20. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  21. bg_scan_period="0")
  22. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  23. if ev is None:
  24. raise Exception("No connection event received from hostapd")
  25. hwsim_utils.test_connectivity(dev[0], hapd)
  26. dev[0].request("DISCONNECT")
  27. ev = hapd.wait_event([ "AP-STA-DISCONNECTED" ], timeout=5)
  28. if ev is None:
  29. raise Exception("No disconnection event received from hostapd")
  30. def test_ap_open_packet_loss(dev, apdev):
  31. """AP with open mode configuration and large packet loss"""
  32. params = { "ssid": "open",
  33. "ignore_probe_probability": "0.5",
  34. "ignore_auth_probability": "0.5",
  35. "ignore_assoc_probability": "0.5",
  36. "ignore_reassoc_probability": "0.5" }
  37. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  38. for i in range(0, 3):
  39. dev[i].connect("open", key_mgmt="NONE", scan_freq="2412",
  40. wait_connect=False)
  41. for i in range(0, 3):
  42. dev[i].wait_connected(timeout=20)
  43. def test_ap_open_unknown_action(dev, apdev):
  44. """AP with open mode configuration and unknown Action frame"""
  45. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  46. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  47. bssid = apdev[0]['bssid']
  48. cmd = "MGMT_TX {} {} freq=2412 action=765432".format(bssid, bssid)
  49. if "FAIL" in dev[0].request(cmd):
  50. raise Exception("Could not send test Action frame")
  51. ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
  52. if ev is None:
  53. raise Exception("Timeout on MGMT-TX-STATUS")
  54. if "result=SUCCESS" not in ev:
  55. raise Exception("AP did not ack Action frame")
  56. def test_ap_open_reconnect_on_inactivity_disconnect(dev, apdev):
  57. """Reconnect to open mode AP after inactivity related disconnection"""
  58. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  59. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  60. hapd.request("DEAUTHENTICATE " + dev[0].p2p_interface_addr() + " reason=4")
  61. dev[0].wait_disconnected(timeout=5)
  62. dev[0].wait_connected(timeout=2, error="Timeout on reconnection")
  63. def test_ap_open_assoc_timeout(dev, apdev):
  64. """AP timing out association"""
  65. ssid = "test"
  66. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  67. dev[0].scan(freq="2412")
  68. hapd.set("ext_mgmt_frame_handling", "1")
  69. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  70. wait_connect=False)
  71. for i in range(0, 10):
  72. req = hapd.mgmt_rx()
  73. if req is None:
  74. raise Exception("MGMT RX wait timed out")
  75. if req['subtype'] == 11:
  76. break
  77. req = None
  78. if not req:
  79. raise Exception("Authentication frame not received")
  80. resp = {}
  81. resp['fc'] = req['fc']
  82. resp['da'] = req['sa']
  83. resp['sa'] = req['da']
  84. resp['bssid'] = req['bssid']
  85. resp['payload'] = struct.pack('<HHH', 0, 2, 0)
  86. hapd.mgmt_tx(resp)
  87. assoc = 0
  88. for i in range(0, 10):
  89. req = hapd.mgmt_rx()
  90. if req is None:
  91. raise Exception("MGMT RX wait timed out")
  92. if req['subtype'] == 0:
  93. assoc += 1
  94. if assoc == 3:
  95. break
  96. if assoc != 3:
  97. raise Exception("Association Request frames not received: assoc=%d" % assoc)
  98. hapd.set("ext_mgmt_frame_handling", "0")
  99. dev[0].wait_connected(timeout=15)
  100. def test_ap_open_id_str(dev, apdev):
  101. """AP with open mode and id_str"""
  102. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  103. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", id_str="foo",
  104. wait_connect=False)
  105. ev = dev[0].wait_connected(timeout=10)
  106. if "id_str=foo" not in ev:
  107. raise Exception("CTRL-EVENT-CONNECT did not have matching id_str: " + ev)
  108. if dev[0].get_status_field("id_str") != "foo":
  109. raise Exception("id_str mismatch")
  110. def test_ap_open_select_any(dev, apdev):
  111. """AP with open mode and select any network"""
  112. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  113. id = dev[0].connect("unknown", key_mgmt="NONE", scan_freq="2412",
  114. only_add_network=True)
  115. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  116. only_add_network=True)
  117. dev[0].select_network(id)
  118. ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
  119. if ev is not None:
  120. raise Exception("Unexpected connection")
  121. dev[0].select_network("any")
  122. dev[0].wait_connected(timeout=10)
  123. def test_ap_open_unexpected_assoc_event(dev, apdev):
  124. """AP with open mode and unexpected association event"""
  125. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  126. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  127. dev[0].request("DISCONNECT")
  128. dev[0].wait_disconnected(timeout=15)
  129. dev[0].dump_monitor()
  130. # This will be accepted due to matching network
  131. subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
  132. apdev[0]['bssid']])
  133. dev[0].wait_connected(timeout=15)
  134. dev[0].dump_monitor()
  135. dev[0].request("REMOVE_NETWORK all")
  136. dev[0].wait_disconnected(timeout=5)
  137. dev[0].dump_monitor()
  138. # This will result in disconnection due to no matching network
  139. subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
  140. apdev[0]['bssid']])
  141. dev[0].wait_disconnected(timeout=15)
  142. def test_ap_bss_load(dev, apdev):
  143. """AP with open mode (no security) configuration"""
  144. hapd = hostapd.add_ap(apdev[0]['ifname'],
  145. { "ssid": "open",
  146. "bss_load_update_period": "10" })
  147. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  148. # this does not really get much useful output with mac80211_hwsim currently,
  149. # but run through the channel survey update couple of times
  150. for i in range(0, 10):
  151. hwsim_utils.test_connectivity(dev[0], hapd)
  152. hwsim_utils.test_connectivity(dev[0], hapd)
  153. hwsim_utils.test_connectivity(dev[0], hapd)
  154. time.sleep(0.15)
  155. def hapd_out_of_mem(hapd, apdev, count, func):
  156. with alloc_fail(hapd, count, func):
  157. started = False
  158. try:
  159. hostapd.add_ap(apdev['ifname'], { "ssid": "open" })
  160. started = True
  161. except:
  162. pass
  163. if started:
  164. raise Exception("hostapd interface started even with memory allocation failure: " + arg)
  165. def test_ap_open_out_of_memory(dev, apdev):
  166. """hostapd failing to setup interface due to allocation failure"""
  167. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  168. hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_alloc_bss_data")
  169. for i in range(1, 3):
  170. hapd_out_of_mem(hapd, apdev[1], i, "hostapd_iface_alloc")
  171. for i in range(1, 5):
  172. hapd_out_of_mem(hapd, apdev[1], i, "hostapd_config_defaults;hostapd_config_alloc")
  173. hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_config_alloc")
  174. hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_driver_init")
  175. for i in range(1, 4):
  176. hapd_out_of_mem(hapd, apdev[1], i, "=wpa_driver_nl80211_drv_init")
  177. # eloop_register_read_sock() call from i802_init()
  178. hapd_out_of_mem(hapd, apdev[1], 1, "eloop_sock_table_add_sock;eloop_register_sock;?eloop_register_read_sock;=i802_init")
  179. # verify that a new interface can still be added when memory allocation does
  180. # not fail
  181. hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
  182. def test_bssid_black_white_list(dev, apdev):
  183. """BSSID black/white list"""
  184. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  185. hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
  186. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  187. bssid_whitelist=apdev[1]['bssid'])
  188. dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
  189. bssid_blacklist=apdev[1]['bssid'])
  190. dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
  191. bssid_whitelist="00:00:00:00:00:00/00:00:00:00:00:00",
  192. bssid_blacklist=apdev[1]['bssid'])
  193. if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
  194. raise Exception("dev[0] connected to unexpected AP")
  195. if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
  196. raise Exception("dev[1] connected to unexpected AP")
  197. if dev[2].get_status_field('bssid') != apdev[0]['bssid']:
  198. raise Exception("dev[2] connected to unexpected AP")
  199. dev[0].request("REMOVE_NETWORK all")
  200. dev[1].request("REMOVE_NETWORK all")
  201. dev[2].request("REMOVE_NETWORK all")
  202. dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
  203. bssid_whitelist="00:00:00:00:00:00", wait_connect=False)
  204. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  205. bssid_whitelist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
  206. dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
  207. bssid_blacklist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
  208. if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
  209. raise Exception("dev[0] connected to unexpected AP")
  210. if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
  211. raise Exception("dev[1] connected to unexpected AP")
  212. dev[0].request("REMOVE_NETWORK all")
  213. dev[1].request("REMOVE_NETWORK all")
  214. ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
  215. if ev is not None:
  216. raise Exception("Unexpected dev[2] connectin")
  217. dev[2].request("REMOVE_NETWORK all")
  218. def test_ap_open_wpas_in_bridge(dev, apdev):
  219. """Open mode AP and wpas interface in a bridge"""
  220. br_ifname='sta-br0'
  221. ifname='wlan5'
  222. try:
  223. _test_ap_open_wpas_in_bridge(dev, apdev)
  224. finally:
  225. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
  226. subprocess.call(['brctl', 'delif', br_ifname, ifname])
  227. subprocess.call(['brctl', 'delbr', br_ifname])
  228. subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
  229. def _test_ap_open_wpas_in_bridge(dev, apdev):
  230. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  231. br_ifname='sta-br0'
  232. ifname='wlan5'
  233. wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
  234. # First, try a failure case of adding an interface
  235. try:
  236. wpas.interface_add(ifname, br_ifname=br_ifname)
  237. raise Exception("Interface addition succeeded unexpectedly")
  238. except Exception, e:
  239. if "Failed to add" in str(e):
  240. logger.info("Ignore expected interface_add failure due to missing bridge interface: " + str(e))
  241. else:
  242. raise
  243. # Next, add the bridge interface and add the interface again
  244. subprocess.call(['brctl', 'addbr', br_ifname])
  245. subprocess.call(['brctl', 'setfd', br_ifname, '0'])
  246. subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
  247. subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
  248. subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
  249. wpas.interface_add(ifname, br_ifname=br_ifname)
  250. wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
  251. def test_ap_open_start_disabled(dev, apdev):
  252. """AP with open mode and beaconing disabled"""
  253. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
  254. "start_disabled": "1" })
  255. bssid = apdev[0]['bssid']
  256. dev[0].flush_scan_cache()
  257. dev[0].scan(freq=2412, only_new=True)
  258. if dev[0].get_bss(bssid) is not None:
  259. raise Exception("AP was seen beaconing")
  260. if "OK" not in hapd.request("RELOAD"):
  261. raise Exception("RELOAD failed")
  262. dev[0].scan_for_bss(bssid, freq=2412)
  263. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  264. def test_ap_open_start_disabled2(dev, apdev):
  265. """AP with open mode and beaconing disabled (2)"""
  266. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
  267. "start_disabled": "1" })
  268. bssid = apdev[0]['bssid']
  269. dev[0].flush_scan_cache()
  270. dev[0].scan(freq=2412, only_new=True)
  271. if dev[0].get_bss(bssid) is not None:
  272. raise Exception("AP was seen beaconing")
  273. if "OK" not in hapd.request("UPDATE_BEACON"):
  274. raise Exception("UPDATE_BEACON failed")
  275. dev[0].scan_for_bss(bssid, freq=2412)
  276. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  277. if "OK" not in hapd.request("UPDATE_BEACON"):
  278. raise Exception("UPDATE_BEACON failed")
  279. dev[0].request("DISCONNECT")
  280. dev[0].wait_disconnected()
  281. dev[0].request("RECONNECT")
  282. dev[0].wait_connected()
  283. def test_ap_open_ifdown(dev, apdev):
  284. """AP with open mode and external ifconfig down"""
  285. params = { "ssid": "open",
  286. "ap_max_inactivity": "1" }
  287. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  288. bssid = apdev[0]['bssid']
  289. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
  290. dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
  291. subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'down'])
  292. ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=10)
  293. if ev is None:
  294. raise Exception("Timeout on AP-STA-DISCONNECTED (1)")
  295. ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=5)
  296. if ev is None:
  297. raise Exception("Timeout on AP-STA-DISCONNECTED (2)")
  298. ev = hapd.wait_event(["INTERFACE-DISABLED"], timeout=5)
  299. if ev is None:
  300. raise Exception("No INTERFACE-DISABLED event")
  301. # The following wait tests beacon loss detection in mac80211 on dev0.
  302. # dev1 is used to test stopping of AP side functionality on client polling.
  303. dev[1].request("REMOVE_NETWORK all")
  304. subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'up'])
  305. dev[0].wait_disconnected()
  306. dev[1].wait_disconnected()
  307. ev = hapd.wait_event(["INTERFACE-ENABLED"], timeout=10)
  308. if ev is None:
  309. raise Exception("No INTERFACE-ENABLED event")
  310. dev[0].wait_connected()
  311. hwsim_utils.test_connectivity(dev[0], hapd)
  312. def test_ap_open_disconnect_in_ps(dev, apdev, params):
  313. """Disconnect with the client in PS to regression-test a kernel bug"""
  314. hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
  315. dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
  316. bg_scan_period="0")
  317. ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
  318. if ev is None:
  319. raise Exception("No connection event received from hostapd")
  320. time.sleep(0.2)
  321. hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_MANUAL_POLL)
  322. try:
  323. # inject some traffic
  324. sa = hapd.own_addr()
  325. da = dev[0].own_addr()
  326. hapd.request('DATA_TEST_CONFIG 1')
  327. hapd.request('DATA_TEST_TX {} {} 0'.format(da, sa))
  328. hapd.request('DATA_TEST_CONFIG 0')
  329. # let the AP send couple of Beacon frames
  330. time.sleep(0.3)
  331. # disconnect - with traffic pending - shouldn't cause kernel warnings
  332. dev[0].request("DISCONNECT")
  333. finally:
  334. hwsim_utils.set_powersave(dev[0], hwsim_utils.PS_DISABLED)
  335. time.sleep(0.2)
  336. out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"),
  337. "wlan_mgt.tim.partial_virtual_bitmap",
  338. ["wlan_mgt.tim.partial_virtual_bitmap"])
  339. if out is not None:
  340. state = 0
  341. for l in out.splitlines():
  342. pvb = int(l, 16)
  343. if pvb > 0 and state == 0:
  344. state = 1
  345. elif pvb == 0 and state == 1:
  346. state = 2
  347. if state != 2:
  348. raise Exception("Didn't observe TIM bit getting set and unset (state=%d)" % state)