diff options
author | Jouni Malinen <jouni@qca.qualcomm.com> | 2012-02-16 16:32:00 +0200 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2012-02-16 16:32:00 +0200 |
commit | 00bf219ddbc48343a5b26d229ef3ba4852f4735d (patch) | |
tree | 2968d6d2838b0e77ada6b425cf8dcf05244e4030 | |
parent | 95bc2ea63dafc5c4bfa0e439e710324df0fbbbb8 (diff) | |
download | external_wpa_supplicant_8_ti-00bf219ddbc48343a5b26d229ef3ba4852f4735d.zip external_wpa_supplicant_8_ti-00bf219ddbc48343a5b26d229ef3ba4852f4735d.tar.gz external_wpa_supplicant_8_ti-00bf219ddbc48343a5b26d229ef3ba4852f4735d.tar.bz2 |
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>
-rw-r--r-- | wpa_supplicant/config.c | 2 | ||||
-rw-r--r-- | wpa_supplicant/config.h | 8 | ||||
-rw-r--r-- | wpa_supplicant/interworking.c | 57 |
3 files changed, 62 insertions, 5 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index a7c1784..5910b5d 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1825,6 +1825,7 @@ void wpa_config_free(struct wpa_config *config) os_free(config->home_ca_cert); os_free(config->home_imsi); os_free(config->home_milenage); + os_free(config->home_domain); os_free(config); } @@ -2594,6 +2595,7 @@ static const struct global_parse_data global_fields[] = { { STR(home_ca_cert), 0 }, { STR(home_imsi), 0 }, { STR(home_milenage), 0 }, + { STR(home_domain), 0 }, { INT_RANGE(interworking, 0, 1), 0 }, { FUNC(hessid), 0 }, { INT_RANGE(access_network_type, 0, 15), 0 } diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index a62f288..380bfbb 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -478,6 +478,14 @@ struct wpa_config { * <Ki>:<OPc>:<SQN> format */ 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; }; diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 56dd5b1..572e2ed 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -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) { - struct wpa_bss *bss, *selected = NULL; + struct wpa_bss *bss, *selected = NULL, *selected_home = NULL; unsigned int count = 0; + const char *type; + int res; 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)) continue; count++; - wpa_msg(wpa_s, MSG_INFO, INTERWORKING_AP MACSTR, - MAC2STR(bss->bssid)); - if (selected == NULL && wpa_s->auto_select) - selected = bss; + res = interworking_home_sp(wpa_s, bss->anqp_domain_name); + if (res > 0) + type = "home"; + 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) { |