]>
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 wlantest
import Wlantest
22 from wpasupplicant
import WpaSupplicant
23 from test_ap_eap
import check_eap_capa
, check_domain_match_full
25 def hs20_ap_params(ssid
="test-hs20"):
26 params
= hostapd
.wpa2_params(ssid
=ssid
)
27 params
['wpa_key_mgmt'] = "WPA-EAP"
28 params
['ieee80211w'] = "1"
29 params
['ieee8021x'] = "1"
30 params
['auth_server_addr'] = "127.0.0.1"
31 params
['auth_server_port'] = "1812"
32 params
['auth_server_shared_secret'] = "radius"
33 params
['interworking'] = "1"
34 params
['access_network_type'] = "14"
35 params
['internet'] = "1"
39 params
['venue_group'] = "7"
40 params
['venue_type'] = "1"
41 params
['venue_name'] = [ "eng:Example venue", "fin:Esimerkkipaikka" ]
42 params
['roaming_consortium'] = [ "112233", "1020304050", "010203040506",
44 params
['domain_name'] = "example.com,another.example.com"
45 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
46 "0,another.example.com" ]
48 params
['hs20_wan_metrics'] = "01:8000:1000:80:240:3000"
49 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0" ]
50 params
['hs20_operating_class'] = "5173"
51 params
['anqp_3gpp_cell_net'] = "244,91"
54 def check_auto_select(dev
, bssid
):
55 dev
.scan_for_bss(bssid
, freq
="2412")
56 dev
.request("INTERWORKING_SELECT auto freq=2412")
57 ev
= dev
.wait_connected(timeout
=15)
59 raise Exception("Connected to incorrect network")
60 dev
.request("REMOVE_NETWORK all")
62 def interworking_select(dev
, bssid
, type=None, no_match
=False, freq
=None):
64 if bssid
and freq
and not no_match
:
65 dev
.scan_for_bss(bssid
, freq
=freq
)
66 freq_extra
= " freq=" + freq
if freq
else ""
67 dev
.request("INTERWORKING_SELECT" + freq_extra
)
68 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
71 raise Exception("Network selection timed out");
73 if "INTERWORKING-NO-MATCH" not in ev
:
74 raise Exception("Unexpected network match")
76 if "INTERWORKING-NO-MATCH" in ev
:
77 logger
.info("Matching network not found - try again")
79 dev
.request("INTERWORKING_SELECT" + freq_extra
)
80 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
83 raise Exception("Network selection timed out");
84 if "INTERWORKING-NO-MATCH" in ev
:
85 raise Exception("Matching network not found")
86 if bssid
and bssid
not in ev
:
87 raise Exception("Unexpected BSSID in match")
88 if type and "type=" + type not in ev
:
89 raise Exception("Network type not recognized correctly")
91 def check_sp_type(dev
, sp_type
):
92 type = dev
.get_status_field("sp_type")
94 raise Exception("sp_type not available")
96 raise Exception("sp_type did not indicate home network")
98 def hlr_auc_gw_available():
99 if not os
.path
.exists("/tmp/hlr_auc_gw.sock"):
100 raise HwsimSkip("No hlr_auc_gw socket available")
101 if not os
.path
.exists("../../hostapd/hlr_auc_gw"):
102 raise HwsimSkip("No hlr_auc_gw available")
104 def interworking_ext_sim_connect(dev
, bssid
, method
):
105 dev
.request("INTERWORKING_CONNECT " + bssid
)
106 interworking_ext_sim_auth(dev
, method
)
108 def interworking_ext_sim_auth(dev
, method
):
109 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
111 raise Exception("Network connected timed out")
112 if "(" + method
+ ")" not in ev
:
113 raise Exception("Unexpected EAP method selection")
115 ev
= dev
.wait_event(["CTRL-REQ-SIM"], timeout
=15)
117 raise Exception("Wait for external SIM processing request timed out")
119 if p
[1] != "GSM-AUTH":
120 raise Exception("Unexpected CTRL-REQ-SIM type")
121 id = p
[0].split('-')[3]
122 rand
= p
[2].split(' ')[0]
124 res
= subprocess
.check_output(["../../hostapd/hlr_auc_gw",
126 "auth_serv/hlr_auc_gw.milenage_db",
127 "GSM-AUTH-REQ 232010000000000 " + rand
])
128 if "GSM-AUTH-RESP" not in res
:
129 raise Exception("Unexpected hlr_auc_gw response")
130 resp
= res
.split(' ')[2].rstrip()
132 dev
.request("CTRL-RSP-SIM-" + id + ":GSM-AUTH:" + resp
)
133 dev
.wait_connected(timeout
=15)
135 def interworking_connect(dev
, bssid
, method
):
136 dev
.request("INTERWORKING_CONNECT " + bssid
)
137 interworking_auth(dev
, method
)
139 def interworking_auth(dev
, method
):
140 ev
= dev
.wait_event(["CTRL-EVENT-EAP-METHOD"], timeout
=15)
142 raise Exception("Network connected timed out")
143 if "(" + method
+ ")" not in ev
:
144 raise Exception("Unexpected EAP method selection")
146 dev
.wait_connected(timeout
=15)
148 def check_probe_resp(wt
, bssid_unexpected
, bssid_expected
):
150 count
= wt
.get_bss_counter("probe_response", bssid_unexpected
)
152 raise Exception("Unexpected Probe Response frame from AP")
155 count
= wt
.get_bss_counter("probe_response", bssid_expected
)
157 raise Exception("No Probe Response frame from AP")
159 def test_ap_anqp_sharing(dev
, apdev
):
160 """ANQP sharing within ESS and explicit unshare"""
161 bssid
= apdev
[0]['bssid']
162 params
= hs20_ap_params()
163 params
['hessid'] = bssid
164 hostapd
.add_ap(apdev
[0]['ifname'], params
)
166 bssid2
= apdev
[1]['bssid']
167 params
= hs20_ap_params()
168 params
['hessid'] = bssid
169 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]" ]
170 hostapd
.add_ap(apdev
[1]['ifname'], params
)
173 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
174 'password': "secret",
175 'domain': "example.com" })
176 logger
.info("Normal network selection with shared ANQP results")
177 dev
[0].scan_for_bss(bssid
, freq
="2412")
178 dev
[0].scan_for_bss(bssid2
, freq
="2412")
179 interworking_select(dev
[0], None, "home", freq
="2412")
180 dev
[0].dump_monitor()
182 res1
= dev
[0].get_bss(bssid
)
183 res2
= dev
[0].get_bss(bssid2
)
184 if res1
['anqp_nai_realm'] != res2
['anqp_nai_realm']:
185 raise Exception("ANQP results were not shared between BSSes")
187 logger
.info("Explicit ANQP request to unshare ANQP results")
188 dev
[0].request("ANQP_GET " + bssid
+ " 263")
189 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
191 raise Exception("ANQP operation timed out")
193 dev
[0].request("ANQP_GET " + bssid2
+ " 263")
194 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
196 raise Exception("ANQP operation timed out")
198 res1
= dev
[0].get_bss(bssid
)
199 res2
= dev
[0].get_bss(bssid2
)
200 if res1
['anqp_nai_realm'] == res2
['anqp_nai_realm']:
201 raise Exception("ANQP results were not unshared")
203 def test_ap_nai_home_realm_query(dev
, apdev
):
204 """NAI Home Realm Query"""
205 bssid
= apdev
[0]['bssid']
206 params
= hs20_ap_params()
207 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
208 "0,another.example.org" ]
209 hostapd
.add_ap(apdev
[0]['ifname'], params
)
211 dev
[0].scan(freq
="2412")
212 dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " realm=example.com")
213 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
215 raise Exception("ANQP operation timed out")
216 nai1
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
217 dev
[0].dump_monitor()
219 dev
[0].request("ANQP_GET " + bssid
+ " 263")
220 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
222 raise Exception("ANQP operation timed out")
223 nai2
= dev
[0].get_bss(bssid
)['anqp_nai_realm']
225 if len(nai1
) >= len(nai2
):
226 raise Exception("Unexpected NAI Realm list response lengths")
227 if "example.com".encode('hex') not in nai1
:
228 raise Exception("Home realm not reported")
229 if "example.org".encode('hex') in nai1
:
230 raise Exception("Non-home realm reported")
231 if "example.com".encode('hex') not in nai2
:
232 raise Exception("Home realm not reported in wildcard query")
233 if "example.org".encode('hex') not in nai2
:
234 raise Exception("Non-home realm not reported in wildcard query ")
237 "00:11:22:33:44:55 123",
238 "00:11:22:33:44:55 qq" ]
240 if "FAIL" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + cmd
):
241 raise Exception("Invalid HS20_GET_NAI_HOME_REALM_LIST accepted: " + cmd
)
243 dev
[0].dump_monitor()
244 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
245 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
246 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=10)
248 raise Exception("ANQP operation timed out")
249 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=0.1)
251 raise Exception("Unexpected ANQP response: " + ev
)
253 dev
[0].dump_monitor()
254 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
+ " 01000b6578616d706c652e636f6d"):
255 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
256 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
258 raise Exception("No ANQP response")
259 if "NAI Realm list" not in ev
:
260 raise Exception("Missing NAI Realm list: " + ev
)
262 dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
263 'password': "secret",
264 'domain': "example.com" })
265 dev
[0].dump_monitor()
266 if "OK" not in dev
[0].request("HS20_GET_NAI_HOME_REALM_LIST " + bssid
):
267 raise Exception("HS20_GET_NAI_HOME_REALM_LIST failed")
268 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=10)
270 raise Exception("No ANQP response")
271 if "NAI Realm list" not in ev
:
272 raise Exception("Missing NAI Realm list: " + ev
)
274 def test_ap_interworking_scan_filtering(dev
, apdev
):
275 """Interworking scan filtering with HESSID and access network type"""
277 _test_ap_interworking_scan_filtering(dev
, apdev
)
279 dev
[0].request("SET hessid 00:00:00:00:00:00")
280 dev
[0].request("SET access_network_type 15")
282 def _test_ap_interworking_scan_filtering(dev
, apdev
):
283 bssid
= apdev
[0]['bssid']
284 params
= hs20_ap_params()
285 ssid
= "test-hs20-ap1"
286 params
['ssid'] = ssid
287 params
['hessid'] = bssid
288 hostapd
.add_ap(apdev
[0]['ifname'], params
)
290 bssid2
= apdev
[1]['bssid']
291 params
= hs20_ap_params()
292 ssid2
= "test-hs20-ap2"
293 params
['ssid'] = ssid2
294 params
['hessid'] = bssid2
295 params
['access_network_type'] = "1"
296 del params
['venue_group']
297 del params
['venue_type']
298 hostapd
.add_ap(apdev
[1]['ifname'], params
)
305 logger
.info("Check probe request filtering based on HESSID")
307 dev
[0].request("SET hessid " + bssid2
)
308 dev
[0].scan(freq
="2412")
310 check_probe_resp(wt
, bssid
, bssid2
)
312 logger
.info("Check probe request filtering based on access network type")
314 wt
.clear_bss_counters(bssid
)
315 wt
.clear_bss_counters(bssid2
)
316 dev
[0].request("SET hessid 00:00:00:00:00:00")
317 dev
[0].request("SET access_network_type 14")
318 dev
[0].scan(freq
="2412")
320 check_probe_resp(wt
, bssid2
, bssid
)
322 wt
.clear_bss_counters(bssid
)
323 wt
.clear_bss_counters(bssid2
)
324 dev
[0].request("SET hessid 00:00:00:00:00:00")
325 dev
[0].request("SET access_network_type 1")
326 dev
[0].scan(freq
="2412")
328 check_probe_resp(wt
, bssid
, bssid2
)
330 logger
.info("Check probe request filtering based on HESSID and ANT")
332 wt
.clear_bss_counters(bssid
)
333 wt
.clear_bss_counters(bssid2
)
334 dev
[0].request("SET hessid " + bssid
)
335 dev
[0].request("SET access_network_type 14")
336 dev
[0].scan(freq
="2412")
338 check_probe_resp(wt
, bssid2
, bssid
)
340 wt
.clear_bss_counters(bssid
)
341 wt
.clear_bss_counters(bssid2
)
342 dev
[0].request("SET hessid " + bssid2
)
343 dev
[0].request("SET access_network_type 14")
344 dev
[0].scan(freq
="2412")
346 check_probe_resp(wt
, bssid
, None)
347 check_probe_resp(wt
, bssid2
, None)
349 wt
.clear_bss_counters(bssid
)
350 wt
.clear_bss_counters(bssid2
)
351 dev
[0].request("SET hessid " + bssid
)
352 dev
[0].request("SET access_network_type 1")
353 dev
[0].scan(freq
="2412")
355 check_probe_resp(wt
, bssid
, None)
356 check_probe_resp(wt
, bssid2
, None)
358 def test_ap_hs20_select(dev
, apdev
):
359 """Hotspot 2.0 network selection"""
360 bssid
= apdev
[0]['bssid']
361 params
= hs20_ap_params()
362 params
['hessid'] = bssid
363 hostapd
.add_ap(apdev
[0]['ifname'], params
)
366 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
367 'password': "secret",
368 'domain': "example.com" })
369 interworking_select(dev
[0], bssid
, "home")
371 dev
[0].remove_cred(id)
372 id = dev
[0].add_cred_values({ 'realm': "example.com", 'username': "test",
373 'password': "secret",
374 'domain': "no.match.example.com" })
375 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
377 dev
[0].set_cred_quoted(id, "realm", "no.match.example.com");
378 interworking_select(dev
[0], bssid
, no_match
=True, freq
="2412")
380 res
= dev
[0].request("SCAN_RESULTS")
381 if "[HS20]" not in res
:
382 raise Exception("HS20 flag missing from scan results: " + res
)
384 bssid2
= apdev
[1]['bssid']
385 params
= hs20_ap_params()
386 params
['nai_realm'] = [ "0,example.org,21" ]
387 params
['hessid'] = bssid2
388 params
['domain_name'] = "example.org"
389 hostapd
.add_ap(apdev
[1]['ifname'], params
)
390 dev
[0].remove_cred(id)
391 id = dev
[0].add_cred_values({ 'realm': "example.org", 'username': "test",
392 'password': "secret",
393 'domain': "example.org" })
394 interworking_select(dev
[0], bssid2
, "home", freq
="2412")
396 def hs20_simulated_sim(dev
, ap
, method
):
398 params
= hs20_ap_params()
399 params
['hessid'] = bssid
400 params
['anqp_3gpp_cell_net'] = "555,444"
401 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
402 hostapd
.add_ap(ap
['ifname'], params
)
405 dev
.add_cred_values({ 'imsi': "555444-333222111", 'eap': method
,
406 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123"})
407 interworking_select(dev
, "home", freq
="2412")
408 interworking_connect(dev
, bssid
, method
)
409 check_sp_type(dev
, "home")
411 def test_ap_hs20_sim(dev
, apdev
):
412 """Hotspot 2.0 with simulated SIM and EAP-SIM"""
413 hlr_auc_gw_available()
414 hs20_simulated_sim(dev
[0], apdev
[0], "SIM")
415 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
416 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
418 raise Exception("Timeout on already-connected event")
420 def test_ap_hs20_aka(dev
, apdev
):
421 """Hotspot 2.0 with simulated USIM and EAP-AKA"""
422 hlr_auc_gw_available()
423 hs20_simulated_sim(dev
[0], apdev
[0], "AKA")
425 def test_ap_hs20_aka_prime(dev
, apdev
):
426 """Hotspot 2.0 with simulated USIM and EAP-AKA'"""
427 hlr_auc_gw_available()
428 hs20_simulated_sim(dev
[0], apdev
[0], "AKA'")
430 def test_ap_hs20_ext_sim(dev
, apdev
):
431 """Hotspot 2.0 with external SIM processing"""
432 hlr_auc_gw_available()
433 bssid
= apdev
[0]['bssid']
434 params
= hs20_ap_params()
435 params
['hessid'] = bssid
436 params
['anqp_3gpp_cell_net'] = "232,01"
437 params
['domain_name'] = "wlan.mnc001.mcc232.3gppnetwork.org"
438 hostapd
.add_ap(apdev
[0]['ifname'], params
)
442 dev
[0].request("SET external_sim 1")
443 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
444 interworking_select(dev
[0], "home", freq
="2412")
445 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
446 check_sp_type(dev
[0], "home")
448 dev
[0].request("SET external_sim 0")
450 def test_ap_hs20_ext_sim_roaming(dev
, apdev
):
451 """Hotspot 2.0 with external SIM processing in roaming network"""
452 hlr_auc_gw_available()
453 bssid
= apdev
[0]['bssid']
454 params
= hs20_ap_params()
455 params
['hessid'] = bssid
456 params
['anqp_3gpp_cell_net'] = "244,91;310,026;232,01;234,56"
457 params
['domain_name'] = "wlan.mnc091.mcc244.3gppnetwork.org"
458 hostapd
.add_ap(apdev
[0]['ifname'], params
)
462 dev
[0].request("SET external_sim 1")
463 dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM" })
464 interworking_select(dev
[0], "roaming", freq
="2412")
465 interworking_ext_sim_connect(dev
[0], bssid
, "SIM")
466 check_sp_type(dev
[0], "roaming")
468 dev
[0].request("SET external_sim 0")
470 def test_ap_hs20_username(dev
, apdev
):
471 """Hotspot 2.0 connection in username/password credential"""
472 bssid
= apdev
[0]['bssid']
473 params
= hs20_ap_params()
474 params
['hessid'] = bssid
475 params
['disable_dgaf'] = '1'
476 hostapd
.add_ap(apdev
[0]['ifname'], params
)
479 id = dev
[0].add_cred_values({ 'realm': "example.com",
480 'username': "hs20-test",
481 'password': "password",
482 'ca_cert': "auth_serv/ca.pem",
483 'domain': "example.com",
484 'update_identifier': "1234" })
485 interworking_select(dev
[0], bssid
, "home", freq
="2412")
486 interworking_connect(dev
[0], bssid
, "TTLS")
487 check_sp_type(dev
[0], "home")
488 status
= dev
[0].get_status()
489 if status
['pairwise_cipher'] != "CCMP":
490 raise Exception("Unexpected pairwise cipher")
491 if status
['hs20'] != "2":
492 raise Exception("Unexpected HS 2.0 support indication")
494 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
495 identity
="hs20-test", password
="password",
496 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
499 def test_ap_hs20_connect_api(dev
, apdev
):
500 """Hotspot 2.0 connection with connect API"""
501 bssid
= apdev
[0]['bssid']
502 params
= hs20_ap_params()
503 params
['hessid'] = bssid
504 params
['disable_dgaf'] = '1'
505 hostapd
.add_ap(apdev
[0]['ifname'], params
)
507 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
508 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
510 wpas
.flush_scan_cache()
511 id = wpas
.add_cred_values({ 'realm': "example.com",
512 'username': "hs20-test",
513 'password': "password",
514 'ca_cert': "auth_serv/ca.pem",
515 'domain': "example.com",
516 'update_identifier': "1234" })
517 interworking_select(wpas
, bssid
, "home", freq
="2412")
518 interworking_connect(wpas
, bssid
, "TTLS")
519 check_sp_type(wpas
, "home")
520 status
= wpas
.get_status()
521 if status
['pairwise_cipher'] != "CCMP":
522 raise Exception("Unexpected pairwise cipher")
523 if status
['hs20'] != "2":
524 raise Exception("Unexpected HS 2.0 support indication")
526 def test_ap_hs20_auto_interworking(dev
, apdev
):
527 """Hotspot 2.0 connection with auto_interworking=1"""
528 bssid
= apdev
[0]['bssid']
529 params
= hs20_ap_params()
530 params
['hessid'] = bssid
531 params
['disable_dgaf'] = '1'
532 hostapd
.add_ap(apdev
[0]['ifname'], params
)
534 dev
[0].hs20_enable(auto_interworking
=True)
535 id = dev
[0].add_cred_values({ 'realm': "example.com",
536 'username': "hs20-test",
537 'password': "password",
538 'ca_cert': "auth_serv/ca.pem",
539 'domain': "example.com",
540 'update_identifier': "1234" })
541 dev
[0].request("REASSOCIATE")
542 dev
[0].wait_connected(timeout
=15)
543 check_sp_type(dev
[0], "home")
544 status
= dev
[0].get_status()
545 if status
['pairwise_cipher'] != "CCMP":
546 raise Exception("Unexpected pairwise cipher")
547 if status
['hs20'] != "2":
548 raise Exception("Unexpected HS 2.0 support indication")
550 def test_ap_hs20_auto_interworking_no_cred_match(dev
, apdev
):
551 """Hotspot 2.0 connection with auto_interworking=1 but no cred match"""
552 bssid
= apdev
[0]['bssid']
553 params
= { "ssid": "test" }
554 hostapd
.add_ap(apdev
[0]['ifname'], params
)
556 dev
[0].hs20_enable(auto_interworking
=True)
557 dev
[0].add_cred_values({ 'realm': "example.com",
558 'username': "hs20-test",
559 'password': "password",
560 'ca_cert': "auth_serv/ca.pem",
561 'domain': "example.com" })
563 id = dev
[0].connect("test", psk
="12345678", only_add_network
=True)
564 dev
[0].request("ENABLE_NETWORK %s" % id)
565 logger
.info("Verify that scanning continues when there is partial network block match")
566 for i
in range(0, 2):
567 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
569 raise Exception("Scan timed out")
570 logger
.info("Scan completed")
572 def eap_test(dev
, ap
, eap_params
, method
, user
):
574 params
= hs20_ap_params()
575 params
['nai_realm'] = [ "0,example.com," + eap_params
]
576 hostapd
.add_ap(ap
['ifname'], params
)
579 dev
.add_cred_values({ 'realm': "example.com",
580 'ca_cert': "auth_serv/ca.pem",
582 'password': "password" })
583 interworking_select(dev
, bssid
, freq
="2412")
584 interworking_connect(dev
, bssid
, method
)
586 def test_ap_hs20_eap_unknown(dev
, apdev
):
587 """Hotspot 2.0 connection with unknown EAP method"""
588 bssid
= apdev
[0]['bssid']
589 params
= hs20_ap_params()
590 params
['nai_realm'] = "0,example.com,99"
591 hostapd
.add_ap(apdev
[0]['ifname'], params
)
594 dev
[0].add_cred_values(default_cred())
595 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
597 def test_ap_hs20_eap_peap_mschapv2(dev
, apdev
):
598 """Hotspot 2.0 connection with PEAP/MSCHAPV2"""
599 eap_test(dev
[0], apdev
[0], "25[3:26]", "PEAP", "user")
601 def test_ap_hs20_eap_peap_default(dev
, apdev
):
602 """Hotspot 2.0 connection with PEAP/MSCHAPV2 (as default)"""
603 eap_test(dev
[0], apdev
[0], "25", "PEAP", "user")
605 def test_ap_hs20_eap_peap_gtc(dev
, apdev
):
606 """Hotspot 2.0 connection with PEAP/GTC"""
607 eap_test(dev
[0], apdev
[0], "25[3:6]", "PEAP", "user")
609 def test_ap_hs20_eap_peap_unknown(dev
, apdev
):
610 """Hotspot 2.0 connection with PEAP/unknown"""
611 bssid
= apdev
[0]['bssid']
612 params
= hs20_ap_params()
613 params
['nai_realm'] = "0,example.com,25[3:99]"
614 hostapd
.add_ap(apdev
[0]['ifname'], params
)
617 dev
[0].add_cred_values(default_cred())
618 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
620 def test_ap_hs20_eap_ttls_chap(dev
, apdev
):
621 """Hotspot 2.0 connection with TTLS/CHAP"""
622 eap_test(dev
[0], apdev
[0], "21[2:2]", "TTLS", "chap user")
624 def test_ap_hs20_eap_ttls_mschap(dev
, apdev
):
625 """Hotspot 2.0 connection with TTLS/MSCHAP"""
626 eap_test(dev
[0], apdev
[0], "21[2:3]", "TTLS", "mschap user")
628 def test_ap_hs20_eap_ttls_eap_mschapv2(dev
, apdev
):
629 """Hotspot 2.0 connection with TTLS/EAP-MSCHAPv2"""
630 eap_test(dev
[0], apdev
[0], "21[3:26][6:7][99:99]", "TTLS", "user")
632 def test_ap_hs20_eap_ttls_eap_unknown(dev
, apdev
):
633 """Hotspot 2.0 connection with TTLS/EAP-unknown"""
634 bssid
= apdev
[0]['bssid']
635 params
= hs20_ap_params()
636 params
['nai_realm'] = "0,example.com,21[3:99]"
637 hostapd
.add_ap(apdev
[0]['ifname'], params
)
640 dev
[0].add_cred_values(default_cred())
641 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
643 def test_ap_hs20_eap_ttls_eap_unsupported(dev
, apdev
):
644 """Hotspot 2.0 connection with TTLS/EAP-OTP(unsupported)"""
645 bssid
= apdev
[0]['bssid']
646 params
= hs20_ap_params()
647 params
['nai_realm'] = "0,example.com,21[3:5]"
648 hostapd
.add_ap(apdev
[0]['ifname'], params
)
651 dev
[0].add_cred_values(default_cred())
652 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
654 def test_ap_hs20_eap_ttls_unknown(dev
, apdev
):
655 """Hotspot 2.0 connection with TTLS/unknown"""
656 bssid
= apdev
[0]['bssid']
657 params
= hs20_ap_params()
658 params
['nai_realm'] = "0,example.com,21[2:5]"
659 hostapd
.add_ap(apdev
[0]['ifname'], params
)
662 dev
[0].add_cred_values(default_cred())
663 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
665 def test_ap_hs20_eap_fast_mschapv2(dev
, apdev
):
666 """Hotspot 2.0 connection with FAST/EAP-MSCHAPV2"""
667 check_eap_capa(dev
[0], "FAST")
668 eap_test(dev
[0], apdev
[0], "43[3:26]", "FAST", "user")
670 def test_ap_hs20_eap_fast_gtc(dev
, apdev
):
671 """Hotspot 2.0 connection with FAST/EAP-GTC"""
672 check_eap_capa(dev
[0], "FAST")
673 eap_test(dev
[0], apdev
[0], "43[3:6]", "FAST", "user")
675 def test_ap_hs20_eap_tls(dev
, apdev
):
676 """Hotspot 2.0 connection with EAP-TLS"""
677 bssid
= apdev
[0]['bssid']
678 params
= hs20_ap_params()
679 params
['nai_realm'] = [ "0,example.com,13[5:6]" ]
680 hostapd
.add_ap(apdev
[0]['ifname'], params
)
683 dev
[0].add_cred_values({ 'realm': "example.com",
684 'username': "certificate-user",
685 'ca_cert': "auth_serv/ca.pem",
686 'client_cert': "auth_serv/user.pem",
687 'private_key': "auth_serv/user.key"})
688 interworking_select(dev
[0], bssid
, freq
="2412")
689 interworking_connect(dev
[0], bssid
, "TLS")
691 def test_ap_hs20_eap_cert_unknown(dev
, apdev
):
692 """Hotspot 2.0 connection with certificate, but unknown EAP method"""
693 bssid
= apdev
[0]['bssid']
694 params
= hs20_ap_params()
695 params
['nai_realm'] = [ "0,example.com,99[5:6]" ]
696 hostapd
.add_ap(apdev
[0]['ifname'], params
)
699 dev
[0].add_cred_values({ 'realm': "example.com",
700 'username': "certificate-user",
701 'ca_cert': "auth_serv/ca.pem",
702 'client_cert': "auth_serv/user.pem",
703 'private_key': "auth_serv/user.key"})
704 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
706 def test_ap_hs20_eap_cert_unsupported(dev
, apdev
):
707 """Hotspot 2.0 connection with certificate, but unsupported TTLS"""
708 bssid
= apdev
[0]['bssid']
709 params
= hs20_ap_params()
710 params
['nai_realm'] = [ "0,example.com,21[5:6]" ]
711 hostapd
.add_ap(apdev
[0]['ifname'], params
)
714 dev
[0].add_cred_values({ 'realm': "example.com",
715 'username': "certificate-user",
716 'ca_cert': "auth_serv/ca.pem",
717 'client_cert': "auth_serv/user.pem",
718 'private_key': "auth_serv/user.key"})
719 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
721 def test_ap_hs20_eap_invalid_cred(dev
, apdev
):
722 """Hotspot 2.0 connection with invalid cred configuration"""
723 bssid
= apdev
[0]['bssid']
724 params
= hs20_ap_params()
725 hostapd
.add_ap(apdev
[0]['ifname'], params
)
728 dev
[0].add_cred_values({ 'realm': "example.com",
729 'username': "certificate-user",
730 'client_cert': "auth_serv/user.pem" })
731 interworking_select(dev
[0], None, no_match
=True, freq
="2412")
733 def test_ap_hs20_nai_realms(dev
, apdev
):
734 """Hotspot 2.0 connection and multiple NAI realms and TTLS/PAP"""
735 bssid
= apdev
[0]['bssid']
736 params
= hs20_ap_params()
737 params
['hessid'] = bssid
738 params
['nai_realm'] = [ "0,no.match.here;example.com;no.match.here.either,21[2:1][5:7]" ]
739 hostapd
.add_ap(apdev
[0]['ifname'], params
)
742 id = dev
[0].add_cred_values({ 'realm': "example.com",
743 'ca_cert': "auth_serv/ca.pem",
744 'username': "pap user",
745 'password': "password",
746 'domain': "example.com" })
747 interworking_select(dev
[0], bssid
, "home", freq
="2412")
748 interworking_connect(dev
[0], bssid
, "TTLS")
749 check_sp_type(dev
[0], "home")
751 def test_ap_hs20_roaming_consortium(dev
, apdev
):
752 """Hotspot 2.0 connection based on roaming consortium match"""
753 bssid
= apdev
[0]['bssid']
754 params
= hs20_ap_params()
755 params
['hessid'] = bssid
756 hostapd
.add_ap(apdev
[0]['ifname'], params
)
759 for consortium
in [ "112233", "1020304050", "010203040506", "fedcba" ]:
760 id = dev
[0].add_cred_values({ 'username': "user",
761 'password': "password",
762 'domain': "example.com",
763 'ca_cert': "auth_serv/ca.pem",
764 'roaming_consortium': consortium
,
766 interworking_select(dev
[0], bssid
, "home", freq
="2412")
767 interworking_connect(dev
[0], bssid
, "PEAP")
768 check_sp_type(dev
[0], "home")
769 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
770 ev
= dev
[0].wait_event(["INTERWORKING-ALREADY-CONNECTED"], timeout
=15)
772 raise Exception("Timeout on already-connected event")
773 dev
[0].remove_cred(id)
775 def test_ap_hs20_username_roaming(dev
, apdev
):
776 """Hotspot 2.0 connection in username/password credential (roaming)"""
777 bssid
= apdev
[0]['bssid']
778 params
= hs20_ap_params()
779 params
['nai_realm'] = [ "0,example.com,13[5:6],21[2:4][5:7]",
780 "0,roaming.example.com,21[2:4][5:7]",
781 "0,another.example.com" ]
782 params
['domain_name'] = "another.example.com"
783 params
['hessid'] = bssid
784 hostapd
.add_ap(apdev
[0]['ifname'], params
)
787 id = dev
[0].add_cred_values({ 'realm': "roaming.example.com",
788 'username': "hs20-test",
789 'password': "password",
790 'ca_cert': "auth_serv/ca.pem",
791 'domain': "example.com" })
792 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
793 interworking_connect(dev
[0], bssid
, "TTLS")
794 check_sp_type(dev
[0], "roaming")
796 def test_ap_hs20_username_unknown(dev
, apdev
):
797 """Hotspot 2.0 connection in username/password credential (no domain in cred)"""
798 bssid
= apdev
[0]['bssid']
799 params
= hs20_ap_params()
800 params
['hessid'] = bssid
801 hostapd
.add_ap(apdev
[0]['ifname'], params
)
804 id = dev
[0].add_cred_values({ 'realm': "example.com",
805 'ca_cert': "auth_serv/ca.pem",
806 'username': "hs20-test",
807 'password': "password" })
808 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
809 interworking_connect(dev
[0], bssid
, "TTLS")
810 check_sp_type(dev
[0], "unknown")
812 def test_ap_hs20_username_unknown2(dev
, apdev
):
813 """Hotspot 2.0 connection in username/password credential (no domain advertized)"""
814 bssid
= apdev
[0]['bssid']
815 params
= hs20_ap_params()
816 params
['hessid'] = bssid
817 del params
['domain_name']
818 hostapd
.add_ap(apdev
[0]['ifname'], params
)
821 id = dev
[0].add_cred_values({ 'realm': "example.com",
822 'ca_cert': "auth_serv/ca.pem",
823 'username': "hs20-test",
824 'password': "password",
825 'domain': "example.com" })
826 interworking_select(dev
[0], bssid
, "unknown", freq
="2412")
827 interworking_connect(dev
[0], bssid
, "TTLS")
828 check_sp_type(dev
[0], "unknown")
830 def test_ap_hs20_gas_while_associated(dev
, apdev
):
831 """Hotspot 2.0 connection with GAS query while associated"""
832 bssid
= apdev
[0]['bssid']
833 params
= hs20_ap_params()
834 params
['hessid'] = bssid
835 hostapd
.add_ap(apdev
[0]['ifname'], params
)
838 id = dev
[0].add_cred_values({ 'realm': "example.com",
839 'ca_cert': "auth_serv/ca.pem",
840 'username': "hs20-test",
841 'password': "password",
842 'domain': "example.com" })
843 interworking_select(dev
[0], bssid
, "home", freq
="2412")
844 interworking_connect(dev
[0], bssid
, "TTLS")
846 logger
.info("Verifying GAS query while associated")
847 dev
[0].request("FETCH_ANQP")
848 for i
in range(0, 6):
849 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
851 raise Exception("Operation timed out")
853 def test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
854 """Hotspot 2.0 connection with GAS query while associated and using PMF"""
856 _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
)
858 dev
[0].request("SET pmf 0")
860 def _test_ap_hs20_gas_while_associated_with_pmf(dev
, apdev
):
861 bssid
= apdev
[0]['bssid']
862 params
= hs20_ap_params()
863 params
['hessid'] = bssid
864 hostapd
.add_ap(apdev
[0]['ifname'], params
)
866 bssid2
= apdev
[1]['bssid']
867 params
= hs20_ap_params()
868 params
['hessid'] = bssid2
869 params
['nai_realm'] = [ "0,no-match.example.org,13[5:6],21[2:4][5:7]" ]
870 hostapd
.add_ap(apdev
[1]['ifname'], params
)
873 dev
[0].request("SET pmf 2")
874 id = dev
[0].add_cred_values({ 'realm': "example.com",
875 'ca_cert': "auth_serv/ca.pem",
876 'username': "hs20-test",
877 'password': "password",
878 'domain': "example.com" })
879 interworking_select(dev
[0], bssid
, "home", freq
="2412")
880 interworking_connect(dev
[0], bssid
, "TTLS")
882 logger
.info("Verifying GAS query while associated")
883 dev
[0].request("FETCH_ANQP")
884 for i
in range(0, 2 * 6):
885 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
887 raise Exception("Operation timed out")
889 def test_ap_hs20_gas_frag_while_associated(dev
, apdev
):
890 """Hotspot 2.0 connection with fragmented GAS query while associated"""
891 bssid
= apdev
[0]['bssid']
892 params
= hs20_ap_params()
893 params
['hessid'] = bssid
894 hostapd
.add_ap(apdev
[0]['ifname'], params
)
895 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
896 hapd
.set("gas_frag_limit", "50")
899 id = dev
[0].add_cred_values({ 'realm': "example.com",
900 'ca_cert': "auth_serv/ca.pem",
901 'username': "hs20-test",
902 'password': "password",
903 'domain': "example.com" })
904 interworking_select(dev
[0], bssid
, "home", freq
="2412")
905 interworking_connect(dev
[0], bssid
, "TTLS")
907 logger
.info("Verifying GAS query while associated")
908 dev
[0].request("FETCH_ANQP")
909 for i
in range(0, 6):
910 ev
= dev
[0].wait_event(["RX-ANQP"], timeout
=5)
912 raise Exception("Operation timed out")
914 def test_ap_hs20_multiple_connects(dev
, apdev
):
915 """Hotspot 2.0 connection through multiple network selections"""
916 bssid
= apdev
[0]['bssid']
917 params
= hs20_ap_params()
918 params
['hessid'] = bssid
919 hostapd
.add_ap(apdev
[0]['ifname'], params
)
922 values
= { 'realm': "example.com",
923 'ca_cert': "auth_serv/ca.pem",
924 'username': "hs20-test",
925 'password': "password",
926 'domain': "example.com" }
927 id = dev
[0].add_cred_values(values
)
929 dev
[0].scan_for_bss(bssid
, freq
="2412")
931 for i
in range(0, 3):
932 logger
.info("Starting Interworking network selection")
933 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
935 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
936 "INTERWORKING-ALREADY-CONNECTED",
937 "CTRL-EVENT-CONNECTED"], timeout
=15)
939 raise Exception("Connection timed out")
940 if "INTERWORKING-NO-MATCH" in ev
:
941 raise Exception("Matching AP not found")
942 if "CTRL-EVENT-CONNECTED" in ev
:
944 if i
== 2 and "INTERWORKING-ALREADY-CONNECTED" in ev
:
947 dev
[0].request("DISCONNECT")
948 dev
[0].dump_monitor()
950 networks
= dev
[0].list_networks()
951 if len(networks
) > 1:
952 raise Exception("Duplicated network block detected")
954 def test_ap_hs20_disallow_aps(dev
, apdev
):
955 """Hotspot 2.0 connection and disallow_aps"""
956 bssid
= apdev
[0]['bssid']
957 params
= hs20_ap_params()
958 params
['hessid'] = bssid
959 hostapd
.add_ap(apdev
[0]['ifname'], params
)
962 values
= { 'realm': "example.com",
963 'ca_cert': "auth_serv/ca.pem",
964 'username': "hs20-test",
965 'password': "password",
966 'domain': "example.com" }
967 id = dev
[0].add_cred_values(values
)
969 dev
[0].scan_for_bss(bssid
, freq
="2412")
971 logger
.info("Verify disallow_aps bssid")
972 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
973 dev
[0].request("INTERWORKING_SELECT auto")
974 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
976 raise Exception("Network selection timed out")
977 dev
[0].dump_monitor()
979 logger
.info("Verify disallow_aps ssid")
980 dev
[0].request("SET disallow_aps ssid 746573742d68733230")
981 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
982 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH"], timeout
=15)
984 raise Exception("Network selection timed out")
985 dev
[0].dump_monitor()
987 logger
.info("Verify disallow_aps clear")
988 dev
[0].request("SET disallow_aps ")
989 interworking_select(dev
[0], bssid
, "home", freq
="2412")
991 dev
[0].request("SET disallow_aps bssid " + bssid
.translate(None, ':'))
992 ret
= dev
[0].request("INTERWORKING_CONNECT " + bssid
)
993 if "FAIL" not in ret
:
994 raise Exception("INTERWORKING_CONNECT to disallowed BSS not rejected")
996 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT foo"):
997 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
998 if "FAIL" not in dev
[0].request("INTERWORKING_CONNECT 00:11:22:33:44:55"):
999 raise Exception("Invalid INTERWORKING_CONNECT not rejected")
1001 def policy_test(dev
, ap
, values
, only_one
=True):
1004 logger
.info("Verify network selection to AP " + ap
['ifname'])
1006 dev
.scan_for_bss(bssid
, freq
="2412")
1008 logger
.info("Verify network selection")
1011 id = dev
.add_cred_values(values
)
1012 dev
.request("INTERWORKING_SELECT auto freq=2412")
1015 ev
= dev
.wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH",
1016 "INTERWORKING-BLACKLISTED",
1017 "INTERWORKING-SELECTED"], timeout
=15)
1019 raise Exception("Network selection timed out")
1021 if "INTERWORKING-NO-MATCH" in ev
:
1022 raise Exception("Matching AP not found")
1023 if bssid
and only_one
and "INTERWORKING-AP" in ev
and bssid
not in ev
:
1024 raise Exception("Unexpected AP claimed acceptable")
1025 if "INTERWORKING-SELECTED" in ev
:
1026 if bssid
and bssid
not in ev
:
1027 raise Exception("Selected incorrect BSS")
1030 ev
= dev
.wait_connected(timeout
=15)
1031 if bssid
and bssid
not in ev
:
1032 raise Exception("Connected to incorrect BSS")
1034 conn_bssid
= dev
.get_status_field("bssid")
1035 if bssid
and conn_bssid
!= bssid
:
1036 raise Exception("bssid information points to incorrect BSS")
1042 def default_cred(domain
=None):
1043 cred
= { 'realm': "example.com",
1044 'ca_cert': "auth_serv/ca.pem",
1045 'username': "hs20-test",
1046 'password': "password" }
1048 cred
['domain'] = domain
1051 def test_ap_hs20_prefer_home(dev
, apdev
):
1052 """Hotspot 2.0 required roaming consortium"""
1053 params
= hs20_ap_params()
1054 params
['domain_name'] = "example.org"
1055 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1057 params
= hs20_ap_params()
1058 params
['ssid'] = "test-hs20-other"
1059 params
['domain_name'] = "example.com"
1060 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1062 values
= default_cred()
1063 values
['domain'] = "example.com"
1064 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1065 values
['domain'] = "example.org"
1066 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1068 def test_ap_hs20_req_roaming_consortium(dev
, apdev
):
1069 """Hotspot 2.0 required roaming consortium"""
1070 params
= hs20_ap_params()
1071 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1073 params
= hs20_ap_params()
1074 params
['ssid'] = "test-hs20-other"
1075 params
['roaming_consortium'] = [ "223344" ]
1076 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1078 values
= default_cred()
1079 values
['required_roaming_consortium'] = "223344"
1080 policy_test(dev
[0], apdev
[1], values
)
1081 values
['required_roaming_consortium'] = "112233"
1082 policy_test(dev
[0], apdev
[0], values
)
1084 id = dev
[0].add_cred()
1085 dev
[0].set_cred(id, "required_roaming_consortium", "112233")
1086 dev
[0].set_cred(id, "required_roaming_consortium", "112233445566778899aabbccddeeff")
1088 for val
in [ "", "1", "11", "1122", "1122334", "112233445566778899aabbccddeeff00" ]:
1089 if "FAIL" not in dev
[0].request('SET_CRED {} required_roaming_consortium {}'.format(id, val
)):
1090 raise Exception("Invalid roaming consortium value accepted: " + val
)
1092 def test_ap_hs20_excluded_ssid(dev
, apdev
):
1093 """Hotspot 2.0 exclusion based on SSID"""
1094 params
= hs20_ap_params()
1095 params
['roaming_consortium'] = [ "223344" ]
1096 params
['anqp_3gpp_cell_net'] = "555,444"
1097 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1099 params
= hs20_ap_params()
1100 params
['ssid'] = "test-hs20-other"
1101 params
['roaming_consortium'] = [ "223344" ]
1102 params
['anqp_3gpp_cell_net'] = "555,444"
1103 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1105 values
= default_cred()
1106 values
['excluded_ssid'] = "test-hs20"
1107 events
= policy_test(dev
[0], apdev
[1], values
)
1108 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1110 raise Exception("Excluded network not reported")
1111 values
['excluded_ssid'] = "test-hs20-other"
1112 events
= policy_test(dev
[0], apdev
[0], values
)
1113 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[1]['bssid'] in e
]
1115 raise Exception("Excluded network not reported")
1117 values
= default_cred()
1118 values
['roaming_consortium'] = "223344"
1119 values
['eap'] = "TTLS"
1120 values
['phase2'] = "auth=MSCHAPV2"
1121 values
['excluded_ssid'] = "test-hs20"
1122 events
= policy_test(dev
[0], apdev
[1], values
)
1123 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1125 raise Exception("Excluded network not reported")
1127 values
= { 'imsi': "555444-333222111", 'eap': "SIM",
1128 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123",
1129 'excluded_ssid': "test-hs20" }
1130 events
= policy_test(dev
[0], apdev
[1], values
)
1131 ev
= [e
for e
in events
if "INTERWORKING-BLACKLISTED " + apdev
[0]['bssid'] in e
]
1133 raise Exception("Excluded network not reported")
1135 def test_ap_hs20_roam_to_higher_prio(dev
, apdev
):
1136 """Hotspot 2.0 and roaming from current to higher priority network"""
1137 bssid
= apdev
[0]['bssid']
1138 params
= hs20_ap_params(ssid
="test-hs20-visited")
1139 params
['domain_name'] = "visited.example.org"
1140 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1142 dev
[0].hs20_enable()
1143 id = dev
[0].add_cred_values({ 'realm': "example.com",
1144 'ca_cert': "auth_serv/ca.pem",
1145 'username': "hs20-test",
1146 'password': "password",
1147 'domain': "example.com" })
1148 logger
.info("Connect to the only network option")
1149 interworking_select(dev
[0], bssid
, "roaming", freq
="2412")
1150 dev
[0].dump_monitor()
1151 interworking_connect(dev
[0], bssid
, "TTLS")
1153 logger
.info("Start another AP (home operator) and reconnect")
1154 bssid2
= apdev
[1]['bssid']
1155 params
= hs20_ap_params(ssid
="test-hs20-home")
1156 params
['domain_name'] = "example.com"
1157 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1159 dev
[0].scan_for_bss(bssid2
, freq
="2412", force_scan
=True)
1160 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1161 ev
= dev
[0].wait_event(["INTERWORKING-NO-MATCH",
1162 "INTERWORKING-ALREADY-CONNECTED",
1163 "CTRL-EVENT-CONNECTED"], timeout
=15)
1165 raise Exception("Connection timed out")
1166 if "INTERWORKING-NO-MATCH" in ev
:
1167 raise Exception("Matching AP not found")
1168 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1169 raise Exception("Unexpected AP selected")
1170 if bssid2
not in ev
:
1171 raise Exception("Unexpected BSSID after reconnection")
1173 def test_ap_hs20_domain_suffix_match_full(dev
, apdev
):
1174 """Hotspot 2.0 and domain_suffix_match"""
1175 bssid
= apdev
[0]['bssid']
1176 params
= hs20_ap_params()
1177 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1179 dev
[0].hs20_enable()
1180 id = dev
[0].add_cred_values({ 'realm': "example.com",
1181 'username': "hs20-test",
1182 'password': "password",
1183 'ca_cert': "auth_serv/ca.pem",
1184 'domain': "example.com",
1185 'domain_suffix_match': "server.w1.fi" })
1186 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1187 dev
[0].dump_monitor()
1188 interworking_connect(dev
[0], bssid
, "TTLS")
1189 dev
[0].request("REMOVE_NETWORK all")
1190 dev
[0].dump_monitor()
1192 dev
[0].set_cred_quoted(id, "domain_suffix_match", "no-match.example.com")
1193 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1194 dev
[0].dump_monitor()
1195 dev
[0].request("INTERWORKING_CONNECT " + bssid
)
1196 ev
= dev
[0].wait_event(["CTRL-EVENT-EAP-TLS-CERT-ERROR"])
1198 raise Exception("TLS certificate error not reported")
1199 if "Domain suffix mismatch" not in ev
:
1200 raise Exception("Domain suffix mismatch not reported")
1202 def test_ap_hs20_domain_suffix_match(dev
, apdev
):
1203 """Hotspot 2.0 and domain_suffix_match"""
1204 check_domain_match_full(dev
[0])
1205 bssid
= apdev
[0]['bssid']
1206 params
= hs20_ap_params()
1207 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1209 dev
[0].hs20_enable()
1210 id = dev
[0].add_cred_values({ 'realm': "example.com",
1211 'username': "hs20-test",
1212 'password': "password",
1213 'ca_cert': "auth_serv/ca.pem",
1214 'domain': "example.com",
1215 'domain_suffix_match': "w1.fi" })
1216 interworking_select(dev
[0], bssid
, "home", freq
="2412")
1217 dev
[0].dump_monitor()
1218 interworking_connect(dev
[0], bssid
, "TTLS")
1220 def test_ap_hs20_roaming_partner_preference(dev
, apdev
):
1221 """Hotspot 2.0 and roaming partner preference"""
1222 params
= hs20_ap_params()
1223 params
['domain_name'] = "roaming.example.org"
1224 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1226 params
= hs20_ap_params()
1227 params
['ssid'] = "test-hs20-other"
1228 params
['domain_name'] = "roaming.example.net"
1229 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1231 logger
.info("Verify default vs. specified preference")
1232 values
= default_cred()
1233 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1234 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1235 values
['roaming_partner'] = "roaming.example.net,1,129,*"
1236 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1238 logger
.info("Verify partial FQDN match")
1239 values
['roaming_partner'] = "example.net,0,0,*"
1240 policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1241 values
['roaming_partner'] = "example.net,0,255,*"
1242 policy_test(dev
[0], apdev
[0], values
, only_one
=False)
1244 def test_ap_hs20_max_bss_load(dev
, apdev
):
1245 """Hotspot 2.0 and maximum BSS load"""
1246 params
= hs20_ap_params()
1247 params
['bss_load_test'] = "12:200:20000"
1248 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1250 params
= hs20_ap_params()
1251 params
['ssid'] = "test-hs20-other"
1252 params
['bss_load_test'] = "5:20:10000"
1253 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1255 logger
.info("Verify maximum BSS load constraint")
1256 values
= default_cred()
1257 values
['domain'] = "example.com"
1258 values
['max_bss_load'] = "100"
1259 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1261 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1262 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1263 raise Exception("Maximum BSS Load case not noticed")
1264 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1265 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1266 raise Exception("Maximum BSS Load case reported incorrectly")
1268 logger
.info("Verify maximum BSS load does not prevent connection")
1269 values
['max_bss_load'] = "1"
1270 events
= policy_test(dev
[0], None, values
)
1272 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1273 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1274 raise Exception("Maximum BSS Load case not noticed")
1275 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1276 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1277 raise Exception("Maximum BSS Load case not noticed")
1279 def test_ap_hs20_max_bss_load2(dev
, apdev
):
1280 """Hotspot 2.0 and maximum BSS load with one AP not advertising"""
1281 params
= hs20_ap_params()
1282 params
['bss_load_test'] = "12:200:20000"
1283 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1285 params
= hs20_ap_params()
1286 params
['ssid'] = "test-hs20-other"
1287 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1289 logger
.info("Verify maximum BSS load constraint with AP advertisement")
1290 values
= default_cred()
1291 values
['domain'] = "example.com"
1292 values
['max_bss_load'] = "100"
1293 events
= policy_test(dev
[0], apdev
[1], values
, only_one
=False)
1295 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[0]['bssid'] in e
]
1296 if len(ev
) != 1 or "over_max_bss_load=1" not in ev
[0]:
1297 raise Exception("Maximum BSS Load case not noticed")
1298 ev
= [e
for e
in events
if "INTERWORKING-AP " + apdev
[1]['bssid'] in e
]
1299 if len(ev
) != 1 or "over_max_bss_load=1" in ev
[0]:
1300 raise Exception("Maximum BSS Load case reported incorrectly")
1302 def test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1303 """Hotspot 2.0 multi-cred sp_priority"""
1305 _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
)
1307 dev
[0].request("SET external_sim 0")
1309 def _test_ap_hs20_multi_cred_sp_prio(dev
, apdev
):
1310 hlr_auc_gw_available()
1311 bssid
= apdev
[0]['bssid']
1312 params
= hs20_ap_params()
1313 params
['hessid'] = bssid
1314 del params
['domain_name']
1315 params
['anqp_3gpp_cell_net'] = "232,01"
1316 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1318 dev
[0].hs20_enable()
1319 dev
[0].scan_for_bss(bssid
, freq
="2412")
1320 dev
[0].request("SET external_sim 1")
1321 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1322 'provisioning_sp': "example.com",
1323 'sp_priority' :"1" })
1324 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1325 'ca_cert': "auth_serv/ca.pem",
1326 'username': "hs20-test",
1327 'password': "password",
1328 'domain': "example.com",
1329 'provisioning_sp': "example.com",
1330 'sp_priority': "2" })
1331 dev
[0].dump_monitor()
1332 dev
[0].scan_for_bss(bssid
, freq
="2412")
1333 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1334 interworking_ext_sim_auth(dev
[0], "SIM")
1335 check_sp_type(dev
[0], "unknown")
1336 dev
[0].request("REMOVE_NETWORK all")
1338 dev
[0].set_cred(id1
, "sp_priority", "2")
1339 dev
[0].set_cred(id2
, "sp_priority", "1")
1340 dev
[0].dump_monitor()
1341 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1342 interworking_auth(dev
[0], "TTLS")
1343 check_sp_type(dev
[0], "unknown")
1345 def test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1346 """Hotspot 2.0 multi-cred sp_priority with two BSSes"""
1348 _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
)
1350 dev
[0].request("SET external_sim 0")
1352 def _test_ap_hs20_multi_cred_sp_prio2(dev
, apdev
):
1353 hlr_auc_gw_available()
1354 bssid
= apdev
[0]['bssid']
1355 params
= hs20_ap_params()
1356 params
['hessid'] = bssid
1357 del params
['nai_realm']
1358 del params
['domain_name']
1359 params
['anqp_3gpp_cell_net'] = "232,01"
1360 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1362 bssid2
= apdev
[1]['bssid']
1363 params
= hs20_ap_params()
1364 params
['ssid'] = "test-hs20-other"
1365 params
['hessid'] = bssid2
1366 del params
['domain_name']
1367 del params
['anqp_3gpp_cell_net']
1368 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1370 dev
[0].hs20_enable()
1371 dev
[0].request("SET external_sim 1")
1372 id1
= dev
[0].add_cred_values({ 'imsi': "23201-0000000000", 'eap': "SIM",
1373 'provisioning_sp': "example.com",
1374 'sp_priority': "1" })
1375 id2
= dev
[0].add_cred_values({ 'realm': "example.com",
1376 'ca_cert': "auth_serv/ca.pem",
1377 'username': "hs20-test",
1378 'password': "password",
1379 'domain': "example.com",
1380 'provisioning_sp': "example.com",
1381 'sp_priority': "2" })
1382 dev
[0].dump_monitor()
1383 dev
[0].scan_for_bss(bssid
, freq
="2412")
1384 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1385 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1386 interworking_ext_sim_auth(dev
[0], "SIM")
1387 check_sp_type(dev
[0], "unknown")
1388 conn_bssid
= dev
[0].get_status_field("bssid")
1389 if conn_bssid
!= bssid
:
1390 raise Exception("Connected to incorrect BSS")
1391 dev
[0].request("REMOVE_NETWORK all")
1393 dev
[0].set_cred(id1
, "sp_priority", "2")
1394 dev
[0].set_cred(id2
, "sp_priority", "1")
1395 dev
[0].dump_monitor()
1396 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1397 interworking_auth(dev
[0], "TTLS")
1398 check_sp_type(dev
[0], "unknown")
1399 conn_bssid
= dev
[0].get_status_field("bssid")
1400 if conn_bssid
!= bssid2
:
1401 raise Exception("Connected to incorrect BSS")
1403 def check_conn_capab_selection(dev
, type, missing
):
1404 dev
.request("INTERWORKING_SELECT freq=2412")
1405 ev
= dev
.wait_event(["INTERWORKING-AP"])
1407 raise Exception("Network selection timed out");
1408 if "type=" + type not in ev
:
1409 raise Exception("Unexpected network type")
1410 if missing
and "conn_capab_missing=1" not in ev
:
1411 raise Exception("conn_capab_missing not reported")
1412 if not missing
and "conn_capab_missing=1" in ev
:
1413 raise Exception("conn_capab_missing reported unexpectedly")
1415 def conn_capab_cred(domain
=None, req_conn_capab
=None):
1416 cred
= default_cred(domain
=domain
)
1418 cred
['req_conn_capab'] = req_conn_capab
1421 def test_ap_hs20_req_conn_capab(dev
, apdev
):
1422 """Hotspot 2.0 network selection with req_conn_capab"""
1423 bssid
= apdev
[0]['bssid']
1424 params
= hs20_ap_params()
1425 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1427 dev
[0].hs20_enable()
1428 dev
[0].scan_for_bss(bssid
, freq
="2412")
1429 logger
.info("Not used in home network")
1430 values
= conn_capab_cred(domain
="example.com", req_conn_capab
="6:1234")
1431 id = dev
[0].add_cred_values(values
)
1432 check_conn_capab_selection(dev
[0], "home", False)
1434 logger
.info("Used in roaming network")
1435 dev
[0].remove_cred(id)
1436 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="6:1234")
1437 id = dev
[0].add_cred_values(values
)
1438 check_conn_capab_selection(dev
[0], "roaming", True)
1440 logger
.info("Verify that req_conn_capab does not prevent connection if no other network is available")
1441 check_auto_select(dev
[0], bssid
)
1443 logger
.info("Additional req_conn_capab checks")
1445 dev
[0].remove_cred(id)
1446 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="1:0")
1447 id = dev
[0].add_cred_values(values
)
1448 check_conn_capab_selection(dev
[0], "roaming", True)
1450 dev
[0].remove_cred(id)
1451 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="17:5060")
1452 id = dev
[0].add_cred_values(values
)
1453 check_conn_capab_selection(dev
[0], "roaming", True)
1455 bssid2
= apdev
[1]['bssid']
1456 params
= hs20_ap_params(ssid
="test-hs20b")
1457 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1458 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1460 dev
[0].remove_cred(id)
1461 values
= conn_capab_cred(domain
="example.org", req_conn_capab
="50")
1462 id = dev
[0].add_cred_values(values
)
1463 dev
[0].set_cred(id, "req_conn_capab", "6:22")
1464 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1465 dev
[0].request("INTERWORKING_SELECT freq=2412")
1466 for i
in range(0, 2):
1467 ev
= dev
[0].wait_event(["INTERWORKING-AP"])
1469 raise Exception("Network selection timed out");
1470 if bssid
in ev
and "conn_capab_missing=1" not in ev
:
1471 raise Exception("Missing protocol connection capability not reported")
1472 if bssid2
in ev
and "conn_capab_missing=1" in ev
:
1473 raise Exception("Protocol connection capability not reported correctly")
1475 def test_ap_hs20_req_conn_capab_and_roaming_partner_preference(dev
, apdev
):
1476 """Hotspot 2.0 and req_conn_capab with roaming partner preference"""
1477 bssid
= apdev
[0]['bssid']
1478 params
= hs20_ap_params()
1479 params
['domain_name'] = "roaming.example.org"
1480 params
['hs20_conn_capab'] = [ "1:0:2", "6:22:1", "17:5060:0", "50:0:1" ]
1481 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1483 bssid2
= apdev
[1]['bssid']
1484 params
= hs20_ap_params(ssid
="test-hs20-b")
1485 params
['domain_name'] = "roaming.example.net"
1486 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1488 values
= default_cred()
1489 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1490 id = dev
[0].add_cred_values(values
)
1491 check_auto_select(dev
[0], bssid2
)
1493 dev
[0].set_cred(id, "req_conn_capab", "50")
1494 check_auto_select(dev
[0], bssid
)
1496 dev
[0].remove_cred(id)
1497 id = dev
[0].add_cred_values(values
)
1498 dev
[0].set_cred(id, "req_conn_capab", "51")
1499 check_auto_select(dev
[0], bssid2
)
1501 def check_bandwidth_selection(dev
, type, below
):
1502 dev
.request("INTERWORKING_SELECT freq=2412")
1503 ev
= dev
.wait_event(["INTERWORKING-AP"])
1505 raise Exception("Network selection timed out");
1506 if "type=" + type not in ev
:
1507 raise Exception("Unexpected network type")
1508 if below
and "below_min_backhaul=1" not in ev
:
1509 raise Exception("below_min_backhaul not reported")
1510 if not below
and "below_min_backhaul=1" in ev
:
1511 raise Exception("below_min_backhaul reported unexpectedly")
1513 def bw_cred(domain
=None, dl_home
=None, ul_home
=None, dl_roaming
=None, ul_roaming
=None):
1514 cred
= default_cred(domain
=domain
)
1516 cred
['min_dl_bandwidth_home'] = str(dl_home
)
1518 cred
['min_ul_bandwidth_home'] = str(ul_home
)
1520 cred
['min_dl_bandwidth_roaming'] = str(dl_roaming
)
1522 cred
['min_ul_bandwidth_roaming'] = str(ul_roaming
)
1525 def test_ap_hs20_min_bandwidth_home(dev
, apdev
):
1526 """Hotspot 2.0 network selection with min bandwidth (home)"""
1527 bssid
= apdev
[0]['bssid']
1528 params
= hs20_ap_params()
1529 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1531 dev
[0].hs20_enable()
1532 dev
[0].scan_for_bss(bssid
, freq
="2412")
1533 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=58)
1534 id = dev
[0].add_cred_values(values
)
1535 check_bandwidth_selection(dev
[0], "home", False)
1536 dev
[0].remove_cred(id)
1538 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=58)
1539 id = dev
[0].add_cred_values(values
)
1540 check_bandwidth_selection(dev
[0], "home", True)
1541 dev
[0].remove_cred(id)
1543 values
= bw_cred(domain
="example.com", dl_home
=5490, ul_home
=59)
1544 id = dev
[0].add_cred_values(values
)
1545 check_bandwidth_selection(dev
[0], "home", True)
1546 dev
[0].remove_cred(id)
1548 values
= bw_cred(domain
="example.com", dl_home
=5491, ul_home
=59)
1549 id = dev
[0].add_cred_values(values
)
1550 check_bandwidth_selection(dev
[0], "home", True)
1551 check_auto_select(dev
[0], bssid
)
1553 bssid2
= apdev
[1]['bssid']
1554 params
= hs20_ap_params(ssid
="test-hs20-b")
1555 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1556 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1558 check_auto_select(dev
[0], bssid2
)
1560 def test_ap_hs20_min_bandwidth_roaming(dev
, apdev
):
1561 """Hotspot 2.0 network selection with min bandwidth (roaming)"""
1562 bssid
= apdev
[0]['bssid']
1563 params
= hs20_ap_params()
1564 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1566 dev
[0].hs20_enable()
1567 dev
[0].scan_for_bss(bssid
, freq
="2412")
1568 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=58)
1569 id = dev
[0].add_cred_values(values
)
1570 check_bandwidth_selection(dev
[0], "roaming", False)
1571 dev
[0].remove_cred(id)
1573 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=58)
1574 id = dev
[0].add_cred_values(values
)
1575 check_bandwidth_selection(dev
[0], "roaming", True)
1576 dev
[0].remove_cred(id)
1578 values
= bw_cred(domain
="example.org", dl_roaming
=5490, ul_roaming
=59)
1579 id = dev
[0].add_cred_values(values
)
1580 check_bandwidth_selection(dev
[0], "roaming", True)
1581 dev
[0].remove_cred(id)
1583 values
= bw_cred(domain
="example.org", dl_roaming
=5491, ul_roaming
=59)
1584 id = dev
[0].add_cred_values(values
)
1585 check_bandwidth_selection(dev
[0], "roaming", True)
1586 check_auto_select(dev
[0], bssid
)
1588 bssid2
= apdev
[1]['bssid']
1589 params
= hs20_ap_params(ssid
="test-hs20-b")
1590 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1591 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1593 check_auto_select(dev
[0], bssid2
)
1595 def test_ap_hs20_min_bandwidth_and_roaming_partner_preference(dev
, apdev
):
1596 """Hotspot 2.0 and minimum bandwidth with roaming partner preference"""
1597 bssid
= apdev
[0]['bssid']
1598 params
= hs20_ap_params()
1599 params
['domain_name'] = "roaming.example.org"
1600 params
['hs20_wan_metrics'] = "01:8000:1000:1:1:3000"
1601 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1603 bssid2
= apdev
[1]['bssid']
1604 params
= hs20_ap_params(ssid
="test-hs20-b")
1605 params
['domain_name'] = "roaming.example.net"
1606 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1608 values
= default_cred()
1609 values
['roaming_partner'] = "roaming.example.net,1,127,*"
1610 id = dev
[0].add_cred_values(values
)
1611 check_auto_select(dev
[0], bssid2
)
1613 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "6000")
1614 check_auto_select(dev
[0], bssid
)
1616 dev
[0].set_cred(id, "min_dl_bandwidth_roaming", "10000")
1617 check_auto_select(dev
[0], bssid2
)
1619 def test_ap_hs20_min_bandwidth_no_wan_metrics(dev
, apdev
):
1620 """Hotspot 2.0 network selection with min bandwidth but no WAN Metrics"""
1621 bssid
= apdev
[0]['bssid']
1622 params
= hs20_ap_params()
1623 del params
['hs20_wan_metrics']
1624 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1626 dev
[0].hs20_enable()
1627 dev
[0].scan_for_bss(bssid
, freq
="2412")
1628 values
= bw_cred(domain
="example.com", dl_home
=10000, ul_home
=10000,
1629 dl_roaming
=10000, ul_roaming
=10000)
1630 dev
[0].add_cred_values(values
)
1631 check_bandwidth_selection(dev
[0], "home", False)
1633 def test_ap_hs20_deauth_req_ess(dev
, apdev
):
1634 """Hotspot 2.0 connection and deauthentication request for ESS"""
1636 _test_ap_hs20_deauth_req_ess(dev
, apdev
)
1638 dev
[0].request("SET pmf 0")
1640 def _test_ap_hs20_deauth_req_ess(dev
, apdev
):
1641 dev
[0].request("SET pmf 2")
1642 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1643 dev
[0].dump_monitor()
1644 addr
= dev
[0].p2p_interface_addr()
1645 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1646 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 1 120 http://example.com/")
1647 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1649 raise Exception("Timeout on deauth imminent notice")
1650 if "1 120 http://example.com/" not in ev
:
1651 raise Exception("Unexpected deauth imminent notice: " + ev
)
1652 hapd
.request("DEAUTHENTICATE " + addr
)
1653 dev
[0].wait_disconnected(timeout
=10)
1654 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1655 raise Exception("Network not marked temporarily disabled")
1656 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1657 "Trying to associate",
1658 "CTRL-EVENT-CONNECTED"], timeout
=5)
1660 raise Exception("Unexpected connection attempt")
1662 def test_ap_hs20_deauth_req_bss(dev
, apdev
):
1663 """Hotspot 2.0 connection and deauthentication request for BSS"""
1665 _test_ap_hs20_deauth_req_bss(dev
, apdev
)
1667 dev
[0].request("SET pmf 0")
1669 def _test_ap_hs20_deauth_req_bss(dev
, apdev
):
1670 dev
[0].request("SET pmf 2")
1671 eap_test(dev
[0], apdev
[0], "21[3:26]", "TTLS", "user")
1672 dev
[0].dump_monitor()
1673 addr
= dev
[0].p2p_interface_addr()
1674 hapd
= hostapd
.Hostapd(apdev
[0]['ifname'])
1675 hapd
.request("HS20_DEAUTH_REQ " + addr
+ " 0 120 http://example.com/")
1676 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"])
1678 raise Exception("Timeout on deauth imminent notice")
1679 if "0 120 http://example.com/" not in ev
:
1680 raise Exception("Unexpected deauth imminent notice: " + ev
)
1681 hapd
.request("DEAUTHENTICATE " + addr
+ " reason=4")
1682 ev
= dev
[0].wait_disconnected(timeout
=10)
1683 if "reason=4" not in ev
:
1684 raise Exception("Unexpected disconnection reason")
1685 if "[TEMP-DISABLED]" not in dev
[0].list_networks()[0]['flags']:
1686 raise Exception("Network not marked temporarily disabled")
1687 ev
= dev
[0].wait_event(["SME: Trying to authenticate",
1688 "Trying to associate",
1689 "CTRL-EVENT-CONNECTED"], timeout
=5)
1691 raise Exception("Unexpected connection attempt")
1693 def test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1694 """Hotspot 2.0 connection and deauthentication request from RADIUS"""
1696 _test_ap_hs20_deauth_req_from_radius(dev
, apdev
)
1698 dev
[0].request("SET pmf 0")
1700 def _test_ap_hs20_deauth_req_from_radius(dev
, apdev
):
1701 bssid
= apdev
[0]['bssid']
1702 params
= hs20_ap_params()
1703 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1704 params
['hs20_deauth_req_timeout'] = "2"
1705 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1707 dev
[0].request("SET pmf 2")
1708 dev
[0].hs20_enable()
1709 dev
[0].add_cred_values({ 'realm': "example.com",
1710 'username': "hs20-deauth-test",
1711 'password': "password" })
1712 interworking_select(dev
[0], bssid
, freq
="2412")
1713 interworking_connect(dev
[0], bssid
, "TTLS")
1714 ev
= dev
[0].wait_event(["HS20-DEAUTH-IMMINENT-NOTICE"], timeout
=5)
1716 raise Exception("Timeout on deauth imminent notice")
1717 if " 1 100" not in ev
:
1718 raise Exception("Unexpected deauth imminent contents")
1719 dev
[0].wait_disconnected(timeout
=3)
1721 def test_ap_hs20_remediation_required(dev
, apdev
):
1722 """Hotspot 2.0 connection and remediation required from RADIUS"""
1724 _test_ap_hs20_remediation_required(dev
, apdev
)
1726 dev
[0].request("SET pmf 0")
1728 def _test_ap_hs20_remediation_required(dev
, apdev
):
1729 bssid
= apdev
[0]['bssid']
1730 params
= hs20_ap_params()
1731 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1732 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1734 dev
[0].request("SET pmf 1")
1735 dev
[0].hs20_enable()
1736 dev
[0].add_cred_values({ 'realm': "example.com",
1737 'username': "hs20-subrem-test",
1738 'password': "password" })
1739 interworking_select(dev
[0], bssid
, freq
="2412")
1740 interworking_connect(dev
[0], bssid
, "TTLS")
1741 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1743 raise Exception("Timeout on subscription remediation notice")
1744 if " 1 https://example.com/" not in ev
:
1745 raise Exception("Unexpected subscription remediation event contents")
1747 def test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1748 """Hotspot 2.0 connection and subrem from ctrl_iface"""
1750 _test_ap_hs20_remediation_required_ctrl(dev
, apdev
)
1752 dev
[0].request("SET pmf 0")
1754 def _test_ap_hs20_remediation_required_ctrl(dev
, apdev
):
1755 bssid
= apdev
[0]['bssid']
1756 addr
= dev
[0].p2p_dev_addr()
1757 params
= hs20_ap_params()
1758 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1759 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
1761 dev
[0].request("SET pmf 1")
1762 dev
[0].hs20_enable()
1763 dev
[0].add_cred_values(default_cred())
1764 interworking_select(dev
[0], bssid
, freq
="2412")
1765 interworking_connect(dev
[0], bssid
, "TTLS")
1767 hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://example.com/")
1768 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1770 raise Exception("Timeout on subscription remediation notice")
1771 if " 1 https://example.com/" not in ev
:
1772 raise Exception("Unexpected subscription remediation event contents")
1774 hapd
.request("HS20_WNM_NOTIF " + addr
)
1775 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
1777 raise Exception("Timeout on subscription remediation notice")
1778 if not ev
.endswith("HS20-SUBSCRIPTION-REMEDIATION "):
1779 raise Exception("Unexpected subscription remediation event contents: " + ev
)
1781 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF "):
1782 raise Exception("Unexpected HS20_WNM_NOTIF success")
1783 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF foo"):
1784 raise Exception("Unexpected HS20_WNM_NOTIF success")
1785 if "FAIL" not in hapd
.request("HS20_WNM_NOTIF " + addr
+ " https://12345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678923456789842345678456783456712345678927.very.long.example.com/"):
1786 raise Exception("Unexpected HS20_WNM_NOTIF success")
1788 def test_ap_hs20_session_info(dev
, apdev
):
1789 """Hotspot 2.0 connection and session information from RADIUS"""
1791 _test_ap_hs20_session_info(dev
, apdev
)
1793 dev
[0].request("SET pmf 0")
1795 def _test_ap_hs20_session_info(dev
, apdev
):
1796 bssid
= apdev
[0]['bssid']
1797 params
= hs20_ap_params()
1798 params
['nai_realm'] = [ "0,example.com,21[2:4]" ]
1799 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1801 dev
[0].request("SET pmf 1")
1802 dev
[0].hs20_enable()
1803 dev
[0].add_cred_values({ 'realm': "example.com",
1804 'username': "hs20-session-info-test",
1805 'password': "password" })
1806 interworking_select(dev
[0], bssid
, freq
="2412")
1807 interworking_connect(dev
[0], bssid
, "TTLS")
1808 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"], timeout
=10)
1810 raise Exception("Timeout on ESS disassociation imminent notice")
1811 if " 1 59904 https://example.com/" not in ev
:
1812 raise Exception("Unexpected ESS disassociation imminent event contents")
1813 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"])
1815 raise Exception("Scan not started")
1816 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout
=30)
1818 raise Exception("Scan not completed")
1820 def test_ap_hs20_osen(dev
, apdev
):
1821 """Hotspot 2.0 OSEN connection"""
1822 params
= { 'ssid': "osen",
1824 'auth_server_addr': "127.0.0.1",
1825 'auth_server_port': "1812",
1826 'auth_server_shared_secret': "radius" }
1827 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1829 dev
[1].connect("osen", key_mgmt
="NONE", scan_freq
="2412",
1831 dev
[2].connect("osen", key_mgmt
="NONE", wep_key0
='"hello"',
1832 scan_freq
="2412", wait_connect
=False)
1833 dev
[0].connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1834 group
="GTK_NOT_USED",
1835 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1836 ca_cert
="auth_serv/ca.pem",
1839 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1840 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1841 wpas
.connect("osen", proto
="OSEN", key_mgmt
="OSEN", pairwise
="CCMP",
1842 group
="GTK_NOT_USED",
1843 eap
="WFA-UNAUTH-TLS", identity
="osen@example.com",
1844 ca_cert
="auth_serv/ca.pem",
1846 wpas
.request("DISCONNECT")
1848 def test_ap_hs20_network_preference(dev
, apdev
):
1849 """Hotspot 2.0 network selection with preferred home network"""
1850 bssid
= apdev
[0]['bssid']
1851 params
= hs20_ap_params()
1852 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1854 dev
[0].hs20_enable()
1855 values
= { 'realm': "example.com",
1856 'username': "hs20-test",
1857 'password': "password",
1858 'domain': "example.com" }
1859 dev
[0].add_cred_values(values
)
1861 id = dev
[0].add_network()
1862 dev
[0].set_network_quoted(id, "ssid", "home")
1863 dev
[0].set_network_quoted(id, "psk", "12345678")
1864 dev
[0].set_network(id, "priority", "1")
1865 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1867 dev
[0].scan_for_bss(bssid
, freq
="2412")
1868 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1869 ev
= dev
[0].wait_connected(timeout
=15)
1871 raise Exception("Unexpected network selected")
1873 bssid2
= apdev
[1]['bssid']
1874 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1875 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1877 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1878 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1879 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1880 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1882 raise Exception("Connection timed out")
1883 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1884 raise Exception("No roam to higher priority network")
1885 if bssid2
not in ev
:
1886 raise Exception("Unexpected network selected")
1888 def test_ap_hs20_network_preference2(dev
, apdev
):
1889 """Hotspot 2.0 network selection with preferred credential"""
1890 bssid2
= apdev
[1]['bssid']
1891 params
= hostapd
.wpa2_params(ssid
="home", passphrase
="12345678")
1892 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1894 dev
[0].hs20_enable()
1895 values
= { 'realm': "example.com",
1896 'username': "hs20-test",
1897 'password': "password",
1898 'domain': "example.com",
1900 dev
[0].add_cred_values(values
)
1902 id = dev
[0].add_network()
1903 dev
[0].set_network_quoted(id, "ssid", "home")
1904 dev
[0].set_network_quoted(id, "psk", "12345678")
1905 dev
[0].request("ENABLE_NETWORK %s no-connect" % id)
1907 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1908 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1909 ev
= dev
[0].wait_connected(timeout
=15)
1910 if bssid2
not in ev
:
1911 raise Exception("Unexpected network selected")
1913 bssid
= apdev
[0]['bssid']
1914 params
= hs20_ap_params()
1915 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1917 dev
[0].scan_for_bss(bssid
, freq
="2412")
1918 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1919 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1920 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1922 raise Exception("Connection timed out")
1923 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1924 raise Exception("No roam to higher priority network")
1926 raise Exception("Unexpected network selected")
1928 def test_ap_hs20_network_preference3(dev
, apdev
):
1929 """Hotspot 2.0 network selection with two credential (one preferred)"""
1930 bssid
= apdev
[0]['bssid']
1931 params
= hs20_ap_params()
1932 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1934 bssid2
= apdev
[1]['bssid']
1935 params
= hs20_ap_params(ssid
="test-hs20b")
1936 params
['nai_realm'] = "0,example.org,13[5:6],21[2:4][5:7]"
1937 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1939 dev
[0].hs20_enable()
1940 values
= { 'realm': "example.com",
1941 'username': "hs20-test",
1942 'password': "password",
1944 dev
[0].add_cred_values(values
)
1945 values
= { 'realm': "example.org",
1946 'username': "hs20-test",
1947 'password': "password" }
1948 id = dev
[0].add_cred_values(values
)
1950 dev
[0].scan_for_bss(bssid
, freq
="2412")
1951 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1952 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1953 ev
= dev
[0].wait_connected(timeout
=15)
1955 raise Exception("Unexpected network selected")
1957 dev
[0].set_cred(id, "priority", "2")
1958 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1959 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
1960 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
1962 raise Exception("Connection timed out")
1963 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
1964 raise Exception("No roam to higher priority network")
1965 if bssid2
not in ev
:
1966 raise Exception("Unexpected network selected")
1968 def test_ap_hs20_network_preference4(dev
, apdev
):
1969 """Hotspot 2.0 network selection with username vs. SIM credential"""
1970 bssid
= apdev
[0]['bssid']
1971 params
= hs20_ap_params()
1972 hostapd
.add_ap(apdev
[0]['ifname'], params
)
1974 bssid2
= apdev
[1]['bssid']
1975 params
= hs20_ap_params(ssid
="test-hs20b")
1976 params
['hessid'] = bssid2
1977 params
['anqp_3gpp_cell_net'] = "555,444"
1978 params
['domain_name'] = "wlan.mnc444.mcc555.3gppnetwork.org"
1979 hostapd
.add_ap(apdev
[1]['ifname'], params
)
1981 dev
[0].hs20_enable()
1982 values
= { 'realm': "example.com",
1983 'username': "hs20-test",
1984 'password': "password",
1986 dev
[0].add_cred_values(values
)
1987 values
= { 'imsi': "555444-333222111",
1989 'milenage': "5122250214c33e723a5dd523fc145fc0:981d464c7c52eb6e5036234984ad0bcf:000000000123" }
1990 id = dev
[0].add_cred_values(values
)
1992 dev
[0].scan_for_bss(bssid
, freq
="2412")
1993 dev
[0].scan_for_bss(bssid2
, freq
="2412")
1994 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
1995 ev
= dev
[0].wait_connected(timeout
=15)
1997 raise Exception("Unexpected network selected")
1999 dev
[0].set_cred(id, "priority", "2")
2000 dev
[0].request("INTERWORKING_SELECT auto freq=2412")
2001 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED",
2002 "INTERWORKING-ALREADY-CONNECTED" ], timeout
=15)
2004 raise Exception("Connection timed out")
2005 if "INTERWORKING-ALREADY-CONNECTED" in ev
:
2006 raise Exception("No roam to higher priority network")
2007 if bssid2
not in ev
:
2008 raise Exception("Unexpected network selected")
2010 def test_ap_hs20_fetch_osu(dev
, apdev
):
2011 """Hotspot 2.0 OSU provider and icon fetch"""
2012 bssid
= apdev
[0]['bssid']
2013 params
= hs20_ap_params()
2014 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2015 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2016 params
['osu_method_list'] = "1"
2017 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2018 params
['osu_icon'] = "w1fi_logo"
2019 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2020 params
['osu_server_uri'] = "https://example.com/osu/"
2021 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2023 bssid2
= apdev
[1]['bssid']
2024 params
= hs20_ap_params(ssid
="test-hs20b")
2025 params
['hessid'] = bssid2
2026 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2027 params
['osu_ssid'] = '"HS 2.0 OSU OSEN"'
2028 params
['osu_method_list'] = "0"
2029 params
['osu_nai'] = "osen@example.com"
2030 params
['osu_friendly_name'] = [ "eng:Test2 OSU", "fin:Testi2-OSU" ]
2031 params
['osu_icon'] = "w1fi_logo"
2032 params
['osu_service_desc'] = [ "eng:Example services2", "fin:Esimerkkipalveluja2" ]
2033 params
['osu_server_uri'] = "https://example.org/osu/"
2034 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2036 with
open("w1fi_logo.png", "r") as f
:
2037 orig_logo
= f
.read()
2038 dev
[0].hs20_enable()
2039 dir = "/tmp/osu-fetch"
2040 if os
.path
.isdir(dir):
2041 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2043 os
.remove(dir + "/" + f
)
2050 dev
[1].scan_for_bss(bssid
, freq
="2412")
2051 dev
[0].request("SET osu_dir " + dir)
2052 dev
[0].request("FETCH_OSU")
2053 if "FAIL" not in dev
[1].request("HS20_ICON_REQUEST foo w1fi_logo"):
2054 raise Exception("Invalid HS20_ICON_REQUEST accepted")
2055 if "OK" not in dev
[1].request("HS20_ICON_REQUEST " + bssid
+ " w1fi_logo"):
2056 raise Exception("HS20_ICON_REQUEST failed")
2059 ev
= dev
[0].wait_event(["OSU provider fetch completed",
2060 "RX-HS20-ANQP-ICON"], timeout
=15)
2062 raise Exception("Timeout on OSU fetch")
2063 if "OSU provider fetch completed" in ev
:
2065 if "RX-HS20-ANQP-ICON" in ev
:
2066 with
open(ev
.split(' ')[1], "r") as f
:
2068 if logo
== orig_logo
:
2071 with
open(dir + "/osu-providers.txt", "r") as f
:
2073 if "OSU-PROVIDER " + bssid
not in prov
:
2074 raise Exception("Missing OSU_PROVIDER")
2075 if "OSU-PROVIDER " + bssid2
not in prov
:
2076 raise Exception("Missing OSU_PROVIDER")
2078 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2080 os
.remove(dir + "/" + f
)
2084 raise Exception("Unexpected number of icons fetched")
2086 ev
= dev
[1].wait_event(["GAS-QUERY-START"], timeout
=5)
2088 raise Exception("Timeout on GAS-QUERY-DONE")
2089 ev
= dev
[1].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2091 raise Exception("Timeout on GAS-QUERY-DONE")
2092 if "freq=2412 status_code=0 result=SUCCESS" not in ev
:
2093 raise Exception("Unexpected GAS-QUERY-DONE: " + ev
)
2094 ev
= dev
[1].wait_event(["RX-HS20-ANQP"], timeout
=15)
2096 raise Exception("Timeout on icon fetch")
2097 if "Icon Binary File" not in ev
:
2098 raise Exception("Unexpected ANQP element")
2100 def test_ap_hs20_fetch_osu_stop(dev
, apdev
):
2101 """Hotspot 2.0 OSU provider fetch stopped"""
2102 bssid
= apdev
[0]['bssid']
2103 params
= hs20_ap_params()
2104 params
['hs20_icon'] = "128:80:zxx:image/png:w1fi_logo:w1fi_logo.png"
2105 params
['osu_ssid'] = '"HS 2.0 OSU open"'
2106 params
['osu_method_list'] = "1"
2107 params
['osu_friendly_name'] = [ "eng:Test OSU", "fin:Testi-OSU" ]
2108 params
['osu_icon'] = "w1fi_logo"
2109 params
['osu_service_desc'] = [ "eng:Example services", "fin:Esimerkkipalveluja" ]
2110 params
['osu_server_uri'] = "https://example.com/osu/"
2111 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2113 dev
[0].hs20_enable()
2114 dir = "/tmp/osu-fetch"
2115 if os
.path
.isdir(dir):
2116 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2118 os
.remove(dir + "/" + f
)
2125 dev
[0].request("SET osu_dir " + dir)
2126 dev
[0].request("SCAN freq=2412-2462")
2127 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=10)
2129 raise Exception("Scan did not start")
2130 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2131 raise Exception("FETCH_OSU accepted while scanning")
2132 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 10)
2134 raise Exception("Scan timed out")
2135 hapd
.set("ext_mgmt_frame_handling", "1")
2136 dev
[0].request("FETCH_ANQP")
2137 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2138 raise Exception("FETCH_OSU accepted while in FETCH_ANQP")
2139 dev
[0].request("STOP_FETCH_ANQP")
2140 dev
[0].wait_event(["GAS-QUERY-DONE"], timeout
=5)
2141 dev
[0].dump_monitor()
2143 dev
[0].request("INTERWORKING_SELECT freq=2412")
2145 msg
= hapd
.mgmt_rx()
2146 if msg
['subtype'] == 13:
2148 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2149 raise Exception("FETCH_OSU accepted while in INTERWORKING_SELECT")
2150 ev
= dev
[0].wait_event(["INTERWORKING-AP", "INTERWORKING-NO-MATCH"],
2153 raise Exception("Network selection timed out");
2155 dev
[0].dump_monitor()
2156 if "OK" not in dev
[0].request("FETCH_OSU"):
2157 raise Exception("FETCH_OSU failed")
2158 dev
[0].request("CANCEL_FETCH_OSU")
2162 if dev
[0].get_driver_status_field("scan_state") == "SCAN_COMPLETED":
2165 dev
[0].dump_monitor()
2166 if "OK" not in dev
[0].request("FETCH_OSU"):
2167 raise Exception("FETCH_OSU failed")
2168 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2169 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2170 ev
= dev
[0].wait_event(["GAS-QUERY-START"], 10)
2172 raise Exception("GAS timed out")
2173 if "FAIL" not in dev
[0].request("FETCH_OSU"):
2174 raise Exception("FETCH_OSU accepted while in FETCH_OSU")
2175 dev
[0].request("CANCEL_FETCH_OSU")
2176 ev
= dev
[0].wait_event(["GAS-QUERY-DONE"], 10)
2178 raise Exception("GAS event timed out after CANCEL_FETCH_OSU")
2180 files
= [ f
for f
in os
.listdir(dir) if f
.startswith("osu-") ]
2182 os
.remove(dir + "/" + f
)
2185 def test_ap_hs20_ft(dev
, apdev
):
2186 """Hotspot 2.0 connection with FT"""
2187 bssid
= apdev
[0]['bssid']
2188 params
= hs20_ap_params()
2189 params
['wpa_key_mgmt'] = "FT-EAP"
2190 params
['nas_identifier'] = "nas1.w1.fi"
2191 params
['r1_key_holder'] = "000102030405"
2192 params
["mobility_domain"] = "a1b2"
2193 params
["reassociation_deadline"] = "1000"
2194 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2196 dev
[0].hs20_enable()
2197 id = dev
[0].add_cred_values({ 'realm': "example.com",
2198 'username': "hs20-test",
2199 'password': "password",
2200 'ca_cert': "auth_serv/ca.pem",
2201 'domain': "example.com",
2202 'update_identifier': "1234" })
2203 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2204 interworking_connect(dev
[0], bssid
, "TTLS")
2206 def test_ap_hs20_remediation_sql(dev
, apdev
, params
):
2207 """Hotspot 2.0 connection and remediation required using SQLite for user DB"""
2211 raise HwsimSkip("No sqlite3 module available")
2212 dbfile
= os
.path
.join(params
['logdir'], "eap-user.db")
2217 con
= sqlite3
.connect(dbfile
)
2220 cur
.execute("CREATE TABLE users(identity TEXT PRIMARY KEY, methods TEXT, password TEXT, remediation TEXT, phase2 INTEGER)")
2221 cur
.execute("CREATE TABLE wildcards(identity TEXT PRIMARY KEY, methods TEXT)")
2222 cur
.execute("INSERT INTO users(identity,methods,password,phase2,remediation) VALUES ('user-mschapv2','TTLS-MSCHAPV2','password',1,'user')")
2223 cur
.execute("INSERT INTO wildcards(identity,methods) VALUES ('','TTLS,TLS')")
2224 cur
.execute("CREATE TABLE authlog(timestamp TEXT, session TEXT, nas_ip TEXT, username TEXT, note TEXT)")
2227 params
= { "ssid": "as", "beacon_int": "2000",
2228 "radius_server_clients": "auth_serv/radius_clients.conf",
2229 "radius_server_auth_port": '18128',
2231 "eap_user_file": "sqlite:" + dbfile
,
2232 "ca_cert": "auth_serv/ca.pem",
2233 "server_cert": "auth_serv/server.pem",
2234 "private_key": "auth_serv/server.key",
2235 "subscr_remediation_url": "https://example.org/",
2236 "subscr_remediation_method": "1" }
2237 hostapd
.add_ap(apdev
[1]['ifname'], params
)
2239 bssid
= apdev
[0]['bssid']
2240 params
= hs20_ap_params()
2241 params
['auth_server_port'] = "18128"
2242 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2244 dev
[0].request("SET pmf 1")
2245 dev
[0].hs20_enable()
2246 id = dev
[0].add_cred_values({ 'realm': "example.com",
2247 'username': "user-mschapv2",
2248 'password': "password",
2249 'ca_cert': "auth_serv/ca.pem" })
2250 interworking_select(dev
[0], bssid
, freq
="2412")
2251 interworking_connect(dev
[0], bssid
, "TTLS")
2252 ev
= dev
[0].wait_event(["HS20-SUBSCRIPTION-REMEDIATION"], timeout
=5)
2254 raise Exception("Timeout on subscription remediation notice")
2255 if " 1 https://example.org/" not in ev
:
2256 raise Exception("Unexpected subscription remediation event contents")
2260 cur
.execute("SELECT * from authlog")
2261 rows
= cur
.fetchall()
2263 raise Exception("No authlog entries")
2267 dev
[0].request("SET pmf 0")
2269 def test_ap_hs20_external_selection(dev
, apdev
):
2270 """Hotspot 2.0 connection using external network selection and creation"""
2271 bssid
= apdev
[0]['bssid']
2272 params
= hs20_ap_params()
2273 params
['hessid'] = bssid
2274 params
['disable_dgaf'] = '1'
2275 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2277 dev
[0].hs20_enable()
2278 dev
[0].connect("test-hs20", proto
="RSN", key_mgmt
="WPA-EAP", eap
="TTLS",
2279 identity
="hs20-test", password
="password",
2280 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2281 scan_freq
="2412", update_identifier
="54321")
2282 if dev
[0].get_status_field("hs20") != "2":
2283 raise Exception("Unexpected hs20 indication")
2285 def test_ap_hs20_random_mac_addr(dev
, apdev
):
2286 """Hotspot 2.0 connection with random MAC address"""
2287 bssid
= apdev
[0]['bssid']
2288 params
= hs20_ap_params()
2289 params
['hessid'] = bssid
2290 params
['disable_dgaf'] = '1'
2291 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2293 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
2294 wpas
.interface_add("wlan5")
2295 addr
= wpas
.p2p_interface_addr()
2296 wpas
.request("SET mac_addr 1")
2297 wpas
.request("SET preassoc_mac_addr 1")
2298 wpas
.request("SET rand_addr_lifetime 60")
2300 wpas
.flush_scan_cache()
2301 id = wpas
.add_cred_values({ 'realm': "example.com",
2302 'username': "hs20-test",
2303 'password': "password",
2304 'ca_cert': "auth_serv/ca.pem",
2305 'domain': "example.com",
2306 'update_identifier': "1234" })
2307 interworking_select(wpas
, bssid
, "home", freq
="2412")
2308 interworking_connect(wpas
, bssid
, "TTLS")
2309 addr1
= wpas
.get_driver_status_field("addr")
2311 raise Exception("Did not use random MAC address")
2313 sta
= hapd
.get_sta(addr
)
2314 if sta
['addr'] != "FAIL":
2315 raise Exception("Unexpected STA association with permanent address")
2316 sta
= hapd
.get_sta(addr1
)
2317 if sta
['addr'] != addr1
:
2318 raise Exception("STA association with random address not found")
2320 def test_ap_hs20_multi_network_and_cred_removal(dev
, apdev
):
2321 """Multiple networks and cred removal"""
2322 bssid
= apdev
[0]['bssid']
2323 params
= hs20_ap_params()
2324 params
['nai_realm'] = [ "0,example.com,25[3:26]"]
2325 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
)
2327 dev
[0].add_network()
2328 dev
[0].hs20_enable()
2329 id = dev
[0].add_cred_values({ 'realm': "example.com",
2331 'password': "password" })
2332 interworking_select(dev
[0], bssid
, freq
="2412")
2333 interworking_connect(dev
[0], bssid
, "PEAP")
2334 dev
[0].add_network()
2336 dev
[0].request("DISCONNECT")
2337 dev
[0].wait_disconnected(timeout
=10)
2340 hapd
.set("ssid", "another ssid")
2343 interworking_select(dev
[0], bssid
, freq
="2412")
2344 interworking_connect(dev
[0], bssid
, "PEAP")
2345 dev
[0].add_network()
2346 if len(dev
[0].list_networks()) != 5:
2347 raise Exception("Unexpected number of networks prior to remove_crec")
2349 dev
[0].dump_monitor()
2350 dev
[0].remove_cred(id)
2351 if len(dev
[0].list_networks()) != 3:
2352 raise Exception("Unexpected number of networks after to remove_crec")
2353 dev
[0].wait_disconnected(timeout
=10)
2355 def _test_ap_hs20_proxyarp(dev
, apdev
):
2356 bssid
= apdev
[0]['bssid']
2357 params
= hs20_ap_params()
2358 params
['hessid'] = bssid
2359 params
['disable_dgaf'] = '0'
2360 params
['proxy_arp'] = '1'
2361 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2362 if "OK" in hapd
.request("ENABLE"):
2363 raise Exception("Incomplete hostapd configuration was accepted")
2364 hapd
.set("ap_isolate", "1")
2365 if "OK" in hapd
.request("ENABLE"):
2366 raise Exception("Incomplete hostapd configuration was accepted")
2367 hapd
.set('bridge', 'ap-br0')
2372 # For now, do not report failures due to missing kernel support
2373 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2374 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2376 raise Exception("AP startup timed out")
2377 if "AP-ENABLED" not in ev
:
2378 raise Exception("AP startup failed")
2380 dev
[0].hs20_enable()
2381 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2382 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2384 id = dev
[0].add_cred_values({ 'realm': "example.com",
2385 'username': "hs20-test",
2386 'password': "password",
2387 'ca_cert': "auth_serv/ca.pem",
2388 'domain': "example.com",
2389 'update_identifier': "1234" })
2390 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2391 interworking_connect(dev
[0], bssid
, "TTLS")
2393 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2394 identity
="hs20-test", password
="password",
2395 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2399 addr0
= dev
[0].p2p_interface_addr()
2400 addr1
= dev
[1].p2p_interface_addr()
2402 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2403 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2405 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2406 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2408 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2409 raise Exception("DATA_TEST_FRAME failed")
2411 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:dddd::2",
2412 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:dddd::2",
2414 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2415 raise Exception("DATA_TEST_FRAME failed")
2417 pkt
= build_ns(src_ll
=addr1
, ip_src
="aaaa:bbbb:eeee::2",
2418 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:eeee::2",
2420 if "OK" not in dev
[1].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2421 raise Exception("DATA_TEST_FRAME failed")
2423 matches
= get_permanent_neighbors("ap-br0")
2424 logger
.info("After connect: " + str(matches
))
2425 if len(matches
) != 3:
2426 raise Exception("Unexpected number of neighbor entries after connect")
2427 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2428 raise Exception("dev0 addr missing")
2429 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2430 raise Exception("dev1 addr(1) missing")
2431 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2432 raise Exception("dev1 addr(2) missing")
2433 dev
[0].request("DISCONNECT")
2434 dev
[1].request("DISCONNECT")
2436 matches
= get_permanent_neighbors("ap-br0")
2437 logger
.info("After disconnect: " + str(matches
))
2438 if len(matches
) > 0:
2439 raise Exception("Unexpected neighbor entries after disconnect")
2441 def test_ap_hs20_hidden_ssid_in_scan_res(dev
, apdev
):
2442 """Hotspot 2.0 connection with hidden SSId in scan results"""
2443 bssid
= apdev
[0]['bssid']
2445 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], { "ssid": 'secret',
2446 "ignore_broadcast_ssid": "1" })
2447 dev
[0].scan_for_bss(bssid
, freq
=2412)
2449 hapd_global
= hostapd
.HostapdGlobal()
2451 hapd_global
.remove(apdev
[0]['ifname'])
2453 params
= hs20_ap_params()
2454 params
['hessid'] = bssid
2455 hostapd
.add_ap(apdev
[0]['ifname'], params
)
2457 dev
[0].hs20_enable()
2458 id = dev
[0].add_cred_values({ 'realm': "example.com",
2459 'username': "hs20-test",
2460 'password': "password",
2461 'ca_cert': "auth_serv/ca.pem",
2462 'domain': "example.com" })
2463 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2464 interworking_connect(dev
[0], bssid
, "TTLS")
2466 # clear BSS table to avoid issues in following test cases
2467 dev
[0].request("DISCONNECT")
2468 dev
[0].wait_disconnected()
2469 dev
[0].flush_scan_cache()
2471 def test_ap_hs20_proxyarp(dev
, apdev
):
2472 """Hotspot 2.0 and ProxyARP"""
2474 _test_ap_hs20_proxyarp(dev
, apdev
)
2476 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2477 stderr
=open('/dev/null', 'w'))
2478 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2479 stderr
=open('/dev/null', 'w'))
2481 def _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, disabled
):
2482 bssid
= apdev
[0]['bssid']
2483 params
= hs20_ap_params()
2484 params
['hessid'] = bssid
2485 params
['disable_dgaf'] = '1' if disabled
else '0'
2486 params
['proxy_arp'] = '1'
2487 params
['ap_isolate'] = '1'
2488 params
['bridge'] = 'ap-br0'
2489 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2493 # For now, do not report failures due to missing kernel support
2494 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2495 ev
= hapd
.wait_event(["AP-ENABLED"], timeout
=10)
2497 raise Exception("AP startup timed out")
2499 dev
[0].hs20_enable()
2500 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2501 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2503 id = dev
[0].add_cred_values({ 'realm': "example.com",
2504 'username': "hs20-test",
2505 'password': "password",
2506 'ca_cert': "auth_serv/ca.pem",
2507 'domain': "example.com",
2508 'update_identifier': "1234" })
2509 interworking_select(dev
[0], bssid
, "home", freq
="2412")
2510 interworking_connect(dev
[0], bssid
, "TTLS")
2512 dev
[1].connect("test-hs20", key_mgmt
="WPA-EAP", eap
="TTLS",
2513 identity
="hs20-test", password
="password",
2514 ca_cert
="auth_serv/ca.pem", phase2
="auth=MSCHAPV2",
2518 addr0
= dev
[0].p2p_interface_addr()
2520 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2522 pkt
= build_ns(src_ll
=addr0
, ip_src
="aaaa:bbbb:cccc::2",
2523 ip_dst
="ff02::1:ff00:2", target
="aaaa:bbbb:cccc::2",
2525 if "OK" not in dev
[0].request("DATA_TEST_FRAME " + binascii
.hexlify(pkt
)):
2526 raise Exception("DATA_TEST_FRAME failed")
2528 pkt
= build_ra(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::33",
2530 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2531 raise Exception("DATA_TEST_FRAME failed")
2533 pkt
= build_na(src_ll
=apdev
[0]['bssid'], ip_src
="aaaa:bbbb:cccc::44",
2534 ip_dst
="ff01::1", target
="aaaa:bbbb:cccc::55")
2535 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2536 raise Exception("DATA_TEST_FRAME failed")
2538 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2539 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2540 yiaddr
="192.168.1.123", chaddr
=addr0
)
2541 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2542 raise Exception("DATA_TEST_FRAME failed")
2543 # another copy for additional code coverage
2544 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2545 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2546 yiaddr
="192.168.1.123", chaddr
=addr0
)
2547 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2548 raise Exception("DATA_TEST_FRAME failed")
2550 matches
= get_permanent_neighbors("ap-br0")
2551 logger
.info("After connect: " + str(matches
))
2552 if len(matches
) != 2:
2553 raise Exception("Unexpected number of neighbor entries after connect")
2554 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2555 raise Exception("dev0 addr missing")
2556 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2557 raise Exception("dev0 IPv4 addr missing")
2558 dev
[0].request("DISCONNECT")
2559 dev
[1].request("DISCONNECT")
2561 matches
= get_permanent_neighbors("ap-br0")
2562 logger
.info("After disconnect: " + str(matches
))
2563 if len(matches
) > 0:
2564 raise Exception("Unexpected neighbor entries after disconnect")
2566 def test_ap_hs20_proxyarp_disable_dgaf(dev
, apdev
):
2567 """Hotspot 2.0 and ProxyARP with DGAF disabled"""
2569 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, True)
2571 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2572 stderr
=open('/dev/null', 'w'))
2573 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2574 stderr
=open('/dev/null', 'w'))
2576 def test_ap_hs20_proxyarp_enable_dgaf(dev
, apdev
):
2577 """Hotspot 2.0 and ProxyARP with DGAF enabled"""
2579 _test_ap_hs20_proxyarp_dgaf(dev
, apdev
, False)
2581 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
2582 stderr
=open('/dev/null', 'w'))
2583 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
2584 stderr
=open('/dev/null', 'w'))
2586 def ip_checksum(buf
):
2590 for i
in range(0, len(buf
), 2):
2591 val
, = struct
.unpack('H', buf
[i
:i
+2])
2594 sum = (sum & 0xffff) + (sum >> 16)
2595 return struct
.pack('H', ~
sum & 0xffff)
2597 def ipv6_solicited_node_mcaddr(target
):
2598 prefix
= socket
.inet_pton(socket
.AF_INET6
, "ff02::1:ff00:0")
2599 mask
= socket
.inet_pton(socket
.AF_INET6
, "::ff:ffff")
2600 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2601 p
= struct
.unpack('4I', prefix
)
2602 m
= struct
.unpack('4I', mask
)
2603 t
= struct
.unpack('4I', _target
)
2604 res
= (p
[0] |
(t
[0] & m
[0]),
2605 p
[1] |
(t
[1] & m
[1]),
2606 p
[2] |
(t
[2] & m
[2]),
2607 p
[3] |
(t
[3] & m
[3]))
2608 return socket
.inet_ntop(socket
.AF_INET6
, struct
.pack('4I', *res
))
2610 def build_icmpv6(ipv6_addrs
, type, code
, payload
):
2611 start
= struct
.pack("BB", type, code
)
2613 icmp
= start
+ '\x00\x00' + end
2614 pseudo
= ipv6_addrs
+ struct
.pack(">LBBBB", len(icmp
), 0, 0, 0, 58)
2615 csum
= ip_checksum(pseudo
+ icmp
)
2616 return start
+ csum
+ end
2618 def build_ra(src_ll
, ip_src
, ip_dst
, cur_hop_limit
=0, router_lifetime
=0,
2619 reachable_time
=0, retrans_timer
=0, opt
=None):
2620 link_mc
= binascii
.unhexlify("3333ff000002")
2621 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2623 ehdr
= link_mc
+ _src_ll
+ proto
2624 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2625 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2627 adv
= struct
.pack('>BBHLL', cur_hop_limit
, 0, router_lifetime
,
2628 reachable_time
, retrans_timer
)
2633 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 134, 0, payload
)
2635 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2636 ipv6
+= _ip_src
+ _ip_dst
2638 return ehdr
+ ipv6
+ icmp
2640 def build_ns(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2641 link_mc
= binascii
.unhexlify("3333ff000002")
2642 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2644 ehdr
= link_mc
+ _src_ll
+ proto
2645 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2647 ip_dst
= ipv6_solicited_node_mcaddr(target
)
2648 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2650 reserved
= '\x00\x00\x00\x00'
2651 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2653 payload
= reserved
+ _target
+ opt
2655 payload
= reserved
+ _target
2656 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 135, 0, payload
)
2658 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2659 ipv6
+= _ip_src
+ _ip_dst
2661 return ehdr
+ ipv6
+ icmp
2663 def send_ns(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
2668 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2671 src_ll
= dev
.p2p_interface_addr()
2672 cmd
= "DATA_TEST_FRAME "
2675 opt
= "\x01\x01" + binascii
.unhexlify(src_ll
.replace(':',''))
2677 pkt
= build_ns(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
2679 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2680 raise Exception("DATA_TEST_FRAME failed")
2682 def build_na(src_ll
, ip_src
, ip_dst
, target
, opt
=None):
2683 link_mc
= binascii
.unhexlify("3333ff000002")
2684 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2686 ehdr
= link_mc
+ _src_ll
+ proto
2687 _ip_src
= socket
.inet_pton(socket
.AF_INET6
, ip_src
)
2688 _ip_dst
= socket
.inet_pton(socket
.AF_INET6
, ip_dst
)
2690 reserved
= '\x00\x00\x00\x00'
2691 _target
= socket
.inet_pton(socket
.AF_INET6
, target
)
2693 payload
= reserved
+ _target
+ opt
2695 payload
= reserved
+ _target
2696 icmp
= build_icmpv6(_ip_src
+ _ip_dst
, 136, 0, payload
)
2698 ipv6
= struct
.pack('>BBBBHBB', 0x60, 0, 0, 0, len(icmp
), 58, 255)
2699 ipv6
+= _ip_src
+ _ip_dst
2701 return ehdr
+ ipv6
+ icmp
2703 def send_na(dev
, src_ll
=None, target
=None, ip_src
=None, ip_dst
=None, opt
=None,
2708 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2711 src_ll
= dev
.p2p_interface_addr()
2712 cmd
= "DATA_TEST_FRAME "
2714 pkt
= build_na(src_ll
=src_ll
, ip_src
=ip_src
, ip_dst
=ip_dst
, target
=target
,
2716 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2717 raise Exception("DATA_TEST_FRAME failed")
2719 def build_dhcp_ack(dst_ll
, src_ll
, ip_src
, ip_dst
, yiaddr
, chaddr
,
2720 subnet_mask
="255.255.255.0", truncated_opt
=False,
2721 wrong_magic
=False, force_tot_len
=None, no_dhcp
=False):
2722 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2723 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2725 ehdr
= _dst_ll
+ _src_ll
+ proto
2726 _ip_src
= socket
.inet_pton(socket
.AF_INET
, ip_src
)
2727 _ip_dst
= socket
.inet_pton(socket
.AF_INET
, ip_dst
)
2728 _subnet_mask
= socket
.inet_pton(socket
.AF_INET
, subnet_mask
)
2730 _ciaddr
= '\x00\x00\x00\x00'
2731 _yiaddr
= socket
.inet_pton(socket
.AF_INET
, yiaddr
)
2732 _siaddr
= '\x00\x00\x00\x00'
2733 _giaddr
= '\x00\x00\x00\x00'
2734 _chaddr
= binascii
.unhexlify(chaddr
.replace(':','') + "00000000000000000000")
2735 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2736 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2739 payload
+= '\x63\x82\x53\x00'
2741 payload
+= '\x63\x82\x53\x63'
2743 payload
+= '\x22\xff\x00'
2744 # Option: DHCP Message Type = ACK
2745 payload
+= '\x35\x01\x05'
2748 # Option: Subnet Mask
2749 payload
+= '\x01\x04' + _subnet_mask
2750 # Option: Time Offset
2751 payload
+= struct
.pack('>BBL', 2, 4, 0)
2755 payload
+= '\x00\x00\x00\x00'
2758 payload
= struct
.pack('>BBBBL3BB', 2, 1, 6, 0, 12345, 0, 0, 0, 0)
2759 payload
+= _ciaddr
+ _yiaddr
+ _siaddr
+ _giaddr
+ _chaddr
+ 192*'\x00'
2761 udp
= struct
.pack('>HHHH', 67, 68, 8 + len(payload
), 0) + payload
2764 tot_len
= force_tot_len
2766 tot_len
= 20 + len(udp
)
2767 start
= struct
.pack('>BBHHBBBB', 0x45, 0, tot_len
, 0, 0, 0, 128, 17)
2768 ipv4
= start
+ '\x00\x00' + _ip_src
+ _ip_dst
2769 csum
= ip_checksum(ipv4
)
2770 ipv4
= start
+ csum
+ _ip_src
+ _ip_dst
2772 return ehdr
+ ipv4
+ udp
2774 def build_arp(dst_ll
, src_ll
, opcode
, sender_mac
, sender_ip
,
2775 target_mac
, target_ip
):
2776 _dst_ll
= binascii
.unhexlify(dst_ll
.replace(':',''))
2777 _src_ll
= binascii
.unhexlify(src_ll
.replace(':',''))
2779 ehdr
= _dst_ll
+ _src_ll
+ proto
2781 _sender_mac
= binascii
.unhexlify(sender_mac
.replace(':',''))
2782 _sender_ip
= socket
.inet_pton(socket
.AF_INET
, sender_ip
)
2783 _target_mac
= binascii
.unhexlify(target_mac
.replace(':',''))
2784 _target_ip
= socket
.inet_pton(socket
.AF_INET
, target_ip
)
2786 arp
= struct
.pack('>HHBBH', 1, 0x0800, 6, 4, opcode
)
2787 arp
+= _sender_mac
+ _sender_ip
2788 arp
+= _target_mac
+ _target_ip
2792 def send_arp(dev
, dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=None, opcode
=1,
2793 sender_mac
=None, sender_ip
="0.0.0.0",
2794 target_mac
="00:00:00:00:00:00", target_ip
="0.0.0.0",
2799 if sender_mac
is None:
2800 sender_mac
= hapd_bssid
2801 cmd
= "DATA_TEST_FRAME ifname=ap-br0 "
2804 src_ll
= dev
.p2p_interface_addr()
2805 if sender_mac
is None:
2806 sender_mac
= dev
.p2p_interface_addr()
2807 cmd
= "DATA_TEST_FRAME "
2809 pkt
= build_arp(dst_ll
=dst_ll
, src_ll
=src_ll
, opcode
=opcode
,
2810 sender_mac
=sender_mac
, sender_ip
=sender_ip
,
2811 target_mac
=target_mac
, target_ip
=target_ip
)
2812 if "OK" not in dev
.request(cmd
+ binascii
.hexlify(pkt
)):
2813 raise Exception("DATA_TEST_FRAME failed")
2815 def get_permanent_neighbors(ifname
):
2816 cmd
= subprocess
.Popen(['ip', 'nei'], stdout
=subprocess
.PIPE
)
2817 res
= cmd
.stdout
.read()
2819 return [ line
for line
in res
.splitlines() if "PERMANENT" in line
and ifname
in line
]
2821 def _test_proxyarp_open(dev
, apdev
, params
):
2822 cap_br
= os
.path
.join(params
['logdir'], "proxyarp_open.ap-br0.pcap")
2823 cap_dev0
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[0].ifname
)
2824 cap_dev1
= os
.path
.join(params
['logdir'], "proxyarp_open.%s.pcap" % dev
[1].ifname
)
2826 bssid
= apdev
[0]['bssid']
2827 params
= { 'ssid': 'open' }
2828 params
['proxy_arp'] = '1'
2829 hapd
= hostapd
.add_ap(apdev
[0]['ifname'], params
, no_enable
=True)
2830 hapd
.set("ap_isolate", "1")
2831 hapd
.set('bridge', 'ap-br0')
2836 # For now, do not report failures due to missing kernel support
2837 raise HwsimSkip("Could not start hostapd - assume proxyarp not supported in kernel version")
2838 ev
= hapd
.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout
=10)
2840 raise Exception("AP startup timed out")
2841 if "AP-ENABLED" not in ev
:
2842 raise Exception("AP startup failed")
2844 subprocess
.call(['brctl', 'setfd', 'ap-br0', '0'])
2845 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
2847 for chain
in [ 'FORWARD', 'OUTPUT' ]:
2848 subprocess
.call(['ebtables', '-A', chain
, '-p', 'ARP',
2849 '-d', 'Broadcast', '-o', apdev
[0]['ifname'],
2851 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
2852 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
2853 '--ip6-icmp-type', 'neighbor-solicitation',
2854 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
2855 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
2856 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
2857 '--ip6-icmp-type', 'neighbor-advertisement',
2858 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
2859 subprocess
.call(['ebtables', '-A', chain
,
2860 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
2861 '--ip6-icmp-type', 'router-solicitation',
2862 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
2863 # Multicast Listener Report Message
2864 subprocess
.call(['ebtables', '-A', chain
, '-d', 'Multicast',
2865 '-p', 'IPv6', '--ip6-protocol', 'ipv6-icmp',
2866 '--ip6-icmp-type', '143',
2867 '-o', apdev
[0]['ifname'], '-j', 'DROP'])
2870 cmd
[0] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', 'ap-br0',
2871 '-w', cap_br
, '-s', '2000'],
2872 stderr
=open('/dev/null', 'w'))
2873 cmd
[1] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[0].ifname
,
2874 '-w', cap_dev0
, '-s', '2000'],
2875 stderr
=open('/dev/null', 'w'))
2876 cmd
[2] = subprocess
.Popen(['tcpdump', '-p', '-U', '-i', dev
[1].ifname
,
2877 '-w', cap_dev1
, '-s', '2000'],
2878 stderr
=open('/dev/null', 'w'))
2880 dev
[0].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2881 dev
[1].connect("open", key_mgmt
="NONE", scan_freq
="2412")
2884 addr0
= dev
[0].p2p_interface_addr()
2885 addr1
= dev
[1].p2p_interface_addr()
2887 src_ll_opt0
= "\x01\x01" + binascii
.unhexlify(addr0
.replace(':',''))
2888 src_ll_opt1
= "\x01\x01" + binascii
.unhexlify(addr1
.replace(':',''))
2891 send_ns(dev
[0], ip_src
="::", target
="aaaa:bbbb:cccc::2")
2893 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2")
2894 # test frame without source link-layer address option
2895 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
2897 # test frame with bogus option
2898 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
2899 opt
="\x70\x01\x01\x02\x03\x04\x05\x05")
2900 # test frame with truncated source link-layer address option
2901 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
2902 opt
="\x01\x01\x01\x02\x03\x04")
2903 # test frame with foreign source link-layer address option
2904 send_ns(dev
[0], ip_src
="aaaa:bbbb:cccc::2", target
="aaaa:bbbb:cccc::2",
2905 opt
="\x01\x01\x01\x02\x03\x04\x05\x06")
2907 send_ns(dev
[1], ip_src
="aaaa:bbbb:dddd::2", target
="aaaa:bbbb:dddd::2")
2909 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
2910 # another copy for additional code coverage
2911 send_ns(dev
[1], ip_src
="aaaa:bbbb:eeee::2", target
="aaaa:bbbb:eeee::2")
2913 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2914 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2915 yiaddr
="192.168.1.124", chaddr
=addr0
)
2916 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2917 raise Exception("DATA_TEST_FRAME failed")
2918 # Change address and verify unicast
2919 pkt
= build_dhcp_ack(dst_ll
=addr0
, src_ll
=bssid
,
2920 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2921 yiaddr
="192.168.1.123", chaddr
=addr0
)
2922 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2923 raise Exception("DATA_TEST_FRAME failed")
2925 # Not-associated client MAC address
2926 pkt
= build_dhcp_ack(dst_ll
="ff:ff:ff:ff:ff:ff", src_ll
=bssid
,
2927 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2928 yiaddr
="192.168.1.125", chaddr
="22:33:44:55:66:77")
2929 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2930 raise Exception("DATA_TEST_FRAME failed")
2933 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2934 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2935 yiaddr
="0.0.0.0", chaddr
=addr1
)
2936 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2937 raise Exception("DATA_TEST_FRAME failed")
2940 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2941 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2942 yiaddr
="192.168.1.126", chaddr
=addr1
,
2943 subnet_mask
="0.0.0.0")
2944 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2945 raise Exception("DATA_TEST_FRAME failed")
2948 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2949 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2950 yiaddr
="192.168.1.127", chaddr
=addr1
,
2952 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2953 raise Exception("DATA_TEST_FRAME failed")
2956 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2957 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2958 yiaddr
="192.168.1.128", chaddr
=addr1
,
2960 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2961 raise Exception("DATA_TEST_FRAME failed")
2963 # Wrong IPv4 total length
2964 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2965 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2966 yiaddr
="192.168.1.129", chaddr
=addr1
,
2968 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2969 raise Exception("DATA_TEST_FRAME failed")
2972 pkt
= build_dhcp_ack(dst_ll
=addr1
, src_ll
=bssid
,
2973 ip_src
="192.168.1.1", ip_dst
="255.255.255.255",
2974 yiaddr
="192.168.1.129", chaddr
=addr1
,
2976 if "OK" not in hapd
.request("DATA_TEST_FRAME ifname=ap-br0 " + binascii
.hexlify(pkt
)):
2977 raise Exception("DATA_TEST_FRAME failed")
2979 matches
= get_permanent_neighbors("ap-br0")
2980 logger
.info("After connect: " + str(matches
))
2981 if len(matches
) != 4:
2982 raise Exception("Unexpected number of neighbor entries after connect")
2983 if 'aaaa:bbbb:cccc::2 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2984 raise Exception("dev0 addr missing")
2985 if 'aaaa:bbbb:dddd::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2986 raise Exception("dev1 addr(1) missing")
2987 if 'aaaa:bbbb:eeee::2 dev ap-br0 lladdr 02:00:00:00:01:00 PERMANENT' not in matches
:
2988 raise Exception("dev1 addr(2) missing")
2989 if '192.168.1.123 dev ap-br0 lladdr 02:00:00:00:00:00 PERMANENT' not in matches
:
2990 raise Exception("dev0 IPv4 addr missing")
2992 targets
= [ "192.168.1.123", "192.168.1.124", "192.168.1.125",
2994 for target
in targets
:
2995 send_arp(dev
[1], sender_ip
="192.168.1.100", target_ip
=target
)
2997 for target
in targets
:
2998 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.101",
3001 # ARP Probe from wireless STA
3002 send_arp(dev
[1], target_ip
="192.168.1.127")
3003 # ARP Announcement from wireless STA
3004 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127")
3005 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.127",
3008 matches
= get_permanent_neighbors("ap-br0")
3009 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3011 # ARP Request for the newly introduced IP address from wireless STA
3012 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3014 # ARP Request for the newly introduced IP address from bridge
3015 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3016 target_ip
="192.168.1.127")
3018 # ARP Probe from bridge
3019 send_arp(hapd
, hapd_bssid
=bssid
, target_ip
="192.168.1.130")
3020 # ARP Announcement from bridge (not to be learned by AP for proxyarp)
3021 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3022 target_ip
="192.168.1.130")
3023 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.130",
3024 target_ip
="192.168.1.130", opcode
=2)
3026 matches
= get_permanent_neighbors("ap-br0")
3027 logger
.info("After ARP Probe + Announcement: " + str(matches
))
3029 # ARP Request for the newly introduced IP address from wireless STA
3030 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.130")
3031 # ARP Response from bridge (AP does not proxy for non-wireless devices)
3032 send_arp(hapd
, hapd_bssid
=bssid
, dst_ll
=addr0
, sender_ip
="192.168.1.130",
3033 target_ip
="192.168.1.123", opcode
=2)
3035 # ARP Request for the newly introduced IP address from bridge
3036 send_arp(hapd
, hapd_bssid
=bssid
, sender_ip
="192.168.1.102",
3037 target_ip
="192.168.1.130")
3039 # ARP Probe from wireless STA (duplicate address; learned through DHCP)
3040 send_arp(dev
[1], target_ip
="192.168.1.123")
3041 # ARP Probe from wireless STA (duplicate address; learned through ARP)
3042 send_arp(dev
[0], target_ip
="192.168.1.127")
3044 # Gratuitous ARP Reply for another STA's IP address
3045 send_arp(dev
[0], opcode
=2, sender_mac
=addr0
, sender_ip
="192.168.1.127",
3046 target_mac
=addr1
, target_ip
="192.168.1.127")
3047 send_arp(dev
[1], opcode
=2, sender_mac
=addr1
, sender_ip
="192.168.1.123",
3048 target_mac
=addr0
, target_ip
="192.168.1.123")
3049 # ARP Request to verify previous mapping
3050 send_arp(dev
[1], sender_ip
="192.168.1.127", target_ip
="192.168.1.123")
3051 send_arp(dev
[0], sender_ip
="192.168.1.123", target_ip
="192.168.1.127")
3055 send_ns(dev
[0], target
="aaaa:bbbb:dddd::2", ip_src
="aaaa:bbbb:cccc::2")
3057 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="aaaa:bbbb:dddd::2")
3059 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:dddd::2",
3060 ip_src
="aaaa:bbbb:ffff::2")
3063 # Try to probe for an already assigned address
3064 send_ns(dev
[1], target
="aaaa:bbbb:cccc::2", ip_src
="::")
3066 send_ns(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc::2", ip_src
="::")
3070 send_na(dev
[1], target
="aaaa:bbbb:cccc:aeae::3",
3071 ip_src
="aaaa:bbbb:cccc:aeae::3", ip_dst
="ff02::1")
3072 send_na(hapd
, hapd_bssid
=bssid
, target
="aaaa:bbbb:cccc:aeae::4",
3073 ip_src
="aaaa:bbbb:cccc:aeae::4", ip_dst
="ff02::1")
3075 hwsim_utils
.test_connectivity_iface(dev
[0], hapd
, "ap-br0")
3076 hwsim_utils
.test_connectivity_iface(dev
[1], hapd
, "ap-br0")
3077 hwsim_utils
.test_connectivity(dev
[0], dev
[1])
3079 dev
[0].request("DISCONNECT")
3080 dev
[1].request("DISCONNECT")
3084 matches
= get_permanent_neighbors("ap-br0")
3085 logger
.info("After disconnect: " + str(matches
))
3086 if len(matches
) > 0:
3087 raise Exception("Unexpected neighbor entries after disconnect")
3088 cmd
= subprocess
.Popen(['ebtables', '-L', '--Lc'], stdout
=subprocess
.PIPE
)
3089 res
= cmd
.stdout
.read()
3091 logger
.info("ebtables results:\n" + res
)
3093 def test_proxyarp_open(dev
, apdev
, params
):
3094 """ProxyARP with open network"""
3096 _test_proxyarp_open(dev
, apdev
, params
)
3099 subprocess
.call(['ebtables', '-F', 'FORWARD'])
3100 subprocess
.call(['ebtables', '-F', 'OUTPUT'])
3103 subprocess
.call(['ip', 'link', 'set', 'dev', 'ap-br0', 'down'],
3104 stderr
=open('/dev/null', 'w'))
3105 subprocess
.call(['brctl', 'delbr', 'ap-br0'],
3106 stderr
=open('/dev/null', 'w'))