]>
git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_ap_hs20.py
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
12 logger
= logging
.getLogger()
19 from utils
import HwsimSkip
21 from tshark
import run_tshark
22 from wlantest
import Wlantest
23 from wpasupplicant
import WpaSupplicant
24 from test_ap_eap
import check_eap_capa
, check_domain_match_full
26 def hs20_ap_params(ssid
="test-hs20"):
27 params
= hostapd
.wpa2_params(ssid
=ssid
)
28 params
['wpa_key_mgmt'] = "WPA-EAP"
29 params
['ieee80211w'] = "1"
30 params
['ieee8021x'] = "1"
31 params
['auth_server_addr'] = "127.0.0.1"
32 params
['auth_server_port'] = "1812"
33 params
['auth_server_shared_secret'] = "radius"
34 params
['interworking'] = "1"
35 params
['access_network_type'] = "14"
36 params
['internet'] = "1"
40 params
['venue_group'] = "7"
41 params
['venue_type'] = "1"
42 params
['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
43 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
45 params
['domain_name'] = "example.com,another.example.com"
46 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
47 "0,another.example.com" ]
49 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
50 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
51 params
['hs20_operating_class'] = "5173"
52 params
['anqp_3gpp_cell_net'] = "244,91"
55 def check_auto_select(dev
, bssid
):
56 dev
.scan_for_bss(bssid
, freq
="2412")
57 dev
.request("INTERWORKING_SELECT auto freq=2412")
58 ev
= dev
.wait_connected(timeout
=15)
60 raise Exception("Connected to incorrect network")
61 dev
.request("REMOVE_NETWORK all")
62 dev
.wait_disconnected()
64 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
66 if bssid
and freq
and not no_match
:
67 dev
.scan_for_bss(bssid
, freq
=freq
)
68 freq_extra
= " freq=" + freq
if freq
else ""
69 dev
.request("INTERWORKING_SELECT" + freq_extra
)
70 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
73 raise Exception("Network selection timed out");
75 if "INTERWORKING-NO-MATCH" not in ev
:
76 raise Exception("Unexpected network match")
78 if "INTERWORKING-NO-MATCH" in ev
:
79 logger
.info("Matching network not found - try again")
81 dev
.request("INTERWORKING_SELECT" + freq_extra
)
82 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
85 raise Exception("Network selection timed out");
86 if "INTERWORKING-NO-MATCH" in ev
:
87 raise Exception("Matching network not found")
88 if bssid
and bssid
not in ev
:
89 raise Exception("Unexpected BSSID in match")
90 if type and "type=" + type not in ev
:
91 raise Exception("Network type not recognized correctly")
93 def check_sp_type(dev
, sp_type
):
94 type = dev
.get_status_field("sp_type")
96 raise Exception("sp_type not available")
98 raise Exception("sp_type did not indicate home network")
100 def hlr_auc_gw_available():
101 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
102 raise HwsimSkip("No hlr_auc_gw socket available")
103 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
104 raise HwsimSkip("No hlr_auc_gw available")
106 def interworking_ext_sim_connect(dev
, bssid
, method
):
107 dev
.request("INTERWORKING_CONNECT " + bssid
)
108 interworking_ext_sim_auth(dev
, method
)
110 def interworking_ext_sim_auth(dev
, method
):
111 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
113 raise Exception("Network connected timed out")
114 if "(" + method
+ ")" not in ev
:
115 raise Exception("Unexpected EAP method selection")
117 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
119 raise Exception("Wait for external SIM processing request timed out")
121 if p
[1] != "GSM-AUTH":
122 raise Exception("Unexpected CTRL-REQ-SIM type")
123 id = p
[0].split('-')[3]
124 rand
= p
[2].split(' ')[0]
126 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
128 "auth_serv/hlr_auc_gw.milenage_db",
129 "GSM-AUTH-REQ 232010000000000 " + rand
])
130 if "GSM-AUTH-RESP" not in res
:
131 raise Exception("Unexpected hlr_auc_gw response")
132 resp
= res
.split(' ')[2].rstrip()
134 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
135 dev
.wait_connected(timeout
=15)
137 def interworking_connect(dev
, bssid
, method
):
138 dev
.request("INTERWORKING_CONNECT " + bssid
)
139 interworking_auth(dev
, method
)
141 def interworking_auth(dev
, method
):
142 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
144 raise Exception("Network connected timed out")
145 if "(" + method
+ ")" not in ev
:
146 raise Exception("Unexpected EAP method selection")
148 dev
.wait_connected(timeout
=15)
150 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
152 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
154 raise Exception("Unexpected Probe Response frame from AP")
157 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
159 raise Exception("No Probe Response frame from AP")
161 def test_ap_anqp_sharing(dev
, apdev
):
162 """ANQP sharing within ESS and explicit unshare"""
163 dev
[0].flush_scan_cache()
165 bssid
= apdev
[0]['bssid']
166 params
= hs20_ap_params()
167 params
['hessid'] = bssid
168 hostapd
.add_ap(apdev
[0]['ifname'], params
)
170 bssid2
= apdev
[1]['bssid']
171 params
= hs20_ap_params()
172 params
['hessid'] = bssid
173 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
174 hostapd
.add_ap(apdev
[1]['ifname'], params
)
177 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
178 'password': "secret",
179 'domain': "example.com" })
180 logger
.info("Normal network selection with shared ANQP results")
181 dev
[0].scan_for_bss(bssid
, freq
="2412")
182 dev
[0].scan_for_bss(bssid2
, freq
="2412")
183 interworking_select(dev
[0], None, "home", freq
="2412")
184 dev
[0].dump_monitor()
186 logger
.debug("BSS entries:\n" + dev
[0].request("BSS RANGE=ALL"))
187 res1
= dev
[0].get_bss(bssid
)
188 res2
= dev
[0].get_bss(bssid2
)
189 if 'anqp_nai_realm' not in res1
:
190 raise Exception("anqp_nai_realm not found for AP1")
191 if 'anqp_nai_realm' not in res2
:
192 raise Exception("anqp_nai_realm not found for AP2")
193 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
194 raise Exception("ANQP results were not shared between BSSes")
196 logger
.info("Explicit ANQP request to unshare ANQP results")
197 dev
[0].request("ANQP_GET " + bssid
+ " 263")
198 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
200 raise Exception("ANQP operation timed out")
202 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
203 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
205 raise Exception("ANQP operation timed out")
207 res1
= dev
[0].get_bss(bssid
)
208 res2
= dev
[0].get_bss(bssid2
)
209 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
210 raise Exception("ANQP results were not unshared")
212 def test_ap_nai_home_realm_query(dev
, apdev
):
213 """NAI Home Realm Query"""
214 bssid
= apdev
[0]['bssid']
215 params
= hs20_ap_params()
216 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
217 "0,another.example.org" ]
218 hostapd
.add_ap(apdev
[0]['ifname'], params
)
220 dev
[0].scan(freq
="2412")
221 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
222 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
224 raise Exception("ANQP operation timed out")
225 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
226 dev
[0].dump_monitor()
228 dev
[0].request("ANQP_GET " + bssid
+ " 263")
229 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
231 raise Exception("ANQP operation timed out")
232 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
234 if len(nai1
) >= len(nai2
):
235 raise Exception("Unexpected NAI Realm list response lengths")
236 if "example.com".encode('hex') not in nai1
:
237 raise Exception("Home realm not reported")
238 if "example.org".encode('hex') in nai1
:
239 raise Exception("Non-home realm reported")
240 if "example.com".encode('hex') not in nai2
:
241 raise Exception("Home realm not reported in wildcard query")
242 if "example.org".encode('hex') not in nai2
:
243 raise Exception("Non-home realm not reported in wildcard query ")
246 "00:11:22:33:44:55 123",
247 "00:11:22:33:44:55 qq" ]
249 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
250 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
252 dev
[0].dump_monitor()
253 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
254 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
255 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
257 raise Exception("ANQP operation timed out")
258 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
260 raise Exception("Unexpected ANQP response: " + ev
)
262 dev
[0].dump_monitor()
263 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
264 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
265 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
267 raise Exception("No ANQP response")
268 if "NAI Realm list" not in ev
:
269 raise Exception("Missing NAI Realm list: " + ev
)
271 dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
272 'password': "secret",
273 'domain': "example.com" })
274 dev
[0].dump_monitor()
275 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
276 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
277 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
279 raise Exception("No ANQP response")
280 if "NAI Realm list" not in ev
:
281 raise Exception("Missing NAI Realm list: " + ev
)
283 def test_ap_interworking_scan_filtering(dev
, apdev
):
284 """Interworking scan filtering with HESSID and access network type"""
286 _test_ap_interworking_scan_filtering(dev
, apdev
)
288 dev
[0].request("SET hessid 00:00:00:00:00:00")
289 dev
[0].request("SET access_network_type 15")
291 def _test_ap_interworking_scan_filtering(dev
, apdev
):
292 bssid
= apdev
[0]['bssid']
293 params
= hs20_ap_params()
294 ssid
= "test-hs20-ap1"
295 params
['ssid'] = ssid
296 params
['hessid'] = bssid
297 hostapd
.add_ap(apdev
[0]['ifname'], params
)
299 bssid2
= apdev
[1]['bssid']
300 params
= hs20_ap_params()
301 ssid2
= "test-hs20-ap2"
302 params
['ssid'] = ssid2
303 params
['hessid'] = bssid2
304 params
['access_network_type'] = "1"
305 del params
['venue_group']
306 del params
['venue_type']
307 hostapd
.add_ap(apdev
[1]['ifname'], params
)
314 logger
.info("Check probe request filtering based on HESSID")
316 dev
[0].request("SET hessid " + bssid2
)
317 dev
[0].scan(freq
="2412")
319 check_probe_resp(wt
, bssid
, bssid2
)
321 logger
.info("Check probe request filtering based on access network type")
323 wt
.clear_bss_counters(bssid
)
324 wt
.clear_bss_counters(bssid2
)
325 dev
[0].request("SET hessid 00:00:00:00:00:00")
326 dev
[0].request("SET access_network_type 14")
327 dev
[0].scan(freq
="2412")
329 check_probe_resp(wt
, bssid2
, bssid
)
331 wt
.clear_bss_counters(bssid
)
332 wt
.clear_bss_counters(bssid2
)
333 dev
[0].request("SET hessid 00:00:00:00:00:00")
334 dev
[0].request("SET access_network_type 1")
335 dev
[0].scan(freq
="2412")
337 check_probe_resp(wt
, bssid
, bssid2
)
339 logger
.info("Check probe request filtering based on HESSID and ANT")
341 wt
.clear_bss_counters(bssid
)
342 wt
.clear_bss_counters(bssid2
)
343 dev
[0].request("SET hessid " + bssid
)
344 dev
[0].request("SET access_network_type 14")
345 dev
[0].scan(freq
="2412")
347 check_probe_resp(wt
, bssid2
, bssid
)
349 wt
.clear_bss_counters(bssid
)
350 wt
.clear_bss_counters(bssid2
)
351 dev
[0].request("SET hessid " + bssid2
)
352 dev
[0].request("SET access_network_type 14")
353 dev
[0].scan(freq
="2412")
355 check_probe_resp(wt
, bssid
, None)
356 check_probe_resp(wt
, bssid2
, None)
358 wt
.clear_bss_counters(bssid
)
359 wt
.clear_bss_counters(bssid2
)
360 dev
[0].request("SET hessid " + bssid
)
361 dev
[0].request("SET access_network_type 1")
362 dev
[0].scan(freq
="2412")
364 check_probe_resp(wt
, bssid
, None)
365 check_probe_resp(wt
, bssid2
, None)
367 def test_ap_hs20_select(dev
, apdev
):
368 """Hotspot 2.0 network selection"""
369 bssid
= apdev
[0]['bssid']
370 params
= hs20_ap_params()
371 params
['hessid'] = bssid
372 hostapd
.add_ap(apdev
[0]['ifname'], params
)
375 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
376 'password': "secret",
377 'domain': "example.com" })
378 interworking_select(dev
[0], bssid
, "home")
380 dev
[0].remove_cred(id)
381 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
382 'password': "secret",
383 'domain': "no.match.example.com" })
384 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
386 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
387 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
389 res
= dev
[0].request("SCAN_RESULTS")
390 if "[HS20]" not in res
:
391 raise Exception("HS20 flag missing from scan results: " + res
)
393 bssid2
= apdev
[1]['bssid']
394 params
= hs20_ap_params()
395 params
['nai_realm'] = [ "0,example.org,21" ]
396 params
['hessid'] = bssid2
397 params
['domain_name'] = "example.org"
398 hostapd
.add_ap(apdev
[1]['ifname'], params
)
399 dev
[0].remove_cred(id)
400 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
401 'password': "secret",
402 'domain': "example.org" })
403 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
405 def hs20_simulated_sim(dev
, ap
, method
):
407 params
= hs20_ap_params()
408 params
['hessid'] = bssid
409 params
['anqp_3gpp_cell_net'] = "555,444"
410 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
411 hostapd
.add_ap(ap
['ifname'], params
)
414 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
415 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
416 interworking_select(dev
, "home", freq
="2412")
417 interworking_connect(dev
, bssid
, method
)
418 check_sp_type(dev
, "home")
420 def test_ap_hs20_sim(dev
, apdev
):
421 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
422 hlr_auc_gw_available()
423 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
424 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
425 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
427 raise Exception("Timeout on already-connected event")
429 def test_ap_hs20_aka(dev
, apdev
):
430 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
431 hlr_auc_gw_available()
432 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
434 def test_ap_hs20_aka_prime(dev
, apdev
):
435 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
436 hlr_auc_gw_available()
437 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
439 def test_ap_hs20_ext_sim(dev
, apdev
):
440 """Hotspot 2.0 with external SIM processing"""
441 hlr_auc_gw_available()
442 bssid
= apdev
[0]['bssid']
443 params
= hs20_ap_params()
444 params
['hessid'] = bssid
445 params
['anqp_3gpp_cell_net'] = "232,01"
446 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
447 hostapd
.add_ap(apdev
[0]['ifname'], params
)
451 dev
[0].request("SET external_sim 1")
452 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
453 interworking_select(dev
[0], "home", freq
="2412")
454 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
455 check_sp_type(dev
[0], "home")
457 dev
[0].request("SET external_sim 0")
459 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
460 """Hotspot 2.0 with external SIM processing in roaming network"""
461 hlr_auc_gw_available()
462 bssid
= apdev
[0]['bssid']
463 params
= hs20_ap_params()
464 params
['hessid'] = bssid
465 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
466 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
467 hostapd
.add_ap(apdev
[0]['ifname'], params
)
471 dev
[0].request("SET external_sim 1")
472 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
473 interworking_select(dev
[0], "roaming", freq
="2412")
474 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
475 check_sp_type(dev
[0], "roaming")
477 dev
[0].request("SET external_sim 0")
479 def test_ap_hs20_username(dev
, apdev
):
480 """Hotspot 2.0 connection in username/password credential"""
481 bssid
= apdev
[0]['bssid']
482 params
= hs20_ap_params()
483 params
['hessid'] = bssid
484 params
['disable_dgaf'] = '1'
485 hostapd
.add_ap(apdev
[0]['ifname'], params
)
488 id = dev
[0].add_cred_values({ 'realm': "example.com",
489 'username': "hs20-test",
490 'password': "password",
491 'ca_cert': "auth_serv/ca.pem",
492 'domain': "example.com",
493 'update_identifier': "1234" })
494 interworking_select(dev
[0], bssid
, "home", freq
="2412")
495 interworking_connect(dev
[0], bssid
, "TTLS")
496 check_sp_type(dev
[0], "home")
497 status
= dev
[0].get_status()
498 if status
['pairwise_cipher'] != "CCMP":
499 raise Exception("Unexpected pairwise cipher")
500 if status
['hs20'] != "2":
501 raise Exception("Unexpected HS 2.0 support indication")
503 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
504 identity
="hs20-test", password
="password",
505 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
508 def test_ap_hs20_connect_api(dev
, apdev
):
509 """Hotspot 2.0 connection with connect API"""
510 bssid
= apdev
[0]['bssid']
511 params
= hs20_ap_params()
512 params
['hessid'] = bssid
513 params
['disable_dgaf'] = '1'
514 hostapd
.add_ap(apdev
[0]['ifname'], params
)
516 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
517 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
519 wpas
.flush_scan_cache()
520 id = wpas
.add_cred_values({ 'realm': "example.com",
521 'username': "hs20-test",
522 'password': "password",
523 'ca_cert': "auth_serv/ca.pem",
524 'domain': "example.com",
525 'update_identifier': "1234" })
526 interworking_select(wpas
, bssid
, "home", freq
="2412")
527 interworking_connect(wpas
, bssid
, "TTLS")
528 check_sp_type(wpas
, "home")
529 status
= wpas
.get_status()
530 if status
['pairwise_cipher'] != "CCMP":
531 raise Exception("Unexpected pairwise cipher")
532 if status
['hs20'] != "2":
533 raise Exception("Unexpected HS 2.0 support indication")
535 def test_ap_hs20_auto_interworking(dev
, apdev
):
536 """Hotspot 2.0 connection with auto_interworking=1"""
537 bssid
= apdev
[0]['bssid']
538 params
= hs20_ap_params()
539 params
['hessid'] = bssid
540 params
['disable_dgaf'] = '1'
541 hostapd
.add_ap(apdev
[0]['ifname'], params
)
543 dev
[0].hs20_enable(auto_interworking
=True)
544 id = dev
[0].add_cred_values({ 'realm': "example.com",
545 'username': "hs20-test",
546 'password': "password",
547 'ca_cert': "auth_serv/ca.pem",
548 'domain': "example.com",
549 'update_identifier': "1234" })
550 dev
[0].request("REASSOCIATE")
551 dev
[0].wait_connected(timeout
=15)
552 check_sp_type(dev
[0], "home")
553 status
= dev
[0].get_status()
554 if status
['pairwise_cipher'] != "CCMP":
555 raise Exception("Unexpected pairwise cipher")
556 if status
['hs20'] != "2":
557 raise Exception("Unexpected HS 2.0 support indication")
559 def test_ap_hs20_auto_interworking_no_match(dev
, apdev
):
560 """Hotspot 2.0 connection with auto_interworking=1 and no matching network"""
561 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], { "ssid": "mismatch" })
563 dev
[0].hs20_enable(auto_interworking
=True)
564 id = dev
[0].connect("mismatch", psk
="12345678", scan_freq
="2412",
565 only_add_network
=True)
566 dev
[0].request("ENABLE_NETWORK " + str(id) + " no-connect")
568 id = dev
[0].add_cred_values({ 'realm': "example.com",
569 'username': "hs20-test",
570 'password': "password",
571 'ca_cert': "auth_serv/ca.pem",
572 'domain': "example.com",
573 'update_identifier': "1234" })
574 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
576 dev
[0].dump_monitor()
578 logger
.info("start ping")
579 if "PONG" not in dev
[0].ctrl
.request("PING", timeout
=2):
580 raise Exception("PING failed")
581 logger
.info("ping done")
585 ev
= dev
[0].wait_event([ "ANQP fetch completed",
586 "CTRL-EVENT-SCAN-RESULTS" ], timeout
=0.05)
589 if "ANQP fetch completed" in ev
:
593 if fetch
> 2 * scan
+ 3:
594 raise Exception("Too many ANQP fetch iterations")
595 dev
[0].dump_monitor()
596 dev
[0].request("DISCONNECT")
598 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
599 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
600 bssid
= apdev
[0]['bssid']
601 params
= { "ssid": "test" }
602 hostapd
.add_ap(apdev
[0]['ifname'], params
)
604 dev
[0].hs20_enable(auto_interworking
=True)
605 dev
[0].add_cred_values({ 'realm': "example.com",
606 'username': "hs20-test",
607 'password': "password",
608 'ca_cert': "auth_serv/ca.pem",
609 'domain': "example.com" })
611 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
612 dev
[0].request("ENABLE_NETWORK %s" % id)
613 logger
.info("Verify that scanning continues when there is partial network block match")
614 for i
in range(0, 2):
615 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
617 raise Exception("Scan timed out")
618 logger
.info("Scan completed")
620 def eap_test(dev
, ap
, eap_params
, method
, user
):
622 params
= hs20_ap_params()
623 params
['nai_realm'] = [ "0,example.com," + eap_params
]
624 hostapd
.add_ap(ap
['ifname'], params
)
627 dev
.add_cred_values({ 'realm': "example.com",
628 'ca_cert': "auth_serv/ca.pem",
630 'password': "password" })
631 interworking_select(dev
, bssid
, freq
="2412")
632 interworking_connect(dev
, bssid
, method
)
634 def test_ap_hs20_eap_unknown(dev
, apdev
):
635 """Hotspot 2.0 connection with unknown EAP method"""
636 bssid
= apdev
[0]['bssid']
637 params
= hs20_ap_params()
638 params
['nai_realm'] = "0,example.com,99"
639 hostapd
.add_ap(apdev
[0]['ifname'], params
)
642 dev
[0].add_cred_values(default_cred())
643 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
645 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
646 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
647 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
649 def test_ap_hs20_eap_peap_default(dev
, apdev
):
650 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
651 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
653 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
654 """Hotspot 2.0 connection with PEAP/GTC"""
655 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
657 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
658 """Hotspot 2.0 connection with PEAP/unknown"""
659 bssid
= apdev
[0]['bssid']
660 params
= hs20_ap_params()
661 params
['nai_realm'] = "0,example.com,25[3:99]"
662 hostapd
.add_ap(apdev
[0]['ifname'], params
)
665 dev
[0].add_cred_values(default_cred())
666 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
668 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
669 """Hotspot 2.0 connection with TTLS/CHAP"""
670 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
672 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
673 """Hotspot 2.0 connection with TTLS/MSCHAP"""
674 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
676 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
677 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
678 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
680 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
681 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
682 bssid
= apdev
[0]['bssid']
683 params
= hs20_ap_params()
684 params
['nai_realm'] = "0,example.com,21[3:99]"
685 hostapd
.add_ap(apdev
[0]['ifname'], params
)
688 dev
[0].add_cred_values(default_cred())
689 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
691 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
692 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
693 bssid
= apdev
[0]['bssid']
694 params
= hs20_ap_params()
695 params
['nai_realm'] = "0,example.com,21[3:5]"
696 hostapd
.add_ap(apdev
[0]['ifname'], params
)
699 dev
[0].add_cred_values(default_cred())
700 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
702 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
703 """Hotspot 2.0 connection with TTLS/unknown"""
704 bssid
= apdev
[0]['bssid']
705 params
= hs20_ap_params()
706 params
['nai_realm'] = "0,example.com,21[2:5]"
707 hostapd
.add_ap(apdev
[0]['ifname'], params
)
710 dev
[0].add_cred_values(default_cred())
711 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
713 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
714 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
715 check_eap_capa(dev
[0], "FAST")
716 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
718 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
719 """Hotspot 2.0 connection with FAST/EAP-GTC"""
720 check_eap_capa(dev
[0], "FAST")
721 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
723 def test_ap_hs20_eap_tls(dev
, apdev
):
724 """Hotspot 2.0 connection with EAP-TLS"""
725 bssid
= apdev
[0]['bssid']
726 params
= hs20_ap_params()
727 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
728 hostapd
.add_ap(apdev
[0]['ifname'], params
)
731 dev
[0].add_cred_values({ 'realm': "example.com",
732 'username': "certificate-user",
733 'ca_cert': "auth_serv/ca.pem",
734 'client_cert': "auth_serv/user.pem",
735 'private_key': "auth_serv/user.key"})
736 interworking_select(dev
[0], bssid
, freq
="2412")
737 interworking_connect(dev
[0], bssid
, "TLS")
739 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
740 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
741 bssid
= apdev
[0]['bssid']
742 params
= hs20_ap_params()
743 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
744 hostapd
.add_ap(apdev
[0]['ifname'], params
)
747 dev
[0].add_cred_values({ 'realm': "example.com",
748 'username': "certificate-user",
749 'ca_cert': "auth_serv/ca.pem",
750 'client_cert': "auth_serv/user.pem",
751 'private_key': "auth_serv/user.key"})
752 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
754 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
755 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
756 bssid
= apdev
[0]['bssid']
757 params
= hs20_ap_params()
758 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
759 hostapd
.add_ap(apdev
[0]['ifname'], params
)
762 dev
[0].add_cred_values({ 'realm': "example.com",
763 'username': "certificate-user",
764 'ca_cert': "auth_serv/ca.pem",
765 'client_cert': "auth_serv/user.pem",
766 'private_key': "auth_serv/user.key"})
767 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
769 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
770 """Hotspot 2.0 connection with invalid cred configuration"""
771 bssid
= apdev
[0]['bssid']
772 params
= hs20_ap_params()
773 hostapd
.add_ap(apdev
[0]['ifname'], params
)
776 dev
[0].add_cred_values({ 'realm': "example.com",
777 'username': "certificate-user",
778 'client_cert': "auth_serv/user.pem" })
779 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
781 def test_ap_hs20_nai_realms(dev
, apdev
):
782 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
783 bssid
= apdev
[0]['bssid']
784 params
= hs20_ap_params()
785 params
['hessid'] = bssid
786 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
787 hostapd
.add_ap(apdev
[0]['ifname'], params
)
790 id = dev
[0].add_cred_values({ 'realm': "example.com",
791 'ca_cert': "auth_serv/ca.pem",
792 'username': "pap user",
793 'password': "password",
794 'domain': "example.com" })
795 interworking_select(dev
[0], bssid
, "home", freq
="2412")
796 interworking_connect(dev
[0], bssid
, "TTLS")
797 check_sp_type(dev
[0], "home")
799 def test_ap_hs20_roaming_consortium(dev
, apdev
):
800 """Hotspot 2.0 connection based on roaming consortium match"""
801 bssid
= apdev
[0]['bssid']
802 params
= hs20_ap_params()
803 params
['hessid'] = bssid
804 hostapd
.add_ap(apdev
[0]['ifname'], params
)
807 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
808 id = dev
[0].add_cred_values({ 'username': "user",
809 'password': "password",
810 'domain': "example.com",
811 'ca_cert': "auth_serv/ca.pem",
812 'roaming_consortium': consortium
,
814 interworking_select(dev
[0], bssid
, "home", freq
="2412")
815 interworking_connect(dev
[0], bssid
, "PEAP")
816 check_sp_type(dev
[0], "home")
817 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
818 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
820 raise Exception("Timeout on already-connected event")
821 dev
[0].remove_cred(id)
823 def test_ap_hs20_username_roaming(dev
, apdev
):
824 """Hotspot 2.0 connection in username/password credential (roaming)"""
825 bssid
= apdev
[0]['bssid']
826 params
= hs20_ap_params()
827 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
828 "0,roaming.example.com,21[2:4][5:7]",
829 "0,another.example.com" ]
830 params
['domain_name'] = "another.example.com"
831 params
['hessid'] = bssid
832 hostapd
.add_ap(apdev
[0]['ifname'], params
)
835 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
836 'username': "hs20-test",
837 'password': "password",
838 'ca_cert': "auth_serv/ca.pem",
839 'domain': "example.com" })
840 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
841 interworking_connect(dev
[0], bssid
, "TTLS")
842 check_sp_type(dev
[0], "roaming")
844 def test_ap_hs20_username_unknown(dev
, apdev
):
845 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
846 bssid
= apdev
[0]['bssid']
847 params
= hs20_ap_params()
848 params
['hessid'] = bssid
849 hostapd
.add_ap(apdev
[0]['ifname'], params
)
852 id = dev
[0].add_cred_values({ 'realm': "example.com",
853 'ca_cert': "auth_serv/ca.pem",
854 'username': "hs20-test",
855 'password': "password" })
856 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
857 interworking_connect(dev
[0], bssid
, "TTLS")
858 check_sp_type(dev
[0], "unknown")
860 def test_ap_hs20_username_unknown2(dev
, apdev
):
861 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
862 bssid
= apdev
[0]['bssid']
863 params
= hs20_ap_params()
864 params
['hessid'] = bssid
865 del params
['domain_name']
866 hostapd
.add_ap(apdev
[0]['ifname'], params
)
869 id = dev
[0].add_cred_values({ 'realm': "example.com",
870 'ca_cert': "auth_serv/ca.pem",
871 'username': "hs20-test",
872 'password': "password",
873 'domain': "example.com" })
874 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
875 interworking_connect(dev
[0], bssid
, "TTLS")
876 check_sp_type(dev
[0], "unknown")
878 def test_ap_hs20_gas_while_associated(dev
, apdev
):
879 """Hotspot 2.0 connection with GAS query while associated"""
880 bssid
= apdev
[0]['bssid']
881 params
= hs20_ap_params()
882 params
['hessid'] = bssid
883 hostapd
.add_ap(apdev
[0]['ifname'], params
)
886 id = dev
[0].add_cred_values({ 'realm': "example.com",
887 'ca_cert': "auth_serv/ca.pem",
888 'username': "hs20-test",
889 'password': "password",
890 'domain': "example.com" })
891 interworking_select(dev
[0], bssid
, "home", freq
="2412")
892 interworking_connect(dev
[0], bssid
, "TTLS")
894 logger
.info("Verifying GAS query while associated")
895 dev
[0].request("FETCH_ANQP")
896 for i
in range(0, 6):
897 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
899 raise Exception("Operation timed out")
901 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
902 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
904 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
906 dev
[0].request("SET pmf 0")
908 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
909 bssid
= apdev
[0]['bssid']
910 params
= hs20_ap_params()
911 params
['hessid'] = bssid
912 hostapd
.add_ap(apdev
[0]['ifname'], params
)
914 bssid2
= apdev
[1]['bssid']
915 params
= hs20_ap_params()
916 params
['hessid'] = bssid2
917 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
918 hostapd
.add_ap(apdev
[1]['ifname'], params
)
921 dev
[0].request("SET pmf 2")
922 id = dev
[0].add_cred_values({ 'realm': "example.com",
923 'ca_cert': "auth_serv/ca.pem",
924 'username': "hs20-test",
925 'password': "password",
926 'domain': "example.com" })
927 interworking_select(dev
[0], bssid
, "home", freq
="2412")
928 interworking_connect(dev
[0], bssid
, "TTLS")
930 logger
.info("Verifying GAS query while associated")
931 dev
[0].request("FETCH_ANQP")
932 for i
in range(0, 2 * 6):
933 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
935 raise Exception("Operation timed out")
937 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
938 """Hotspot 2.0 connection with fragmented GAS query while associated"""
939 bssid
= apdev
[0]['bssid']
940 params
= hs20_ap_params()
941 params
['hessid'] = bssid
942 hostapd
.add_ap(apdev
[0]['ifname'], params
)
943 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
944 hapd
.set("gas_frag_limit", "50")
947 id = dev
[0].add_cred_values({ 'realm': "example.com",
948 'ca_cert': "auth_serv/ca.pem",
949 'username': "hs20-test",
950 'password': "password",
951 'domain': "example.com" })
952 interworking_select(dev
[0], bssid
, "home", freq
="2412")
953 interworking_connect(dev
[0], bssid
, "TTLS")
955 logger
.info("Verifying GAS query while associated")
956 dev
[0].request("FETCH_ANQP")
957 for i
in range(0, 6):
958 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
960 raise Exception("Operation timed out")
962 def test_ap_hs20_multiple_connects(dev
, apdev
):
963 """Hotspot 2.0 connection through multiple network selections"""
964 bssid
= apdev
[0]['bssid']
965 params
= hs20_ap_params()
966 params
['hessid'] = bssid
967 hostapd
.add_ap(apdev
[0]['ifname'], params
)
970 values
= { 'realm': "example.com",
971 'ca_cert': "auth_serv/ca.pem",
972 'username': "hs20-test",
973 'password': "password",
974 'domain': "example.com" }
975 id = dev
[0].add_cred_values(values
)
977 dev
[0].scan_for_bss(bssid
, freq
="2412")
979 for i
in range(0, 3):
980 logger
.info("Starting Interworking network selection")
981 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
983 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
984 "INTERWORKING-ALREADY-CONNECTED",
985 "CTRL-EVENT-CONNECTED"], timeout
=15)
987 raise Exception("Connection timed out")
988 if "INTERWORKING-NO-MATCH" in ev
:
989 raise Exception("Matching AP not found")
990 if "CTRL-EVENT-CONNECTED" in ev
:
992 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
995 dev
[0].request("DISCONNECT")
996 dev
[0].dump_monitor()
998 networks
= dev
[0].list_networks()
999 if len(networks
) > 1:
1000 raise Exception("Duplicated network block detected")
1002 def test_ap_hs20_disallow_aps(dev
, apdev
):
1003 """Hotspot 2.0 connection and disallow_aps"""
1004 bssid
= apdev
[0]['bssid']
1005 params
= hs20_ap_params()
1006 params
['hessid'] = bssid
1007 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1009 dev
[0].hs20_enable()
1010 values
= { 'realm': "example.com",
1011 'ca_cert': "auth_serv/ca.pem",
1012 'username': "hs20-test",
1013 'password': "password",
1014 'domain': "example.com" }
1015 id = dev
[0].add_cred_values(values
)
1017 dev
[0].scan_for_bss(bssid
, freq
="2412")
1019 logger
.info("Verify disallow_aps bssid")
1020 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1021 dev
[0].request("INTERWORKING_SELECT auto")
1022 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1024 raise Exception("Network selection timed out")
1025 dev
[0].dump_monitor()
1027 logger
.info("Verify disallow_aps ssid")
1028 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
1029 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1030 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
1032 raise Exception("Network selection timed out")
1033 dev
[0].dump_monitor()
1035 logger
.info("Verify disallow_aps clear")
1036 dev
[0].request("SET disallow_aps ")
1037 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1039 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
1040 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1041 if "FAIL" not in ret
:
1042 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
1044 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
1045 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1046 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
1047 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1049 def policy_test(dev
, ap
, values
, only_one
=True):
1052 logger
.info("Verify network selection to AP " + ap
['ifname'])
1054 dev
.scan_for_bss(bssid
, freq
="2412")
1056 logger
.info("Verify network selection")
1059 id = dev
.add_cred_values(values
)
1060 dev
.request("INTERWORKING_SELECT auto freq=2412")
1063 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1064 "INTERWORKING-BLACKLISTED",
1065 "INTERWORKING-SELECTED"], timeout
=15)
1067 raise Exception("Network selection timed out")
1069 if "INTERWORKING-NO-MATCH" in ev
:
1070 raise Exception("Matching AP not found")
1071 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1072 raise Exception("Unexpected AP claimed acceptable")
1073 if "INTERWORKING-SELECTED" in ev
:
1074 if bssid
and bssid
not in ev
:
1075 raise Exception("Selected incorrect BSS")
1078 ev
= dev
.wait_connected(timeout
=15)
1079 if bssid
and bssid
not in ev
:
1080 raise Exception("Connected to incorrect BSS")
1082 conn_bssid
= dev
.get_status_field("bssid")
1083 if bssid
and conn_bssid
!= bssid
:
1084 raise Exception("bssid information points to incorrect BSS")
1090 def default_cred(domain
=None):
1091 cred
= { 'realm': "example.com",
1092 'ca_cert': "auth_serv/ca.pem",
1093 'username': "hs20-test",
1094 'password': "password" }
1096 cred
['domain'] = domain
1099 def test_ap_hs20_prefer_home(dev
, apdev
):
1100 """Hotspot 2.0 required roaming consortium"""
1101 params
= hs20_ap_params()
1102 params
['domain_name'] = "example.org"
1103 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1105 params
= hs20_ap_params()
1106 params
['ssid'] = "test-hs20-other"
1107 params
['domain_name'] = "example.com"
1108 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1110 values
= default_cred()
1111 values
['domain'] = "example.com"
1112 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1113 values
['domain'] = "example.org"
1114 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1116 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1117 """Hotspot 2.0 required roaming consortium"""
1118 params
= hs20_ap_params()
1119 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1121 params
= hs20_ap_params()
1122 params
['ssid'] = "test-hs20-other"
1123 params
['roaming_consortium'] = [ "223344" ]
1124 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1126 values
= default_cred()
1127 values
['required_roaming_consortium'] = "223344"
1128 policy_test(dev
[0], apdev
[1], values
)
1129 values
['required_roaming_consortium'] = "112233"
1130 policy_test(dev
[0], apdev
[0], values
)
1132 id = dev
[0].add_cred()
1133 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1134 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1136 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1137 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1138 raise Exception("Invalid roaming consortium value accepted: " + val
)
1140 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1141 """Hotspot 2.0 exclusion based on SSID"""
1142 params
= hs20_ap_params()
1143 params
['roaming_consortium'] = [ "223344" ]
1144 params
['anqp_3gpp_cell_net'] = "555,444"
1145 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1147 params
= hs20_ap_params()
1148 params
['ssid'] = "test-hs20-other"
1149 params
['roaming_consortium'] = [ "223344" ]
1150 params
['anqp_3gpp_cell_net'] = "555,444"
1151 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1153 values
= default_cred()
1154 values
['excluded_ssid'] = "test-hs20"
1155 events
= policy_test(dev
[0], apdev
[1], values
)
1156 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1158 raise Exception("Excluded network not reported")
1159 values
['excluded_ssid'] = "test-hs20-other"
1160 events
= policy_test(dev
[0], apdev
[0], values
)
1161 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1163 raise Exception("Excluded network not reported")
1165 values
= default_cred()
1166 values
['roaming_consortium'] = "223344"
1167 values
['eap'] = "TTLS"
1168 values
['phase2'] = "auth=MSCHAPV2"
1169 values
['excluded_ssid'] = "test-hs20"
1170 events
= policy_test(dev
[0], apdev
[1], values
)
1171 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1173 raise Exception("Excluded network not reported")
1175 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1176 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1177 'excluded_ssid': "test-hs20" }
1178 events
= policy_test(dev
[0], apdev
[1], values
)
1179 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1181 raise Exception("Excluded network not reported")
1183 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1184 """Hotspot 2.0 and roaming from current to higher priority network"""
1185 bssid
= apdev
[0]['bssid']
1186 params
= hs20_ap_params(ssid
="test-hs20-visited")
1187 params
['domain_name'] = "visited.example.org"
1188 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1190 dev
[0].hs20_enable()
1191 id = dev
[0].add_cred_values({ 'realm': "example.com",
1192 'ca_cert': "auth_serv/ca.pem",
1193 'username': "hs20-test",
1194 'password': "password",
1195 'domain': "example.com" })
1196 logger
.info("Connect to the only network option")
1197 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1198 dev
[0].dump_monitor()
1199 interworking_connect(dev
[0], bssid
, "TTLS")
1201 logger
.info("Start another AP (home operator) and reconnect")
1202 bssid2
= apdev
[1]['bssid']
1203 params
= hs20_ap_params(ssid
="test-hs20-home")
1204 params
['domain_name'] = "example.com"
1205 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1207 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1208 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1209 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1210 "INTERWORKING-ALREADY-CONNECTED",
1211 "CTRL-EVENT-CONNECTED"], timeout
=15)
1213 raise Exception("Connection timed out")
1214 if "INTERWORKING-NO-MATCH" in ev
:
1215 raise Exception("Matching AP not found")
1216 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1217 raise Exception("Unexpected AP selected")
1218 if bssid2
not in ev
:
1219 raise Exception("Unexpected BSSID after reconnection")
1221 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1222 """Hotspot 2.0 and domain_suffix_match"""
1223 bssid
= apdev
[0]['bssid']
1224 params
= hs20_ap_params()
1225 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1227 dev
[0].hs20_enable()
1228 id = dev
[0].add_cred_values({ 'realm': "example.com",
1229 'username': "hs20-test",
1230 'password': "password",
1231 'ca_cert': "auth_serv/ca.pem",
1232 'domain': "example.com",
1233 'domain_suffix_match': "server.w1.fi" })
1234 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1235 dev
[0].dump_monitor()
1236 interworking_connect(dev
[0], bssid
, "TTLS")
1237 dev
[0].request("REMOVE_NETWORK all")
1238 dev
[0].dump_monitor()
1240 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1241 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1242 dev
[0].dump_monitor()
1243 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1244 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1246 raise Exception("TLS certificate error not reported")
1247 if "Domain suffix mismatch" not in ev
:
1248 raise Exception("Domain suffix mismatch not reported")
1250 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1251 """Hotspot 2.0 and domain_suffix_match"""
1252 check_domain_match_full(dev
[0])
1253 bssid
= apdev
[0]['bssid']
1254 params
= hs20_ap_params()
1255 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1257 dev
[0].hs20_enable()
1258 id = dev
[0].add_cred_values({ 'realm': "example.com",
1259 'username': "hs20-test",
1260 'password': "password",
1261 'ca_cert': "auth_serv/ca.pem",
1262 'domain': "example.com",
1263 'domain_suffix_match': "w1.fi" })
1264 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1265 dev
[0].dump_monitor()
1266 interworking_connect(dev
[0], bssid
, "TTLS")
1268 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1269 """Hotspot 2.0 and roaming partner preference"""
1270 params
= hs20_ap_params()
1271 params
['domain_name'] = "roaming.example.org"
1272 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1274 params
= hs20_ap_params()
1275 params
['ssid'] = "test-hs20-other"
1276 params
['domain_name'] = "roaming.example.net"
1277 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1279 logger
.info("Verify default vs. specified preference")
1280 values
= default_cred()
1281 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1282 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1283 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1284 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1286 logger
.info("Verify partial FQDN match")
1287 values
['roaming_partner'] = "example.net,0,0,*"
1288 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1289 values
['roaming_partner'] = "example.net,0,255,*"
1290 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1292 def test_ap_hs20_max_bss_load(dev
, apdev
):
1293 """Hotspot 2.0 and maximum BSS load"""
1294 params
= hs20_ap_params()
1295 params
['bss_load_test'] = "12:200:20000"
1296 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1298 params
= hs20_ap_params()
1299 params
['ssid'] = "test-hs20-other"
1300 params
['bss_load_test'] = "5:20:10000"
1301 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1303 logger
.info("Verify maximum BSS load constraint")
1304 values
= default_cred()
1305 values
['domain'] = "example.com"
1306 values
['max_bss_load'] = "100"
1307 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1309 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1310 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1311 raise Exception("Maximum BSS Load case not noticed")
1312 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1313 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1314 raise Exception("Maximum BSS Load case reported incorrectly")
1316 logger
.info("Verify maximum BSS load does not prevent connection")
1317 values
['max_bss_load'] = "1"
1318 events
= policy_test(dev
[0], None, values
)
1320 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1321 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1322 raise Exception("Maximum BSS Load case not noticed")
1323 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1324 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1325 raise Exception("Maximum BSS Load case not noticed")
1327 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1328 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1329 params
= hs20_ap_params()
1330 params
['bss_load_test'] = "12:200:20000"
1331 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1333 params
= hs20_ap_params()
1334 params
['ssid'] = "test-hs20-other"
1335 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1337 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1338 values
= default_cred()
1339 values
['domain'] = "example.com"
1340 values
['max_bss_load'] = "100"
1341 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1343 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1344 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1345 raise Exception("Maximum BSS Load case not noticed")
1346 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1347 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1348 raise Exception("Maximum BSS Load case reported incorrectly")
1350 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1351 """Hotspot 2.0 multi-cred sp_priority"""
1353 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1355 dev
[0].request("SET external_sim 0")
1357 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1358 hlr_auc_gw_available()
1359 bssid
= apdev
[0]['bssid']
1360 params
= hs20_ap_params()
1361 params
['hessid'] = bssid
1362 del params
['domain_name']
1363 params
['anqp_3gpp_cell_net'] = "232,01"
1364 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1366 dev
[0].hs20_enable()
1367 dev
[0].scan_for_bss(bssid
, freq
="2412")
1368 dev
[0].request("SET external_sim 1")
1369 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1370 'provisioning_sp': "example.com",
1371 'sp_priority' :"1" })
1372 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1373 'ca_cert': "auth_serv/ca.pem",
1374 'username': "hs20-test",
1375 'password': "password",
1376 'domain': "example.com",
1377 'provisioning_sp': "example.com",
1378 'sp_priority': "2" })
1379 dev
[0].dump_monitor()
1380 dev
[0].scan_for_bss(bssid
, freq
="2412")
1381 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1382 interworking_ext_sim_auth(dev
[0], "SIM")
1383 check_sp_type(dev
[0], "unknown")
1384 dev
[0].request("REMOVE_NETWORK all")
1386 dev
[0].set_cred(id1
, "sp_priority", "2")
1387 dev
[0].set_cred(id2
, "sp_priority", "1")
1388 dev
[0].dump_monitor()
1389 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1390 interworking_auth(dev
[0], "TTLS")
1391 check_sp_type(dev
[0], "unknown")
1393 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1394 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1396 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1398 dev
[0].request("SET external_sim 0")
1400 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1401 hlr_auc_gw_available()
1402 bssid
= apdev
[0]['bssid']
1403 params
= hs20_ap_params()
1404 params
['hessid'] = bssid
1405 del params
['nai_realm']
1406 del params
['domain_name']
1407 params
['anqp_3gpp_cell_net'] = "232,01"
1408 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1410 bssid2
= apdev
[1]['bssid']
1411 params
= hs20_ap_params()
1412 params
['ssid'] = "test-hs20-other"
1413 params
['hessid'] = bssid2
1414 del params
['domain_name']
1415 del params
['anqp_3gpp_cell_net']
1416 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1418 dev
[0].hs20_enable()
1419 dev
[0].request("SET external_sim 1")
1420 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1421 'provisioning_sp': "example.com",
1422 'sp_priority': "1" })
1423 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1424 'ca_cert': "auth_serv/ca.pem",
1425 'username': "hs20-test",
1426 'password': "password",
1427 'domain': "example.com",
1428 'provisioning_sp': "example.com",
1429 'sp_priority': "2" })
1430 dev
[0].dump_monitor()
1431 dev
[0].scan_for_bss(bssid
, freq
="2412")
1432 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1433 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1434 interworking_ext_sim_auth(dev
[0], "SIM")
1435 check_sp_type(dev
[0], "unknown")
1436 conn_bssid
= dev
[0].get_status_field("bssid")
1437 if conn_bssid
!= bssid
:
1438 raise Exception("Connected to incorrect BSS")
1439 dev
[0].request("REMOVE_NETWORK all")
1441 dev
[0].set_cred(id1
, "sp_priority", "2")
1442 dev
[0].set_cred(id2
, "sp_priority", "1")
1443 dev
[0].dump_monitor()
1444 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1445 interworking_auth(dev
[0], "TTLS")
1446 check_sp_type(dev
[0], "unknown")
1447 conn_bssid
= dev
[0].get_status_field("bssid")
1448 if conn_bssid
!= bssid2
:
1449 raise Exception("Connected to incorrect BSS")
1451 def check_conn_capab_selection(dev
, type, missing
):
1452 dev
.request("INTERWORKING_SELECT freq=2412")
1453 ev
= dev
.wait_event(["INTERWORKING-AP"])
1455 raise Exception("Network selection timed out");
1456 if "type=" + type not in ev
:
1457 raise Exception("Unexpected network type")
1458 if missing
and "conn_capab_missing=1" not in ev
:
1459 raise Exception("conn_capab_missing not reported")
1460 if not missing
and "conn_capab_missing=1" in ev
:
1461 raise Exception("conn_capab_missing reported unexpectedly")
1463 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1464 cred
= default_cred(domain
=domain
)
1466 cred
['req_conn_capab'] = req_conn_capab
1469 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1470 """Hotspot 2.0 network selection with req_conn_capab"""
1471 bssid
= apdev
[0]['bssid']
1472 params
= hs20_ap_params()
1473 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1475 dev
[0].hs20_enable()
1476 dev
[0].scan_for_bss(bssid
, freq
="2412")
1477 logger
.info("Not used in home network")
1478 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1479 id = dev
[0].add_cred_values(values
)
1480 check_conn_capab_selection(dev
[0], "home", False)
1482 logger
.info("Used in roaming network")
1483 dev
[0].remove_cred(id)
1484 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1485 id = dev
[0].add_cred_values(values
)
1486 check_conn_capab_selection(dev
[0], "roaming", True)
1488 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1489 check_auto_select(dev
[0], bssid
)
1491 logger
.info("Additional req_conn_capab checks")
1493 dev
[0].remove_cred(id)
1494 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1495 id = dev
[0].add_cred_values(values
)
1496 check_conn_capab_selection(dev
[0], "roaming", True)
1498 dev
[0].remove_cred(id)
1499 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1500 id = dev
[0].add_cred_values(values
)
1501 check_conn_capab_selection(dev
[0], "roaming", True)
1503 bssid2
= apdev
[1]['bssid']
1504 params
= hs20_ap_params(ssid
="test-hs20b")
1505 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1506 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1508 dev
[0].remove_cred(id)
1509 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1510 id = dev
[0].add_cred_values(values
)
1511 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1512 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1513 dev
[0].request("INTERWORKING_SELECT freq=2412")
1514 for i
in range(0, 2):
1515 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1517 raise Exception("Network selection timed out");
1518 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1519 raise Exception("Missing protocol connection capability not reported")
1520 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1521 raise Exception("Protocol connection capability not reported correctly")
1523 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1524 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1525 bssid
= apdev
[0]['bssid']
1526 params
= hs20_ap_params()
1527 params
['domain_name'] = "roaming.example.org"
1528 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1529 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1531 bssid2
= apdev
[1]['bssid']
1532 params
= hs20_ap_params(ssid
="test-hs20-b")
1533 params
['domain_name'] = "roaming.example.net"
1534 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1536 values
= default_cred()
1537 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1538 id = dev
[0].add_cred_values(values
)
1539 check_auto_select(dev
[0], bssid2
)
1541 dev
[0].set_cred(id, "req_conn_capab", "50")
1542 check_auto_select(dev
[0], bssid
)
1544 dev
[0].remove_cred(id)
1545 id = dev
[0].add_cred_values(values
)
1546 dev
[0].set_cred(id, "req_conn_capab", "51")
1547 check_auto_select(dev
[0], bssid2
)
1549 def check_bandwidth_selection(dev
, type, below
):
1550 dev
.request("INTERWORKING_SELECT freq=2412")
1551 ev
= dev
.wait_event(["INTERWORKING-AP"])
1553 raise Exception("Network selection timed out");
1554 logger
.debug("BSS entries:\n" + dev
.request("BSS RANGE=ALL"))
1555 if "type=" + type not in ev
:
1556 raise Exception("Unexpected network type")
1557 if below
and "below_min_backhaul=1" not in ev
:
1558 raise Exception("below_min_backhaul not reported")
1559 if not below
and "below_min_backhaul=1" in ev
:
1560 raise Exception("below_min_backhaul reported unexpectedly")
1562 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1563 cred
= default_cred(domain
=domain
)
1565 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1567 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1569 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1571 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1574 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1575 """Hotspot 2.0 network selection with min bandwidth (home)"""
1576 bssid
= apdev
[0]['bssid']
1577 params
= hs20_ap_params()
1578 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1580 dev
[0].hs20_enable()
1581 dev
[0].scan_for_bss(bssid
, freq
="2412")
1582 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1583 id = dev
[0].add_cred_values(values
)
1584 check_bandwidth_selection(dev
[0], "home", False)
1585 dev
[0].remove_cred(id)
1587 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1588 id = dev
[0].add_cred_values(values
)
1589 check_bandwidth_selection(dev
[0], "home", True)
1590 dev
[0].remove_cred(id)
1592 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1593 id = dev
[0].add_cred_values(values
)
1594 check_bandwidth_selection(dev
[0], "home", True)
1595 dev
[0].remove_cred(id)
1597 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1598 id = dev
[0].add_cred_values(values
)
1599 check_bandwidth_selection(dev
[0], "home", True)
1600 check_auto_select(dev
[0], bssid
)
1602 bssid2
= apdev
[1]['bssid']
1603 params
= hs20_ap_params(ssid
="test-hs20-b")
1604 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1605 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1607 check_auto_select(dev
[0], bssid2
)
1609 def test_ap_hs20_min_bandwidth_home_hidden_ssid_in_scan_res(dev
, apdev
):
1610 """Hotspot 2.0 network selection with min bandwidth (home) while hidden SSID is included in scan results"""
1611 bssid
= apdev
[0]['bssid']
1613 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], { "ssid": 'secret',
1614 "ignore_broadcast_ssid": "1" })
1615 dev
[0].scan_for_bss(bssid
, freq
=2412)
1617 hapd_global
= hostapd
.HostapdGlobal()
1619 hapd_global
.remove(apdev
[0]['ifname'])
1621 params
= hs20_ap_params()
1622 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1624 dev
[0].hs20_enable()
1625 dev
[0].scan_for_bss(bssid
, freq
="2412")
1626 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1627 id = dev
[0].add_cred_values(values
)
1628 check_bandwidth_selection(dev
[0], "home", False)
1629 dev
[0].remove_cred(id)
1631 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1632 id = dev
[0].add_cred_values(values
)
1633 check_bandwidth_selection(dev
[0], "home", True)
1634 dev
[0].remove_cred(id)
1636 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1637 id = dev
[0].add_cred_values(values
)
1638 check_bandwidth_selection(dev
[0], "home", True)
1639 dev
[0].remove_cred(id)
1641 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1642 id = dev
[0].add_cred_values(values
)
1643 check_bandwidth_selection(dev
[0], "home", True)
1644 check_auto_select(dev
[0], bssid
)
1646 bssid2
= apdev
[1]['bssid']
1647 params
= hs20_ap_params(ssid
="test-hs20-b")
1648 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1649 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1651 check_auto_select(dev
[0], bssid2
)
1653 dev
[0].flush_scan_cache()
1655 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1656 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1657 bssid
= apdev
[0]['bssid']
1658 params
= hs20_ap_params()
1659 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1661 dev
[0].hs20_enable()
1662 dev
[0].scan_for_bss(bssid
, freq
="2412")
1663 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1664 id = dev
[0].add_cred_values(values
)
1665 check_bandwidth_selection(dev
[0], "roaming", False)
1666 dev
[0].remove_cred(id)
1668 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1669 id = dev
[0].add_cred_values(values
)
1670 check_bandwidth_selection(dev
[0], "roaming", True)
1671 dev
[0].remove_cred(id)
1673 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1674 id = dev
[0].add_cred_values(values
)
1675 check_bandwidth_selection(dev
[0], "roaming", True)
1676 dev
[0].remove_cred(id)
1678 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1679 id = dev
[0].add_cred_values(values
)
1680 check_bandwidth_selection(dev
[0], "roaming", True)
1681 check_auto_select(dev
[0], bssid
)
1683 bssid2
= apdev
[1]['bssid']
1684 params
= hs20_ap_params(ssid
="test-hs20-b")
1685 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1686 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1688 check_auto_select(dev
[0], bssid2
)
1690 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1691 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1692 bssid
= apdev
[0]['bssid']
1693 params
= hs20_ap_params()
1694 params
['domain_name'] = "roaming.example.org"
1695 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1696 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1698 bssid2
= apdev
[1]['bssid']
1699 params
= hs20_ap_params(ssid
="test-hs20-b")
1700 params
['domain_name'] = "roaming.example.net"
1701 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1703 values
= default_cred()
1704 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1705 id = dev
[0].add_cred_values(values
)
1706 check_auto_select(dev
[0], bssid2
)
1708 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1709 check_auto_select(dev
[0], bssid
)
1711 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1712 check_auto_select(dev
[0], bssid2
)
1714 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1715 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1716 bssid
= apdev
[0]['bssid']
1717 params
= hs20_ap_params()
1718 del params
['hs20_wan_metrics']
1719 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1721 dev
[0].hs20_enable()
1722 dev
[0].scan_for_bss(bssid
, freq
="2412")
1723 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1724 dl_roaming
=10000, ul_roaming
=10000)
1725 dev
[0].add_cred_values(values
)
1726 check_bandwidth_selection(dev
[0], "home", False)
1728 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1729 """Hotspot 2.0 connection and deauthentication request for ESS"""
1731 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
1733 dev
[0].request("SET pmf 0")
1735 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
1736 dev
[0].request("SET pmf 2")
1737 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1738 dev
[0].dump_monitor()
1739 addr
= dev
[0].p2p_interface_addr()
1740 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1741 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1742 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1744 raise Exception("Timeout on deauth imminent notice")
1745 if "1 120 http://example.com/" not in ev
:
1746 raise Exception("Unexpected deauth imminent notice: " + ev
)
1747 hapd
.request("DEAUTHENTICATE " + addr
)
1748 dev
[0].wait_disconnected(timeout
=10)
1749 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1750 raise Exception("Network not marked temporarily disabled")
1751 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1752 "Trying to associate",
1753 "CTRL-EVENT-CONNECTED"], timeout
=5)
1755 raise Exception("Unexpected connection attempt")
1757 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1758 """Hotspot 2.0 connection and deauthentication request for BSS"""
1760 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
1762 dev
[0].request("SET pmf 0")
1764 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
1765 dev
[0].request("SET pmf 2")
1766 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1767 dev
[0].dump_monitor()
1768 addr
= dev
[0].p2p_interface_addr()
1769 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1770 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1771 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1773 raise Exception("Timeout on deauth imminent notice")
1774 if "0 120 http://example.com/" not in ev
:
1775 raise Exception("Unexpected deauth imminent notice: " + ev
)
1776 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1777 ev
= dev
[0].wait_disconnected(timeout
=10)
1778 if "reason=4" not in ev
:
1779 raise Exception("Unexpected disconnection reason")
1780 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1781 raise Exception("Network not marked temporarily disabled")
1782 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1783 "Trying to associate",
1784 "CTRL-EVENT-CONNECTED"], timeout
=5)
1786 raise Exception("Unexpected connection attempt")
1788 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1789 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1791 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
1793 dev
[0].request("SET pmf 0")
1795 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1796 bssid
= apdev
[0]['bssid']
1797 params
= hs20_ap_params()
1798 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1799 params
['hs20_deauth_req_timeout'] = "2"
1800 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1802 dev
[0].request("SET pmf 2")
1803 dev
[0].hs20_enable()
1804 dev
[0].add_cred_values({ 'realm': "example.com",
1805 'username': "hs20-deauth-test",
1806 'password': "password" })
1807 interworking_select(dev
[0], bssid
, freq
="2412")
1808 interworking_connect(dev
[0], bssid
, "TTLS")
1809 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1811 raise Exception("Timeout on deauth imminent notice")
1812 if " 1 100" not in ev
:
1813 raise Exception("Unexpected deauth imminent contents")
1814 dev
[0].wait_disconnected(timeout
=3)
1816 def test_ap_hs20_remediation_required(dev
, apdev
):
1817 """Hotspot 2.0 connection and remediation required from RADIUS"""
1819 _test_ap_hs20_remediation_required(dev
, apdev
)
1821 dev
[0].request("SET pmf 0")
1823 def _test_ap_hs20_remediation_required(dev
, apdev
):
1824 bssid
= apdev
[0]['bssid']
1825 params
= hs20_ap_params()
1826 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1827 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1829 dev
[0].request("SET pmf 1")
1830 dev
[0].hs20_enable()
1831 dev
[0].add_cred_values({ 'realm': "example.com",
1832 'username': "hs20-subrem-test",
1833 'password': "password" })
1834 interworking_select(dev
[0], bssid
, freq
="2412")
1835 interworking_connect(dev
[0], bssid
, "TTLS")
1836 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1838 raise Exception("Timeout on subscription remediation notice")
1839 if " 1 https://example.com/" not in ev
:
1840 raise Exception("Unexpected subscription remediation event contents")
1842 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1843 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1845 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
1847 dev
[0].request("SET pmf 0")
1849 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1850 bssid
= apdev
[0]['bssid']
1851 addr
= dev
[0].own_addr()
1852 params
= hs20_ap_params()
1853 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1854 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
1856 dev
[0].request("SET pmf 1")
1857 dev
[0].hs20_enable()
1858 dev
[0].add_cred_values(default_cred())
1859 interworking_select(dev
[0], bssid
, freq
="2412")
1860 interworking_connect(dev
[0], bssid
, "TTLS")
1862 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1863 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1865 raise Exception("Timeout on subscription remediation notice")
1866 if " 1 https://example.com/" not in ev
:
1867 raise Exception("Unexpected subscription remediation event contents")
1869 hapd
.request("HS20_WNM_NOTIF " + addr
)
1870 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1872 raise Exception("Timeout on subscription remediation notice")
1873 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1874 raise Exception("Unexpected subscription remediation event contents: " + ev
)
1876 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
1877 raise Exception("Unexpected HS20_WNM_NOTIF success")
1878 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
1879 raise Exception("Unexpected HS20_WNM_NOTIF success")
1880 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1881 raise Exception("Unexpected HS20_WNM_NOTIF success")
1883 def test_ap_hs20_session_info(dev
, apdev
):
1884 """Hotspot 2.0 connection and session information from RADIUS"""
1886 _test_ap_hs20_session_info(dev
, apdev
)
1888 dev
[0].request("SET pmf 0")
1890 def _test_ap_hs20_session_info(dev
, apdev
):
1891 bssid
= apdev
[0]['bssid']
1892 params
= hs20_ap_params()
1893 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1894 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1896 dev
[0].request("SET pmf 1")
1897 dev
[0].hs20_enable()
1898 dev
[0].add_cred_values({ 'realm': "example.com",
1899 'username': "hs20-session-info-test",
1900 'password': "password" })
1901 interworking_select(dev
[0], bssid
, freq
="2412")
1902 interworking_connect(dev
[0], bssid
, "TTLS")
1903 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
1905 raise Exception("Timeout on ESS disassociation imminent notice")
1906 if " 1 59904 https://example.com/" not in ev
:
1907 raise Exception("Unexpected ESS disassociation imminent event contents")
1908 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1910 raise Exception("Scan not started")
1911 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
1913 raise Exception("Scan not completed")
1915 def test_ap_hs20_osen(dev
, apdev
):
1916 """Hotspot 2.0 OSEN connection"""
1917 params
= { 'ssid': "osen",
1919 'auth_server_addr': "127.0.0.1",
1920 'auth_server_port': "1812",
1921 'auth_server_shared_secret': "radius" }
1922 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1924 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
1926 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
1927 scan_freq
="2412", wait_connect
=False)
1928 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1929 group
="GTK_NOT_USED",
1930 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1931 ca_cert
="auth_serv/ca.pem",
1934 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1935 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1936 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1937 group
="GTK_NOT_USED",
1938 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1939 ca_cert
="auth_serv/ca.pem",
1941 wpas
.request("DISCONNECT")
1943 def test_ap_hs20_network_preference(dev
, apdev
):
1944 """Hotspot 2.0 network selection with preferred home network"""
1945 bssid
= apdev
[0]['bssid']
1946 params
= hs20_ap_params()
1947 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1949 dev
[0].hs20_enable()
1950 values
= { 'realm': "example.com",
1951 'username': "hs20-test",
1952 'password': "password",
1953 'domain': "example.com" }
1954 dev
[0].add_cred_values(values
)
1956 id = dev
[0].add_network()
1957 dev
[0].set_network_quoted(id, "ssid", "home")
1958 dev
[0].set_network_quoted(id, "psk", "12345678")
1959 dev
[0].set_network(id, "priority", "1")
1960 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1962 dev
[0].scan_for_bss(bssid
, freq
="2412")
1963 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1964 ev
= dev
[0].wait_connected(timeout
=15)
1966 raise Exception("Unexpected network selected")
1968 bssid2
= apdev
[1]['bssid']
1969 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1970 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1972 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1973 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1974 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1975 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1977 raise Exception("Connection timed out")
1978 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1979 raise Exception("No roam to higher priority network")
1980 if bssid2
not in ev
:
1981 raise Exception("Unexpected network selected")
1983 def test_ap_hs20_network_preference2(dev
, apdev
):
1984 """Hotspot 2.0 network selection with preferred credential"""
1985 bssid2
= apdev
[1]['bssid']
1986 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1987 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1989 dev
[0].hs20_enable()
1990 values
= { 'realm': "example.com",
1991 'username': "hs20-test",
1992 'password': "password",
1993 'domain': "example.com",
1995 dev
[0].add_cred_values(values
)
1997 id = dev
[0].add_network()
1998 dev
[0].set_network_quoted(id, "ssid", "home")
1999 dev
[0].set_network_quoted(id, "psk", "12345678")
2000 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
2002 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2003 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2004 ev
= dev
[0].wait_connected(timeout
=15)
2005 if bssid2
not in ev
:
2006 raise Exception("Unexpected network selected")
2008 bssid
= apdev
[0]['bssid']
2009 params
= hs20_ap_params()
2010 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2012 dev
[0].scan_for_bss(bssid
, freq
="2412")
2013 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2014 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2015 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2017 raise Exception("Connection timed out")
2018 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2019 raise Exception("No roam to higher priority network")
2021 raise Exception("Unexpected network selected")
2023 def test_ap_hs20_network_preference3(dev
, apdev
):
2024 """Hotspot 2.0 network selection with two credential (one preferred)"""
2025 bssid
= apdev
[0]['bssid']
2026 params
= hs20_ap_params()
2027 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2029 bssid2
= apdev
[1]['bssid']
2030 params
= hs20_ap_params(ssid
="test-hs20b")
2031 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
2032 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2034 dev
[0].hs20_enable()
2035 values
= { 'realm': "example.com",
2036 'username': "hs20-test",
2037 'password': "password",
2039 dev
[0].add_cred_values(values
)
2040 values
= { 'realm': "example.org",
2041 'username': "hs20-test",
2042 'password': "password" }
2043 id = dev
[0].add_cred_values(values
)
2045 dev
[0].scan_for_bss(bssid
, freq
="2412")
2046 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2047 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2048 ev
= dev
[0].wait_connected(timeout
=15)
2050 raise Exception("Unexpected network selected")
2052 dev
[0].set_cred(id, "priority", "2")
2053 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2054 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2055 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2057 raise Exception("Connection timed out")
2058 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2059 raise Exception("No roam to higher priority network")
2060 if bssid2
not in ev
:
2061 raise Exception("Unexpected network selected")
2063 def test_ap_hs20_network_preference4(dev
, apdev
):
2064 """Hotspot 2.0 network selection with username vs. SIM credential"""
2065 bssid
= apdev
[0]['bssid']
2066 params
= hs20_ap_params()
2067 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2069 bssid2
= apdev
[1]['bssid']
2070 params
= hs20_ap_params(ssid
="test-hs20b")
2071 params
['hessid'] = bssid2
2072 params
['anqp_3gpp_cell_net'] = "555,444"
2073 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
2074 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2076 dev
[0].hs20_enable()
2077 values
= { 'realm': "example.com",
2078 'username': "hs20-test",
2079 'password': "password",
2081 dev
[0].add_cred_values(values
)
2082 values
= { 'imsi': "555444-333222111",
2084 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
2085 id = dev
[0].add_cred_values(values
)
2087 dev
[0].scan_for_bss(bssid
, freq
="2412")
2088 dev
[0].scan_for_bss(bssid2
, freq
="2412")
2089 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2090 ev
= dev
[0].wait_connected(timeout
=15)
2092 raise Exception("Unexpected network selected")
2094 dev
[0].set_cred(id, "priority", "2")
2095 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2096 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2097 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2099 raise Exception("Connection timed out")
2100 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2101 raise Exception("No roam to higher priority network")
2102 if bssid2
not in ev
:
2103 raise Exception("Unexpected network selected")
2105 def test_ap_hs20_fetch_osu(dev
, apdev
):
2106 """Hotspot 2.0 OSU provider and icon fetch"""
2107 bssid
= apdev
[0]['bssid']
2108 params
= hs20_ap_params()
2109 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2110 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2111 params
['osu_method_list'] = "1"
2112 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2113 params
['osu_icon'] = "w1fi_logo"
2114 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2115 params
['osu_server_uri'] = "https://example.com/osu/"
2116 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2118 bssid2
= apdev
[1]['bssid']
2119 params
= hs20_ap_params(ssid
="test-hs20b")
2120 params
['hessid'] = bssid2
2121 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2122 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2123 params
['osu_method_list'] = "0"
2124 params
['osu_nai'] = "osen@example.com"
2125 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2126 params
['osu_icon'] = "w1fi_logo"
2127 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2128 params
['osu_server_uri'] = "https://example.org/osu/"
2129 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2131 with
open("w1fi_logo.png", "r") as f
:
2132 orig_logo
= f
.read()
2133 dev
[0].hs20_enable()
2134 dir = "/tmp/osu-fetch"
2135 if os
.path
.isdir(dir):
2136 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2138 os
.remove(dir + "/" + f
)
2145 dev
[1].scan_for_bss(bssid
, freq
="2412")
2146 dev
[0].request("SET osu_dir " + dir)
2147 dev
[0].request("FETCH_OSU")
2148 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2149 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2150 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2151 raise Exception("HS20_ICON_REQUEST failed")
2154 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2155 "RX-HS20-ANQP-ICON"], timeout
=15)
2157 raise Exception("Timeout on OSU fetch")
2158 if "OSU provider fetch completed" in ev
:
2160 if "RX-HS20-ANQP-ICON" in ev
:
2161 with
open(ev
.split(' ')[1], "r") as f
:
2163 if logo
== orig_logo
:
2166 with
open(dir + "/osu-providers.txt", "r") as f
:
2168 logger
.debug("osu-providers.txt: " + prov
)
2169 if "OSU-PROVIDER " + bssid
not in prov
:
2170 raise Exception("Missing OSU_PROVIDER(1)")
2171 if "OSU-PROVIDER " + bssid2
not in prov
:
2172 raise Exception("Missing OSU_PROVIDER(2)")
2174 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2176 os
.remove(dir + "/" + f
)
2180 raise Exception("Unexpected number of icons fetched")
2182 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2184 raise Exception("Timeout on GAS-QUERY-DONE")
2185 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2187 raise Exception("Timeout on GAS-QUERY-DONE")
2188 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2189 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2190 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2192 raise Exception("Timeout on icon fetch")
2193 if "Icon Binary File" not in ev
:
2194 raise Exception("Unexpected ANQP element")
2196 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
2197 """Hotspot 2.0 OSU provider fetch stopped"""
2198 bssid
= apdev
[0]['bssid']
2199 params
= hs20_ap_params()
2200 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2201 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2202 params
['osu_method_list'] = "1"
2203 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2204 params
['osu_icon'] = "w1fi_logo"
2205 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2206 params
['osu_server_uri'] = "https://example.com/osu/"
2207 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2209 dev
[0].hs20_enable()
2210 dir = "/tmp/osu-fetch"
2211 if os
.path
.isdir(dir):
2212 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2214 os
.remove(dir + "/" + f
)
2221 dev
[0].request("SET osu_dir " + dir)
2222 dev
[0].request("SCAN freq=2412-2462")
2223 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
2225 raise Exception("Scan did not start")
2226 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2227 raise Exception("FETCH_OSU accepted while scanning")
2228 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2230 raise Exception("Scan timed out")
2231 hapd
.set("ext_mgmt_frame_handling", "1")
2232 dev
[0].request("FETCH_ANQP")
2233 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2234 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2235 dev
[0].request("STOP_FETCH_ANQP")
2236 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2237 dev
[0].dump_monitor()
2239 dev
[0].request("INTERWORKING_SELECT freq=2412")
2241 msg
= hapd
.mgmt_rx()
2242 if msg
['subtype'] == 13:
2244 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2245 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2246 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2249 raise Exception("Network selection timed out");
2251 dev
[0].dump_monitor()
2252 if "OK" not in dev
[0].request("FETCH_OSU"):
2253 raise Exception("FETCH_OSU failed")
2254 dev
[0].request("CANCEL_FETCH_OSU")
2258 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2261 dev
[0].dump_monitor()
2262 if "OK" not in dev
[0].request("FETCH_OSU"):
2263 raise Exception("FETCH_OSU failed")
2264 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2265 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2266 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
2268 raise Exception("GAS timed out")
2269 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2270 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2271 dev
[0].request("CANCEL_FETCH_OSU")
2272 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
2274 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2276 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2278 os
.remove(dir + "/" + f
)
2281 def test_ap_hs20_ft(dev
, apdev
):
2282 """Hotspot 2.0 connection with FT"""
2283 bssid
= apdev
[0]['bssid']
2284 params
= hs20_ap_params()
2285 params
['wpa_key_mgmt'] = "FT-EAP"
2286 params
['nas_identifier'] = "nas1.w1.fi"
2287 params
['r1_key_holder'] = "000102030405"
2288 params
["mobility_domain"] = "a1b2"
2289 params
["reassociation_deadline"] = "1000"
2290 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2292 dev
[0].hs20_enable()
2293 id = dev
[0].add_cred_values({ 'realm': "example.com",
2294 'username': "hs20-test",
2295 'password': "password",
2296 'ca_cert': "auth_serv/ca.pem",
2297 'domain': "example.com",
2298 'update_identifier': "1234" })
2299 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2300 interworking_connect(dev
[0], bssid
, "TTLS")
2302 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2303 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2307 raise HwsimSkip("No sqlite3 module available")
2308 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2313 con
= sqlite3
.connect(dbfile
)
2316 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2317 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2318 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2319 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2320 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2323 params
= { "ssid": "as", "beacon_int": "2000",
2324 "radius_server_clients": "auth_serv/radius_clients.conf",
2325 "radius_server_auth_port": '18128',
2327 "eap_user_file": "sqlite:" + dbfile
,
2328 "ca_cert": "auth_serv/ca.pem",
2329 "server_cert": "auth_serv/server.pem",
2330 "private_key": "auth_serv/server.key",
2331 "subscr_remediation_url": "https://example.org/",
2332 "subscr_remediation_method": "1" }
2333 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2335 bssid
= apdev
[0]['bssid']
2336 params
= hs20_ap_params()
2337 params
['auth_server_port'] = "18128"
2338 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2340 dev
[0].request("SET pmf 1")
2341 dev
[0].hs20_enable()
2342 id = dev
[0].add_cred_values({ 'realm': "example.com",
2343 'username': "user-mschapv2",
2344 'password': "password",
2345 'ca_cert': "auth_serv/ca.pem" })
2346 interworking_select(dev
[0], bssid
, freq
="2412")
2347 interworking_connect(dev
[0], bssid
, "TTLS")
2348 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2350 raise Exception("Timeout on subscription remediation notice")
2351 if " 1 https://example.org/" not in ev
:
2352 raise Exception("Unexpected subscription remediation event contents")
2356 cur
.execute("SELECT * from authlog")
2357 rows
= cur
.fetchall()
2359 raise Exception("No authlog entries")
2363 dev
[0].request("SET pmf 0")
2365 def test_ap_hs20_external_selection(dev
, apdev
):
2366 """Hotspot 2.0 connection using external network selection and creation"""
2367 bssid
= apdev
[0]['bssid']
2368 params
= hs20_ap_params()
2369 params
['hessid'] = bssid
2370 params
['disable_dgaf'] = '1'
2371 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2373 dev
[0].hs20_enable()
2374 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2375 identity
="hs20-test", password
="password",
2376 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2377 scan_freq
="2412", update_identifier
="54321")
2378 if dev
[0].get_status_field("hs20") != "2":
2379 raise Exception("Unexpected hs20 indication")
2381 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2382 """Hotspot 2.0 connection with random MAC address"""
2383 bssid
= apdev
[0]['bssid']
2384 params
= hs20_ap_params()
2385 params
['hessid'] = bssid
2386 params
['disable_dgaf'] = '1'
2387 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2389 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2390 wpas
.interface_add("wlan5")
2391 addr
= wpas
.p2p_interface_addr()
2392 wpas
.request("SET mac_addr 1")
2393 wpas
.request("SET preassoc_mac_addr 1")
2394 wpas
.request("SET rand_addr_lifetime 60")
2396 wpas
.flush_scan_cache()
2397 id = wpas
.add_cred_values({ 'realm': "example.com",
2398 'username': "hs20-test",
2399 'password': "password",
2400 'ca_cert': "auth_serv/ca.pem",
2401 'domain': "example.com",
2402 'update_identifier': "1234" })
2403 interworking_select(wpas
, bssid
, "home", freq
="2412")
2404 interworking_connect(wpas
, bssid
, "TTLS")
2405 addr1
= wpas
.get_driver_status_field("addr")
2407 raise Exception("Did not use random MAC address")
2409 sta
= hapd
.get_sta(addr
)
2410 if sta
['addr'] != "FAIL":
2411 raise Exception("Unexpected STA association with permanent address")
2412 sta
= hapd
.get_sta(addr1
)
2413 if sta
['addr'] != addr1
:
2414 raise Exception("STA association with random address not found")
2416 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2417 """Multiple networks and cred removal"""
2418 bssid
= apdev
[0]['bssid']
2419 params
= hs20_ap_params()
2420 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2421 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2423 dev
[0].add_network()
2424 dev
[0].hs20_enable()
2425 id = dev
[0].add_cred_values({ 'realm': "example.com",
2427 'password': "password" })
2428 interworking_select(dev
[0], bssid
, freq
="2412")
2429 interworking_connect(dev
[0], bssid
, "PEAP")
2430 dev
[0].add_network()
2432 dev
[0].request("DISCONNECT")
2433 dev
[0].wait_disconnected(timeout
=10)
2436 hapd
.set("ssid", "another ssid")
2439 interworking_select(dev
[0], bssid
, freq
="2412")
2440 interworking_connect(dev
[0], bssid
, "PEAP")
2441 dev
[0].add_network()
2442 if len(dev
[0].list_networks()) != 5:
2443 raise Exception("Unexpected number of networks prior to remove_crec")
2445 dev
[0].dump_monitor()
2446 dev
[0].remove_cred(id)
2447 if len(dev
[0].list_networks()) != 3:
2448 raise Exception("Unexpected number of networks after to remove_crec")
2449 dev
[0].wait_disconnected(timeout
=10)
2451 def _test_ap_hs20_proxyarp(dev
, apdev
):
2452 bssid
= apdev
[0]['bssid']
2453 params
= hs20_ap_params()
2454 params
['hessid'] = bssid
2455 params
['disable_dgaf'] = '0'
2456 params
['proxy_arp'] = '1'
2457 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2458 if "OK" in hapd
.request("ENABLE"):
2459 raise Exception("Incomplete hostapd configuration was accepted")
2460 hapd
.set("ap_isolate", "1")
2461 if "OK" in hapd
.request("ENABLE"):
2462 raise Exception("Incomplete hostapd configuration was accepted")
2463 hapd
.set('bridge', 'ap-br0')
2468 # For now, do not report failures due to missing kernel support
2469 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2470 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2472 raise Exception("AP startup timed out")
2473 if "AP-ENABLED" not in ev
:
2474 raise Exception("AP startup failed")
2476 dev
[0].hs20_enable()
2477 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2478 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2480 id = dev
[0].add_cred_values({ 'realm': "example.com",
2481 'username': "hs20-test",
2482 'password': "password",
2483 'ca_cert': "auth_serv/ca.pem",
2484 'domain': "example.com",
2485 'update_identifier': "1234" })
2486 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2487 interworking_connect(dev
[0], bssid
, "TTLS")
2489 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2490 identity
="hs20-test", password
="password",
2491 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2495 addr0
= dev
[0].p2p_interface_addr()
2496 addr1
= dev
[1].p2p_interface_addr()
2498 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2499 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2501 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2502 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2504 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2505 raise Exception("DATA_TEST_FRAME failed")
2507 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2508 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2510 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2511 raise Exception("DATA_TEST_FRAME failed")
2513 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2514 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2516 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2517 raise Exception("DATA_TEST_FRAME failed")
2519 matches
= get_permanent_neighbors("ap-br0")
2520 logger
.info("After connect: " + str(matches
))
2521 if len(matches
) != 3:
2522 raise Exception("Unexpected number of neighbor entries after connect")
2523 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2524 raise Exception("dev0 addr missing")
2525 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2526 raise Exception("dev1 addr(1) missing")
2527 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2528 raise Exception("dev1 addr(2) missing")
2529 dev
[0].request("DISCONNECT")
2530 dev
[1].request("DISCONNECT")
2532 matches
= get_permanent_neighbors("ap-br0")
2533 logger
.info("After disconnect: " + str(matches
))
2534 if len(matches
) > 0:
2535 raise Exception("Unexpected neighbor entries after disconnect")
2537 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
2538 """Hotspot 2.0 connection with hidden SSId in scan results"""
2539 bssid
= apdev
[0]['bssid']
2541 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], { "ssid": 'secret',
2542 "ignore_broadcast_ssid": "1" })
2543 dev
[0].scan_for_bss(bssid
, freq
=2412)
2545 hapd_global
= hostapd
.HostapdGlobal()
2547 hapd_global
.remove(apdev
[0]['ifname'])
2549 params
= hs20_ap_params()
2550 params
['hessid'] = bssid
2551 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2553 dev
[0].hs20_enable()
2554 id = dev
[0].add_cred_values({ 'realm': "example.com",
2555 'username': "hs20-test",
2556 'password': "password",
2557 'ca_cert': "auth_serv/ca.pem",
2558 'domain': "example.com" })
2559 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2560 interworking_connect(dev
[0], bssid
, "TTLS")
2562 # clear BSS table to avoid issues in following test cases
2563 dev
[0].request("DISCONNECT")
2564 dev
[0].wait_disconnected()
2565 dev
[0].flush_scan_cache()
2567 def test_ap_hs20_proxyarp(dev
, apdev
):
2568 """Hotspot 2.0 and ProxyARP"""
2570 _test_ap_hs20_proxyarp(dev
, apdev
)
2572 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2573 stderr
=open('/dev/null', 'w'))
2574 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2575 stderr
=open('/dev/null', 'w'))
2577 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2578 bssid
= apdev
[0]['bssid']
2579 params
= hs20_ap_params()
2580 params
['hessid'] = bssid
2581 params
['disable_dgaf'] = '1' if disabled
else '0'
2582 params
['proxy_arp'] = '1'
2583 params
['ap_isolate'] = '1'
2584 params
['bridge'] = 'ap-br0'
2585 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2589 # For now, do not report failures due to missing kernel support
2590 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2591 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2593 raise Exception("AP startup timed out")
2595 dev
[0].hs20_enable()
2596 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2597 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2599 id = dev
[0].add_cred_values({ 'realm': "example.com",
2600 'username': "hs20-test",
2601 'password': "password",
2602 'ca_cert': "auth_serv/ca.pem",
2603 'domain': "example.com",
2604 'update_identifier': "1234" })
2605 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2606 interworking_connect(dev
[0], bssid
, "TTLS")
2608 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2609 identity
="hs20-test", password
="password",
2610 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2614 addr0
= dev
[0].p2p_interface_addr()
2616 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2618 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2619 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2621 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2622 raise Exception("DATA_TEST_FRAME failed")
2624 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2626 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2627 raise Exception("DATA_TEST_FRAME failed")
2629 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2630 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2631 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2632 raise Exception("DATA_TEST_FRAME failed")
2634 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2635 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2636 yiaddr
="192.168.1.123", chaddr
=addr0
)
2637 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2638 raise Exception("DATA_TEST_FRAME failed")
2639 # another copy for additional code coverage
2640 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2641 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2642 yiaddr
="192.168.1.123", chaddr
=addr0
)
2643 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2644 raise Exception("DATA_TEST_FRAME failed")
2646 matches
= get_permanent_neighbors("ap-br0")
2647 logger
.info("After connect: " + str(matches
))
2648 if len(matches
) != 2:
2649 raise Exception("Unexpected number of neighbor entries after connect")
2650 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2651 raise Exception("dev0 addr missing")
2652 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2653 raise Exception("dev0 IPv4 addr missing")
2654 dev
[0].request("DISCONNECT")
2655 dev
[1].request("DISCONNECT")
2657 matches
= get_permanent_neighbors("ap-br0")
2658 logger
.info("After disconnect: " + str(matches
))
2659 if len(matches
) > 0:
2660 raise Exception("Unexpected neighbor entries after disconnect")
2662 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2663 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2665 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2667 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2668 stderr
=open('/dev/null', 'w'))
2669 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2670 stderr
=open('/dev/null', 'w'))
2672 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2673 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2675 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2677 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2678 stderr
=open('/dev/null', 'w'))
2679 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2680 stderr
=open('/dev/null', 'w'))
2682 def ip_checksum(buf
):
2686 for i
in range(0, len(buf
), 2):
2687 val
, = struct
.unpack('H', buf
[i
:i
+2])
2690 sum = (sum & 0xffff) + (sum >> 16)
2691 return struct
.pack('H', ~
sum & 0xffff)
2693 def ipv6_solicited_node_mcaddr(target
):
2694 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
2695 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
2696 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2697 p
= struct
.unpack('4I', prefix
)
2698 m
= struct
.unpack('4I', mask
)
2699 t
= struct
.unpack('4I', _target
)
2700 res
= (p
[0] |
(t
[0] & m
[0]),
2701 p
[1] |
(t
[1] & m
[1]),
2702 p
[2] |
(t
[2] & m
[2]),
2703 p
[3] |
(t
[3] & m
[3]))
2704 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
2706 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2707 start
= struct
.pack("BB", type, code
)
2709 icmp
= start
+ '\x00\x00' + end
2710 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2711 csum
= ip_checksum(pseudo
+ icmp
)
2712 return start
+ csum
+ end
2714 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2715 reachable_time
=0, retrans_timer
=0, opt
=None):
2716 link_mc
= binascii
.unhexlify("3333ff000002")
2717 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2719 ehdr
= link_mc
+ _src_ll
+ proto
2720 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2721 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2723 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2724 reachable_time
, retrans_timer
)
2729 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2731 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2732 ipv6
+= _ip_src
+ _ip_dst
2734 return ehdr
+ ipv6
+ icmp
2736 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2737 link_mc
= binascii
.unhexlify("3333ff000002")
2738 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2740 ehdr
= link_mc
+ _src_ll
+ proto
2741 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2743 ip_dst
= ipv6_solicited_node_mcaddr(target
)
2744 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2746 reserved
= '\x00\x00\x00\x00'
2747 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2749 payload
= reserved
+ _target
+ opt
2751 payload
= reserved
+ _target
2752 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2754 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2755 ipv6
+= _ip_src
+ _ip_dst
2757 return ehdr
+ ipv6
+ icmp
2759 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
2764 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2767 src_ll
= dev
.p2p_interface_addr()
2768 cmd
= "DATA_TEST_FRAME "
2771 opt
= "\x01\x01" + binascii
.unhexlify(src_ll
.replace(':',''))
2773 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
2775 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2776 raise Exception("DATA_TEST_FRAME failed")
2778 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2779 link_mc
= binascii
.unhexlify("3333ff000002")
2780 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2782 ehdr
= link_mc
+ _src_ll
+ proto
2783 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2784 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2786 reserved
= '\x00\x00\x00\x00'
2787 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2789 payload
= reserved
+ _target
+ opt
2791 payload
= reserved
+ _target
2792 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2794 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2795 ipv6
+= _ip_src
+ _ip_dst
2797 return ehdr
+ ipv6
+ icmp
2799 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
2804 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2807 src_ll
= dev
.p2p_interface_addr()
2808 cmd
= "DATA_TEST_FRAME "
2810 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
2812 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2813 raise Exception("DATA_TEST_FRAME failed")
2815 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
2816 subnet_mask
="255.255.255.0", truncated_opt
=False,
2817 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
2818 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2819 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2821 ehdr
= _dst_ll
+ _src_ll
+ proto
2822 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
2823 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
2824 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
2826 _ciaddr
= '\x00\x00\x00\x00'
2827 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
2828 _siaddr
= '\x00\x00\x00\x00'
2829 _giaddr
= '\x00\x00\x00\x00'
2830 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
2831 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2832 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2835 payload
+= '\x63\x82\x53\x00'
2837 payload
+= '\x63\x82\x53\x63'
2839 payload
+= '\x22\xff\x00'
2840 # Option: DHCP Message Type = ACK
2841 payload
+= '\x35\x01\x05'
2844 # Option: Subnet Mask
2845 payload
+= '\x01\x04' + _subnet_mask
2846 # Option: Time Offset
2847 payload
+= struct
.pack('>BBL', 2, 4, 0)
2851 payload
+= '\x00\x00\x00\x00'
2854 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2855 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2857 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
2860 tot_len
= force_tot_len
2862 tot_len
= 20 + len(udp
)
2863 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
2864 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
2865 csum
= ip_checksum(ipv4
)
2866 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
2868 return ehdr
+ ipv4
+ udp
2870 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
2871 target_mac
, target_ip
):
2872 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2873 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2875 ehdr
= _dst_ll
+ _src_ll
+ proto
2877 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
2878 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
2879 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
2880 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
2882 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
2883 arp
+= _sender_mac
+ _sender_ip
2884 arp
+= _target_mac
+ _target_ip
2888 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
2889 sender_mac
=None, sender_ip
="0.0.0.0",
2890 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
2895 if sender_mac
is None:
2896 sender_mac
= hapd_bssid
2897 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2900 src_ll
= dev
.p2p_interface_addr()
2901 if sender_mac
is None:
2902 sender_mac
= dev
.p2p_interface_addr()
2903 cmd
= "DATA_TEST_FRAME "
2905 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
2906 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
2907 target_mac
=target_mac
, target_ip
=target_ip
)
2908 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2909 raise Exception("DATA_TEST_FRAME failed")
2911 def get_permanent_neighbors(ifname
):
2912 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2913 res
= cmd
.stdout
.read()
2915 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2917 def get_bridge_macs(ifname
):
2918 cmd
= subprocess
.Popen(['brctl', 'showmacs', ifname
],
2919 stdout
=subprocess
.PIPE
)
2920 res
= cmd
.stdout
.read()
2924 def tshark_get_arp(cap
, filter):
2925 res
= run_tshark(cap
, filter,
2926 [ "eth.dst", "eth.src",
2927 "arp.src.hw_mac", "arp.src.proto_ipv4",
2928 "arp.dst.hw_mac", "arp.dst.proto_ipv4" ],
2931 for l
in res
.splitlines():
2932 frames
.append(l
.split('\t'))
2935 def tshark_get_ns(cap
):
2936 res
= run_tshark(cap
, "icmpv6.type == 135",
2937 [ "eth.dst", "eth.src",
2938 "ipv6.src", "ipv6.dst",
2939 "icmpv6.nd.ns.target_address",
2940 "icmpv6.opt.linkaddr" ],
2943 for l
in res
.splitlines():
2944 frames
.append(l
.split('\t'))
2947 def tshark_get_na(cap
):
2948 res
= run_tshark(cap
, "icmpv6.type == 136",
2949 [ "eth.dst", "eth.src",
2950 "ipv6.src", "ipv6.dst",
2951 "icmpv6.nd.na.target_address",
2952 "icmpv6.opt.linkaddr" ],
2955 for l
in res
.splitlines():
2956 frames
.append(l
.split('\t'))
2959 def _test_proxyarp_open(dev
, apdev
, params
, ebtables
=False):
2960 prefix
= "proxyarp_open"
2962 prefix
+= "_ebtables"
2963 cap_br
= os
.path
.join(params
['logdir'], prefix
+ ".ap-br0.pcap")
2964 cap_dev0
= os
.path
.join(params
['logdir'],
2965 prefix
+ ".%s.pcap" % dev
[0].ifname
)
2966 cap_dev1
= os
.path
.join(params
['logdir'],
2967 prefix
+ ".%s.pcap" % dev
[1].ifname
)
2968 cap_dev2
= os
.path
.join(params
['logdir'],
2969 prefix
+ ".%s.pcap" % dev
[2].ifname
)
2971 bssid
= apdev
[0]['bssid']
2972 params
= { 'ssid': 'open' }
2973 params
['proxy_arp'] = '1'
2974 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2975 hapd
.set("ap_isolate", "1")
2976 hapd
.set('bridge', 'ap-br0')
2981 # For now, do not report failures due to missing kernel support
2982 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2983 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2985 raise Exception("AP startup timed out")
2986 if "AP-ENABLED" not in ev
:
2987 raise Exception("AP startup failed")
2989 params2
= { 'ssid': 'another' }
2990 hapd2
= hostapd
.add_ap(apdev
[1]['ifname'], params2
, no_enable
=True)
2991 hapd2
.set('bridge', 'ap-br0')
2994 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2995 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2998 for chain
in [ 'FORWARD', 'OUTPUT' ]:
2999 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
3000 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
3002 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3003 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3004 '--ip6-icmp-type', 'neighbor-solicitation',
3005 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3006 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3007 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3008 '--ip6-icmp-type', 'neighbor-advertisement',
3009 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3010 subprocess
.call(['ebtables', '-A', chain
,
3011 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3012 '--ip6-icmp-type', 'router-solicitation',
3013 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3014 # Multicast Listener Report Message
3015 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
3016 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
3017 '--ip6-icmp-type', '143',
3018 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
3022 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
3023 '-w', cap_br
, '-s', '2000'],
3024 stderr
=open('/dev/null', 'w'))
3025 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
3026 '-w', cap_dev0
, '-s', '2000'],
3027 stderr
=open('/dev/null', 'w'))
3028 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
3029 '-w', cap_dev1
, '-s', '2000'],
3030 stderr
=open('/dev/null', 'w'))
3031 cmd
[3] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[2].ifname
,
3032 '-w', cap_dev2
, '-s', '2000'],
3033 stderr
=open('/dev/null', 'w'))
3035 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3036 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
3037 dev
[2].connect("another", key_mgmt
="NONE", scan_freq
="2412")
3040 brcmd
= subprocess
.Popen(['brctl', 'show'], stdout
=subprocess
.PIPE
)
3041 res
= brcmd
.stdout
.read()
3042 brcmd
.stdout
.close()
3043 logger
.info("Bridge setup: " + res
)
3045 brcmd
= subprocess
.Popen(['brctl', 'showstp', 'ap-br0'],
3046 stdout
=subprocess
.PIPE
)
3047 res
= brcmd
.stdout
.read()
3048 brcmd
.stdout
.close()
3049 logger
.info("Bridge showstp: " + res
)
3051 addr0
= dev
[0].p2p_interface_addr()
3052 addr1
= dev
[1].p2p_interface_addr()
3053 addr2
= dev
[2].p2p_interface_addr()
3055 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
3056 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
3059 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
3061 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
3062 # test frame without source link-layer address option
3063 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3065 # test frame with bogus option
3066 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3067 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
3068 # test frame with truncated source link-layer address option
3069 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3070 opt
="\x01\x01\x01\x02\x03\x04")
3071 # test frame with foreign source link-layer address option
3072 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
3073 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
3075 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
3077 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3078 # another copy for additional code coverage
3079 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
3081 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3082 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3083 yiaddr
="192.168.1.124", chaddr
=addr0
)
3084 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3085 raise Exception("DATA_TEST_FRAME failed")
3086 # Change address and verify unicast
3087 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
3088 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3089 yiaddr
="192.168.1.123", chaddr
=addr0
)
3090 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3091 raise Exception("DATA_TEST_FRAME failed")
3093 # Not-associated client MAC address
3094 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
3095 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3096 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
3097 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3098 raise Exception("DATA_TEST_FRAME failed")
3101 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3102 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3103 yiaddr
="0.0.0.0", chaddr
=addr1
)
3104 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3105 raise Exception("DATA_TEST_FRAME failed")
3108 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3109 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3110 yiaddr
="192.168.1.126", chaddr
=addr1
,
3111 subnet_mask
="0.0.0.0")
3112 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3113 raise Exception("DATA_TEST_FRAME failed")
3116 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3117 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3118 yiaddr
="192.168.1.127", chaddr
=addr1
,
3120 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3121 raise Exception("DATA_TEST_FRAME failed")
3124 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3125 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3126 yiaddr
="192.168.1.128", chaddr
=addr1
,
3128 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3129 raise Exception("DATA_TEST_FRAME failed")
3131 # Wrong IPv4 total length
3132 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3133 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3134 yiaddr
="192.168.1.129", chaddr
=addr1
,
3136 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3137 raise Exception("DATA_TEST_FRAME failed")
3140 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
3141 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
3142 yiaddr
="192.168.1.129", chaddr
=addr1
,
3144 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
3145 raise Exception("DATA_TEST_FRAME failed")
3147 macs
= get_bridge_macs("ap-br0")
3148 logger
.info("After connect (showmacs): " + str(macs
))
3150 matches
= get_permanent_neighbors("ap-br0")
3151 logger
.info("After connect: " + str(matches
))
3152 if len(matches
) != 4:
3153 raise Exception("Unexpected number of neighbor entries after connect")
3154 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3155 raise Exception("dev0 addr missing")
3156 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3157 raise Exception("dev1 addr(1) missing")
3158 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
3159 raise Exception("dev1 addr(2) missing")
3160 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
3161 raise Exception("dev0 IPv4 addr missing")
3163 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
3165 for target
in targets
:
3166 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
3168 for target
in targets
:
3169 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
3172 for target
in targets
:
3173 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
=target
)
3175 # ARP Probe from wireless STA
3176 send_arp(dev
[1], target_ip
="192.168.1.127")
3177 # ARP Announcement from wireless STA
3178 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
3179 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
3182 macs
= get_bridge_macs("ap-br0")
3183 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3185 matches
= get_permanent_neighbors("ap-br0")
3186 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3188 # ARP Request for the newly introduced IP address from wireless STA
3189 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3191 # ARP Request for the newly introduced IP address from bridge
3192 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3193 target_ip
="192.168.1.127")
3194 send_arp(dev
[2], sender_ip
="192.168.1.103", target_ip
="192.168.1.127")
3196 # ARP Probe from bridge
3197 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
3198 send_arp(dev
[2], target_ip
="192.168.1.131")
3199 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
3200 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3201 target_ip
="192.168.1.130")
3202 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3203 target_ip
="192.168.1.130", opcode
=2)
3204 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131")
3205 send_arp(dev
[2], sender_ip
="192.168.1.131", target_ip
="192.168.1.131",
3208 macs
= get_bridge_macs("ap-br0")
3209 logger
.info("After ARP Probe + Announcement (showmacs): " + str(macs
))
3211 matches
= get_permanent_neighbors("ap-br0")
3212 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3214 # ARP Request for the newly introduced IP address from wireless STA
3215 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
3216 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3217 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
3218 target_ip
="192.168.1.123", opcode
=2)
3220 # ARP Request for the newly introduced IP address from wireless STA
3221 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.131")
3222 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3223 send_arp(dev
[2], dst_ll
=addr0
, sender_ip
="192.168.1.131",
3224 target_ip
="192.168.1.123", opcode
=2)
3226 # ARP Request for the newly introduced IP address from bridge
3227 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3228 target_ip
="192.168.1.130")
3229 send_arp(dev
[2], sender_ip
="192.168.1.104", target_ip
="192.168.1.131")
3231 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
3232 send_arp(dev
[1], target_ip
="192.168.1.123")
3233 # ARP Probe from wireless STA (duplicate address; learned through ARP)
3234 send_arp(dev
[0], target_ip
="192.168.1.127")
3236 # Gratuitous ARP Reply for another STA's IP address
3237 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
3238 target_mac
=addr1
, target_ip
="192.168.1.127")
3239 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
3240 target_mac
=addr0
, target_ip
="192.168.1.123")
3241 # ARP Request to verify previous mapping
3242 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
3243 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3247 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
3249 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
3251 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
3252 ip_src
="aaaa:bbbb:ffff::2")
3254 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:ff00::2")
3256 send_ns(dev
[2], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:ff00::2")
3258 send_ns(dev
[2], target
="aaaa:bbbb:eeee::2", ip_src
="aaaa:bbbb:ff00::2")
3261 # Try to probe for an already assigned address
3262 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3264 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
3266 send_ns(dev
[2], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3270 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
3271 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
3272 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
3273 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
3274 send_na(dev
[2], target
="aaaa:bbbb:cccc:aeae::5",
3275 ip_src
="aaaa:bbbb:cccc:aeae::5", ip_dst
="ff02::1")
3278 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
3279 except Exception, e
:
3280 logger
.info("test_connectibity_iface failed: " + str(e
))
3281 raise HwsimSkip("Assume kernel did not have the required patches for proxyarp")
3282 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
3283 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
3285 dev
[0].request("DISCONNECT")
3286 dev
[1].request("DISCONNECT")
3288 for i
in range(len(cmd
)):
3290 macs
= get_bridge_macs("ap-br0")
3291 logger
.info("After disconnect (showmacs): " + str(macs
))
3292 matches
= get_permanent_neighbors("ap-br0")
3293 logger
.info("After disconnect: " + str(matches
))
3294 if len(matches
) > 0:
3295 raise Exception("Unexpected neighbor entries after disconnect")
3297 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'],
3298 stdout
=subprocess
.PIPE
)
3299 res
= cmd
.stdout
.read()
3301 logger
.info("ebtables results:\n" + res
)
3303 # Verify that expected ARP messages were seen and no unexpected
3304 # ARP messages were seen.
3306 arp_req
= tshark_get_arp(cap_dev0
, "arp.opcode == 1")
3307 arp_reply
= tshark_get_arp(cap_dev0
, "arp.opcode == 2")
3308 logger
.info("dev0 seen ARP requests:\n" + str(arp_req
))
3309 logger
.info("dev0 seen ARP replies:\n" + str(arp_reply
))
3311 if [ 'ff:ff:ff:ff:ff:ff', addr1
,
3312 addr1
, '192.168.1.100',
3313 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3314 raise Exception("dev0 saw ARP request from dev1")
3315 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3316 addr2
, '192.168.1.103',
3317 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3318 raise Exception("dev0 saw ARP request from dev2")
3319 # TODO: Uncomment once fixed in kernel
3320 #if [ 'ff:ff:ff:ff:ff:ff', bssid,
3321 # bssid, '192.168.1.101',
3322 # '00:00:00:00:00:00', '192.168.1.123' ] in arp_req:
3323 # raise Exception("dev0 saw ARP request from br")
3328 raise Exception("Unexpected foreign ARP request on dev0")
3330 arp_req
= tshark_get_arp(cap_dev1
, "arp.opcode == 1")
3331 arp_reply
= tshark_get_arp(cap_dev1
, "arp.opcode == 2")
3332 logger
.info("dev1 seen ARP requests:\n" + str(arp_req
))
3333 logger
.info("dev1 seen ARP replies:\n" + str(arp_reply
))
3335 if [ 'ff:ff:ff:ff:ff:ff', addr2
,
3336 addr2
, '192.168.1.103',
3337 '00:00:00:00:00:00', '192.168.1.123' ] in arp_req
:
3338 raise Exception("dev1 saw ARP request from dev2")
3339 if [addr1
, addr0
, addr0
, '192.168.1.123', addr1
, '192.168.1.100'] not in arp_reply
:
3340 raise Exception("dev1 did not get ARP response for 192.168.1.123")
3345 raise Exception("Unexpected foreign ARP request on dev1")
3347 arp_req
= tshark_get_arp(cap_dev2
, "arp.opcode == 1")
3348 arp_reply
= tshark_get_arp(cap_dev2
, "arp.opcode == 2")
3349 logger
.info("dev2 seen ARP requests:\n" + str(arp_req
))
3350 logger
.info("dev2 seen ARP replies:\n" + str(arp_reply
))
3353 addr0
, '192.168.1.123',
3354 addr2
, '192.168.1.103' ] not in arp_reply
:
3355 raise Exception("dev2 did not get ARP response for 192.168.1.123")
3357 arp_req
= tshark_get_arp(cap_br
, "arp.opcode == 1")
3358 arp_reply
= tshark_get_arp(cap_br
, "arp.opcode == 2")
3359 logger
.info("br seen ARP requests:\n" + str(arp_req
))
3360 logger
.info("br seen ARP replies:\n" + str(arp_reply
))
3362 # TODO: Uncomment once fixed in kernel
3364 # addr0, '192.168.1.123',
3365 # bssid, '192.168.1.101' ] not in arp_reply:
3366 # raise Exception("br did not get ARP response for 192.168.1.123")
3368 ns
= tshark_get_ns(cap_dev0
)
3369 logger
.info("dev0 seen NS: " + str(ns
))
3370 na
= tshark_get_na(cap_dev0
)
3371 logger
.info("dev0 seen NA: " + str(na
))
3373 # FIX: src mac addr is supposed to be addr1, not bssid
3374 if [ addr0
, bssid
, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:cccc::2',
3375 'aaaa:bbbb:dddd::2', addr1
] not in na
:
3376 raise Exception("dev0 did not get NA for aaaa:bbbb:dddd::2")
3381 raise Exception("Unexpected foreign NS on dev0: " + str(req
))
3383 ns
= tshark_get_ns(cap_dev1
)
3384 logger
.info("dev1 seen NS: " + str(ns
))
3385 na
= tshark_get_na(cap_dev1
)
3386 logger
.info("dev1 seen NA: " + str(na
))
3388 # FIX: src mac addr is supposed to be addr0, not bssid
3389 if [ addr1
, bssid
, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:dddd::2',
3390 'aaaa:bbbb:cccc::2', addr0
] not in na
:
3391 raise Exception("dev1 did not get NA for aaaa:bbbb:cccc::2")
3396 raise Exception("Unexpected foreign NS on dev1: " + str(req
))
3398 ns
= tshark_get_ns(cap_dev2
)
3399 logger
.info("dev2 seen NS: " + str(ns
))
3400 na
= tshark_get_na(cap_dev2
)
3401 logger
.info("dev2 seen NA: " + str(na
))
3403 # FIX: enable once kernel implementation for proxyarp IPv6 is fixed
3404 # FIX: src mac addr is supposed to be addr0/addr1, not bssid
3405 #if [ addr2, bssid, 'aaaa:bbbb:cccc::2', 'aaaa:bbbb:ff00::2',
3406 # 'aaaa:bbbb:cccc::2', addr0 ] not in na:
3407 # raise Exception("dev2 did not get NA for aaaa:bbbb:cccc::2")
3408 #if [ addr2, bssid, 'aaaa:bbbb:dddd::2', 'aaaa:bbbb:ff00::2',
3409 # 'aaaa:bbbb:dddd::2', addr1 ] not in na:
3410 # raise Exception("dev2 did not get NA for aaaa:bbbb:dddd::2")
3411 #if [ addr2, bssid, 'aaaa:bbbb:eeee::2', 'aaaa:bbbb:ff00::2',
3412 # 'aaaa:bbbb:eeee::2', addr1 ] not in na:
3413 # raise Exception("dev2 did not get NA for aaaa:bbbb:eeee::2")
3415 def test_proxyarp_open(dev
, apdev
, params
):
3416 """ProxyARP with open network"""
3418 _test_proxyarp_open(dev
, apdev
, params
)
3420 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3421 stderr
=open('/dev/null', 'w'))
3422 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3423 stderr
=open('/dev/null', 'w'))
3425 def test_proxyarp_open_ebtables(dev
, apdev
, params
):
3426 """ProxyARP with open network"""
3428 _test_proxyarp_open(dev
, apdev
, params
, ebtables
=True)
3431 subprocess
.call(['ebtables', '-F', 'FORWARD'])
3432 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
3435 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3436 stderr
=open('/dev/null', 'w'))
3437 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3438 stderr
=open('/dev/null', 'w'))