Interworking: Move BSS ANQP information into separate struct

This is an initial step in allowing the ANQP responses to be shared
among multiple BSSes if the BSSes are determined to be operating under
identical configuration.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2012-09-04 16:02:29 +03:00 committed by Jouni Malinen
parent 59ff6653aa
commit 476aed355a
5 changed files with 138 additions and 86 deletions

View file

@ -35,6 +35,48 @@
#define WPA_BSS_IES_CHANGED_FLAG BIT(8) #define WPA_BSS_IES_CHANGED_FLAG BIT(8)
struct wpa_bss_anqp * wpa_bss_anqp_alloc(void)
{
struct wpa_bss_anqp *anqp;
anqp = os_zalloc(sizeof(*anqp));
if (anqp == NULL)
return NULL;
anqp->users = 1;
return anqp;
}
static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp)
{
if (anqp == NULL)
return;
anqp->users--;
if (anqp->users > 0) {
/* Another BSS entry holds a pointer to this ANQP info */
return;
}
#ifdef CONFIG_INTERWORKING
wpabuf_free(anqp->venue_name);
wpabuf_free(anqp->network_auth_type);
wpabuf_free(anqp->roaming_consortium);
wpabuf_free(anqp->ip_addr_type_availability);
wpabuf_free(anqp->nai_realm);
wpabuf_free(anqp->anqp_3gpp);
wpabuf_free(anqp->domain_name);
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20
wpabuf_free(anqp->hs20_operator_friendly_name);
wpabuf_free(anqp->hs20_wan_metrics);
wpabuf_free(anqp->hs20_connection_capability);
wpabuf_free(anqp->hs20_operating_class);
#endif /* CONFIG_HS20 */
os_free(anqp);
}
static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
const char *reason) const char *reason)
{ {
@ -58,21 +100,7 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
" SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid), " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
wpa_ssid_txt(bss->ssid, bss->ssid_len), reason); wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id); wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
#ifdef CONFIG_INTERWORKING wpa_bss_anqp_free(bss->anqp);
wpabuf_free(bss->anqp_venue_name);
wpabuf_free(bss->anqp_network_auth_type);
wpabuf_free(bss->anqp_roaming_consortium);
wpabuf_free(bss->anqp_ip_addr_type_availability);
wpabuf_free(bss->anqp_nai_realm);
wpabuf_free(bss->anqp_3gpp);
wpabuf_free(bss->anqp_domain_name);
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20
wpabuf_free(bss->hs20_operator_friendly_name);
wpabuf_free(bss->hs20_wan_metrics);
wpabuf_free(bss->hs20_connection_capability);
wpabuf_free(bss->hs20_operating_class);
#endif /* CONFIG_HS20 */
os_free(bss); os_free(bss);
} }

View file

@ -19,6 +19,25 @@ struct wpa_scan_res;
#define WPA_BSS_ASSOCIATED BIT(5) #define WPA_BSS_ASSOCIATED BIT(5)
#define WPA_BSS_ANQP_FETCH_TRIED BIT(6) #define WPA_BSS_ANQP_FETCH_TRIED BIT(6)
struct wpa_bss_anqp {
unsigned int users;
#ifdef CONFIG_INTERWORKING
struct wpabuf *venue_name;
struct wpabuf *network_auth_type;
struct wpabuf *roaming_consortium;
struct wpabuf *ip_addr_type_availability;
struct wpabuf *nai_realm;
struct wpabuf *anqp_3gpp;
struct wpabuf *domain_name;
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20
struct wpabuf *hs20_operator_friendly_name;
struct wpabuf *hs20_wan_metrics;
struct wpabuf *hs20_connection_capability;
struct wpabuf *hs20_operating_class;
#endif /* CONFIG_HS20 */
};
/** /**
* struct wpa_bss - BSS table * struct wpa_bss - BSS table
* @list: List entry for struct wpa_supplicant::bss * @list: List entry for struct wpa_supplicant::bss
@ -60,21 +79,7 @@ struct wpa_bss {
int level; int level;
u64 tsf; u64 tsf;
struct os_time last_update; struct os_time last_update;
#ifdef CONFIG_INTERWORKING struct wpa_bss_anqp *anqp;
struct wpabuf *anqp_venue_name;
struct wpabuf *anqp_network_auth_type;
struct wpabuf *anqp_roaming_consortium;
struct wpabuf *anqp_ip_addr_type_availability;
struct wpabuf *anqp_nai_realm;
struct wpabuf *anqp_3gpp;
struct wpabuf *anqp_domain_name;
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20
struct wpabuf *hs20_operator_friendly_name;
struct wpabuf *hs20_wan_metrics;
struct wpabuf *hs20_connection_capability;
struct wpabuf *hs20_operating_class;
#endif /* CONFIG_HS20 */
size_t ie_len; size_t ie_len;
size_t beacon_ie_len; size_t beacon_ie_len;
/* followed by ie_len octets of IEs */ /* followed by ie_len octets of IEs */
@ -105,5 +110,6 @@ struct wpabuf * wpa_bss_get_vendor_ie_multi_beacon(const struct wpa_bss *bss,
u32 vendor_type); u32 vendor_type);
int wpa_bss_get_max_rate(const struct wpa_bss *bss); int wpa_bss_get_max_rate(const struct wpa_bss *bss);
int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates); int wpa_bss_get_bit_rates(const struct wpa_bss *bss, u8 **rates);
struct wpa_bss_anqp * wpa_bss_anqp_alloc(void);
#endif /* BSS_H */ #endif /* BSS_H */

View file

@ -2772,27 +2772,28 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
#endif /* CONFIG_WIFI_DISPLAY */ #endif /* CONFIG_WIFI_DISPLAY */
#ifdef CONFIG_INTERWORKING #ifdef CONFIG_INTERWORKING
if (mask & WPA_BSS_MASK_INTERNETW) { if ((mask & WPA_BSS_MASK_INTERNETW) && bss->anqp) {
struct wpa_bss_anqp *anqp = bss->anqp;
pos = anqp_add_hex(pos, end, "anqp_venue_name", pos = anqp_add_hex(pos, end, "anqp_venue_name",
bss->anqp_venue_name); anqp->venue_name);
pos = anqp_add_hex(pos, end, "anqp_network_auth_type", pos = anqp_add_hex(pos, end, "anqp_network_auth_type",
bss->anqp_network_auth_type); anqp->network_auth_type);
pos = anqp_add_hex(pos, end, "anqp_roaming_consortium", pos = anqp_add_hex(pos, end, "anqp_roaming_consortium",
bss->anqp_roaming_consortium); anqp->roaming_consortium);
pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability", pos = anqp_add_hex(pos, end, "anqp_ip_addr_type_availability",
bss->anqp_ip_addr_type_availability); anqp->ip_addr_type_availability);
pos = anqp_add_hex(pos, end, "anqp_nai_realm", pos = anqp_add_hex(pos, end, "anqp_nai_realm",
bss->anqp_nai_realm); anqp->nai_realm);
pos = anqp_add_hex(pos, end, "anqp_3gpp", bss->anqp_3gpp); pos = anqp_add_hex(pos, end, "anqp_3gpp", anqp->anqp_3gpp);
pos = anqp_add_hex(pos, end, "anqp_domain_name", pos = anqp_add_hex(pos, end, "anqp_domain_name",
bss->anqp_domain_name); anqp->domain_name);
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name", pos = anqp_add_hex(pos, end, "hs20_operator_friendly_name",
bss->hs20_operator_friendly_name); anqp->hs20_operator_friendly_name);
pos = anqp_add_hex(pos, end, "hs20_wan_metrics", pos = anqp_add_hex(pos, end, "hs20_wan_metrics",
bss->hs20_wan_metrics); anqp->hs20_wan_metrics);
pos = anqp_add_hex(pos, end, "hs20_connection_capability", pos = anqp_add_hex(pos, end, "hs20_connection_capability",
bss->hs20_connection_capability); anqp->hs20_connection_capability);
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
} }
#endif /* CONFIG_INTERWORKING */ #endif /* CONFIG_INTERWORKING */

View file

@ -110,10 +110,14 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
const u8 *pos = data; const u8 *pos = data;
u8 subtype; u8 subtype;
struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa); struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
struct wpa_bss_anqp *anqp = NULL;
if (slen < 2) if (slen < 2)
return; return;
if (bss)
anqp = bss->anqp;
subtype = *pos++; subtype = *pos++;
slen--; slen--;
@ -130,9 +134,9 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
" Operator Friendly Name", MAC2STR(sa)); " Operator Friendly Name", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->hs20_operator_friendly_name); wpabuf_free(anqp->hs20_operator_friendly_name);
bss->hs20_operator_friendly_name = anqp->hs20_operator_friendly_name =
wpabuf_alloc_copy(pos, slen); wpabuf_alloc_copy(pos, slen);
} }
break; break;
@ -140,18 +144,18 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
" WAN Metrics", MAC2STR(sa)); " WAN Metrics", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "WAN Metrics", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "WAN Metrics", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->hs20_wan_metrics); wpabuf_free(anqp->hs20_wan_metrics);
bss->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen); anqp->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen);
} }
break; break;
case HS20_STYPE_CONNECTION_CAPABILITY: case HS20_STYPE_CONNECTION_CAPABILITY:
wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
" Connection Capability", MAC2STR(sa)); " Connection Capability", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->hs20_connection_capability); wpabuf_free(anqp->hs20_connection_capability);
bss->hs20_connection_capability = anqp->hs20_connection_capability =
wpabuf_alloc_copy(pos, slen); wpabuf_alloc_copy(pos, slen);
} }
break; break;
@ -159,9 +163,9 @@ void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-HS20-ANQP " MACSTR
" Operating Class", MAC2STR(sa)); " Operating Class", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->hs20_operating_class); wpabuf_free(anqp->hs20_operating_class);
bss->hs20_operating_class = anqp->hs20_operating_class =
wpabuf_alloc_copy(pos, slen); wpabuf_alloc_copy(pos, slen);
} }
break; break;

View file

@ -737,7 +737,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
const u8 *ie; const u8 *ie;
if (bss->anqp_3gpp == NULL) if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL)
return -1; return -1;
for (cred = wpa_s->conf->cred; cred; cred = cred->next) { for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
@ -768,7 +768,7 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
#ifdef PCSC_FUNCS #ifdef PCSC_FUNCS
compare: compare:
#endif /* PCSC_FUNCS */ #endif /* PCSC_FUNCS */
if (plmn_id_match(bss->anqp_3gpp, imsi, mnc_len)) if (plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len))
break; break;
} }
if (cred == NULL) if (cred == NULL)
@ -923,7 +923,8 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium(
ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM); ie = wpa_bss_get_ie(bss, WLAN_EID_ROAMING_CONSORTIUM);
if (ie == NULL && bss->anqp_roaming_consortium == NULL) if (ie == NULL &&
(bss->anqp == NULL || bss->anqp->roaming_consortium == NULL))
return NULL; return NULL;
if (wpa_s->conf->cred == NULL) if (wpa_s->conf->cred == NULL)
@ -933,7 +934,10 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium(
if (cred->roaming_consortium_len == 0) if (cred->roaming_consortium_len == 0)
continue; continue;
if (!roaming_consortium_match(ie, bss->anqp_roaming_consortium, if (!roaming_consortium_match(ie,
bss->anqp ?
bss->anqp->roaming_consortium :
NULL,
cred->roaming_consortium, cred->roaming_consortium,
cred->roaming_consortium_len)) cred->roaming_consortium_len))
continue; continue;
@ -1123,7 +1127,8 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
return interworking_connect_roaming_consortium(wpa_s, cred, return interworking_connect_roaming_consortium(wpa_s, cred,
bss, ie); bss, ie);
realm = nai_realm_parse(bss->anqp_nai_realm, &count); realm = nai_realm_parse(bss->anqp ? bss->anqp->nai_realm : NULL,
&count);
if (realm == NULL) { if (realm == NULL) {
wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI " wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
"Realm list from " MACSTR, MAC2STR(bss->bssid)); "Realm list from " MACSTR, MAC2STR(bss->bssid));
@ -1250,7 +1255,7 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
int ret; int ret;
#ifdef INTERWORKING_3GPP #ifdef INTERWORKING_3GPP
if (bss->anqp_3gpp == NULL) if (bss->anqp == NULL || bss->anqp->anqp_3gpp == NULL)
return NULL; return NULL;
for (cred = wpa_s->conf->cred; cred; cred = cred->next) { for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
@ -1283,7 +1288,7 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
#endif /* PCSC_FUNCS */ #endif /* PCSC_FUNCS */
wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from " wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from "
MACSTR, MAC2STR(bss->bssid)); MACSTR, MAC2STR(bss->bssid));
ret = plmn_id_match(bss->anqp_3gpp, imsi, mnc_len); ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not "); wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
if (ret) { if (ret) {
if (selected == NULL || if (selected == NULL ||
@ -1303,7 +1308,7 @@ static struct wpa_cred * interworking_credentials_available_realm(
struct nai_realm *realm; struct nai_realm *realm;
u16 count, i; u16 count, i;
if (bss->anqp_nai_realm == NULL) if (bss->anqp == NULL || bss->anqp->nai_realm == NULL)
return NULL; return NULL;
if (wpa_s->conf->cred == NULL) if (wpa_s->conf->cred == NULL)
@ -1311,7 +1316,7 @@ static struct wpa_cred * interworking_credentials_available_realm(
wpa_printf(MSG_DEBUG, "Interworking: Parsing NAI Realm list from " wpa_printf(MSG_DEBUG, "Interworking: Parsing NAI Realm list from "
MACSTR, MAC2STR(bss->bssid)); MACSTR, MAC2STR(bss->bssid));
realm = nai_realm_parse(bss->anqp_nai_realm, &count); realm = nai_realm_parse(bss->anqp->nai_realm, &count);
if (realm == NULL) { if (realm == NULL) {
wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI " wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
"Realm list from " MACSTR, MAC2STR(bss->bssid)); "Realm list from " MACSTR, MAC2STR(bss->bssid));
@ -1492,7 +1497,8 @@ static void interworking_select_network(struct wpa_supplicant *wpa_s)
continue; continue;
} }
count++; count++;
res = interworking_home_sp(wpa_s, bss->anqp_domain_name); res = interworking_home_sp(wpa_s, bss->anqp ?
bss->anqp->domain_name : NULL);
if (res > 0) if (res > 0)
type = "home"; type = "home";
else if (res == 0) else if (res == 0)
@ -1572,6 +1578,11 @@ static void interworking_next_anqp_fetch(struct wpa_supplicant *wpa_s)
continue; /* AP does not support Interworking */ continue; /* AP does not support Interworking */
if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) { if (!(bss->flags & WPA_BSS_ANQP_FETCH_TRIED)) {
if (bss->anqp == NULL) {
bss->anqp = wpa_bss_anqp_alloc();
if (bss->anqp == NULL)
break;
}
found++; found++;
bss->flags |= WPA_BSS_ANQP_FETCH_TRIED; bss->flags |= WPA_BSS_ANQP_FETCH_TRIED;
wpa_msg(wpa_s, MSG_INFO, "Starting ANQP fetch for " wpa_msg(wpa_s, MSG_INFO, "Starting ANQP fetch for "
@ -1667,10 +1678,14 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
{ {
const u8 *pos = data; const u8 *pos = data;
struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa); struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, sa);
struct wpa_bss_anqp *anqp = NULL;
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
u8 type; u8 type;
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
if (bss)
anqp = bss->anqp;
switch (info_id) { switch (info_id) {
case ANQP_CAPABILITY_LIST: case ANQP_CAPABILITY_LIST:
wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
@ -1680,9 +1695,9 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
" Venue Name", MAC2STR(sa)); " Venue Name", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Venue Name", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Venue Name", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_venue_name); wpabuf_free(anqp->venue_name);
bss->anqp_venue_name = wpabuf_alloc_copy(pos, slen); anqp->venue_name = wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_NETWORK_AUTH_TYPE: case ANQP_NETWORK_AUTH_TYPE:
@ -1691,10 +1706,9 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
MAC2STR(sa)); MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Network Authentication " wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Network Authentication "
"Type", pos, slen); "Type", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_network_auth_type); wpabuf_free(anqp->network_auth_type);
bss->anqp_network_auth_type = anqp->network_auth_type = wpabuf_alloc_copy(pos, slen);
wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_ROAMING_CONSORTIUM: case ANQP_ROAMING_CONSORTIUM:
@ -1702,10 +1716,9 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
" Roaming Consortium list", MAC2STR(sa)); " Roaming Consortium list", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Roaming Consortium", wpa_hexdump_ascii(MSG_DEBUG, "ANQP: Roaming Consortium",
pos, slen); pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_roaming_consortium); wpabuf_free(anqp->roaming_consortium);
bss->anqp_roaming_consortium = anqp->roaming_consortium = wpabuf_alloc_copy(pos, slen);
wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_IP_ADDR_TYPE_AVAILABILITY: case ANQP_IP_ADDR_TYPE_AVAILABILITY:
@ -1714,9 +1727,9 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
MAC2STR(sa)); MAC2STR(sa));
wpa_hexdump(MSG_MSGDUMP, "ANQP: IP Address Availability", wpa_hexdump(MSG_MSGDUMP, "ANQP: IP Address Availability",
pos, slen); pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_ip_addr_type_availability); wpabuf_free(anqp->ip_addr_type_availability);
bss->anqp_ip_addr_type_availability = anqp->ip_addr_type_availability =
wpabuf_alloc_copy(pos, slen); wpabuf_alloc_copy(pos, slen);
} }
break; break;
@ -1724,9 +1737,9 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
" NAI Realm list", MAC2STR(sa)); " NAI Realm list", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "ANQP: NAI Realm", pos, slen); wpa_hexdump_ascii(MSG_DEBUG, "ANQP: NAI Realm", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_nai_realm); wpabuf_free(anqp->nai_realm);
bss->anqp_nai_realm = wpabuf_alloc_copy(pos, slen); anqp->nai_realm = wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_3GPP_CELLULAR_NETWORK: case ANQP_3GPP_CELLULAR_NETWORK:
@ -1734,18 +1747,18 @@ static void interworking_parse_rx_anqp_resp(struct wpa_supplicant *wpa_s,
" 3GPP Cellular Network information", MAC2STR(sa)); " 3GPP Cellular Network information", MAC2STR(sa));
wpa_hexdump_ascii(MSG_DEBUG, "ANQP: 3GPP Cellular Network", wpa_hexdump_ascii(MSG_DEBUG, "ANQP: 3GPP Cellular Network",
pos, slen); pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_3gpp); wpabuf_free(anqp->anqp_3gpp);
bss->anqp_3gpp = wpabuf_alloc_copy(pos, slen); anqp->anqp_3gpp = wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_DOMAIN_NAME: case ANQP_DOMAIN_NAME:
wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR wpa_msg(wpa_s, MSG_INFO, "RX-ANQP " MACSTR
" Domain Name list", MAC2STR(sa)); " Domain Name list", MAC2STR(sa));
wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: Domain Name", pos, slen); wpa_hexdump_ascii(MSG_MSGDUMP, "ANQP: Domain Name", pos, slen);
if (bss) { if (anqp) {
wpabuf_free(bss->anqp_domain_name); wpabuf_free(anqp->domain_name);
bss->anqp_domain_name = wpabuf_alloc_copy(pos, slen); anqp->domain_name = wpabuf_alloc_copy(pos, slen);
} }
break; break;
case ANQP_VENDOR_SPECIFIC: case ANQP_VENDOR_SPECIFIC: