Interworking: Add support for home vs. visited SP determination
Use Domain Name List (ANQP) and the new home_domain configuration parameter to figure out whether a network is operated by the home service provider and if so, prefer it over networks that would require roaming. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
95bc2ea63d
commit
00bf219ddb
3 changed files with 62 additions and 5 deletions
|
@ -1825,6 +1825,7 @@ void wpa_config_free(struct wpa_config *config)
|
||||||
os_free(config->home_ca_cert);
|
os_free(config->home_ca_cert);
|
||||||
os_free(config->home_imsi);
|
os_free(config->home_imsi);
|
||||||
os_free(config->home_milenage);
|
os_free(config->home_milenage);
|
||||||
|
os_free(config->home_domain);
|
||||||
os_free(config);
|
os_free(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2594,6 +2595,7 @@ static const struct global_parse_data global_fields[] = {
|
||||||
{ STR(home_ca_cert), 0 },
|
{ STR(home_ca_cert), 0 },
|
||||||
{ STR(home_imsi), 0 },
|
{ STR(home_imsi), 0 },
|
||||||
{ STR(home_milenage), 0 },
|
{ STR(home_milenage), 0 },
|
||||||
|
{ STR(home_domain), 0 },
|
||||||
{ INT_RANGE(interworking, 0, 1), 0 },
|
{ INT_RANGE(interworking, 0, 1), 0 },
|
||||||
{ FUNC(hessid), 0 },
|
{ FUNC(hessid), 0 },
|
||||||
{ INT_RANGE(access_network_type, 0, 15), 0 }
|
{ INT_RANGE(access_network_type, 0, 15), 0 }
|
||||||
|
|
|
@ -478,6 +478,14 @@ struct wpa_config {
|
||||||
* <Ki>:<OPc>:<SQN> format
|
* <Ki>:<OPc>:<SQN> format
|
||||||
*/
|
*/
|
||||||
char *home_milenage;
|
char *home_milenage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* home_domain - Home service provider FQDN
|
||||||
|
*
|
||||||
|
* This is used to compare against the Domain Name List to figure out
|
||||||
|
* whether the AP is operated by the Home SP.
|
||||||
|
*/
|
||||||
|
char *home_domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -830,10 +830,41 @@ static int interworking_credentials_available(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int interworking_home_sp(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpabuf *domain_names)
|
||||||
|
{
|
||||||
|
const u8 *pos, *end;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (wpa_s->conf->home_domain == NULL || domain_names == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
len = os_strlen(wpa_s->conf->home_domain);
|
||||||
|
pos = wpabuf_head(domain_names);
|
||||||
|
end = pos + wpabuf_len(domain_names);
|
||||||
|
|
||||||
|
while (pos + 1 < end) {
|
||||||
|
if (pos + 1 + pos[0] > end)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (pos[0] == len &&
|
||||||
|
os_strncasecmp(wpa_s->conf->home_domain,
|
||||||
|
(const char *) (pos + 1), len) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
pos += 1 + pos[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void interworking_select_network(struct wpa_supplicant *wpa_s)
|
static void interworking_select_network(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wpa_bss *bss, *selected = NULL;
|
struct wpa_bss *bss, *selected = NULL, *selected_home = NULL;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
const char *type;
|
||||||
|
int res;
|
||||||
|
|
||||||
wpa_s->network_select = 0;
|
wpa_s->network_select = 0;
|
||||||
|
|
||||||
|
@ -841,10 +872,26 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
|
||||||
if (!interworking_credentials_available(wpa_s, bss))
|
if (!interworking_credentials_available(wpa_s, bss))
|
||||||
continue;
|
continue;
|
||||||
count++;
|
count++;
|
||||||
wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR,
|
res = interworking_home_sp(wpa_s, bss->anqp_domain_name);
|
||||||
MAC2STR(bss->bssid));
|
if (res > 0)
|
||||||
if (selected == NULL && wpa_s->auto_select)
|
type = "home";
|
||||||
selected = bss;
|
else if (res == 0)
|
||||||
|
type = "roaming";
|
||||||
|
else
|
||||||
|
type = "unknown";
|
||||||
|
wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR " type=%s",
|
||||||
|
MAC2STR(bss->bssid), type);
|
||||||
|
if (wpa_s->auto_select) {
|
||||||
|
if (selected == NULL)
|
||||||
|
selected = bss;
|
||||||
|
if (selected_home == NULL && res > 0)
|
||||||
|
selected_home = bss;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected_home && selected_home != selected) {
|
||||||
|
/* Prefer network operated by the Home SP */
|
||||||
|
selected = selected_home;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue