diff options
Diffstat (limited to 'src/ap/gas_serv.c')
-rw-r--r-- | src/ap/gas_serv.c | 297 |
1 files changed, 261 insertions, 36 deletions
diff --git a/src/ap/gas_serv.c b/src/ap/gas_serv.c index 9d19f98d0b7c7..6ce178de3b294 100644 --- a/src/ap/gas_serv.c +++ b/src/ap/gas_serv.c @@ -101,6 +101,7 @@ gas_serv_dialog_find(struct hostapd_data *hapd, const u8 *addr, if (sta->gas_dialog[i].dialog_token != dialog_token || !sta->gas_dialog[i].valid) continue; + ap_sta_replenish_timeout(hapd, sta, 5); return &sta->gas_dialog[i]; } wpa_printf(MSG_DEBUG, "ANQP: Could not find dialog for " @@ -167,27 +168,107 @@ static void anqp_add_hs_capab_list(struct hostapd_data *hapd, #endif /* CONFIG_HS20 */ +static struct anqp_element * get_anqp_elem(struct hostapd_data *hapd, + u16 infoid) +{ + struct anqp_element *elem; + + dl_list_for_each(elem, &hapd->conf->anqp_elem, struct anqp_element, + list) { + if (elem->infoid == infoid) + return elem; + } + + return NULL; +} + + +static void anqp_add_elem(struct hostapd_data *hapd, struct wpabuf *buf, + u16 infoid) +{ + struct anqp_element *elem; + + elem = get_anqp_elem(hapd, infoid); + if (!elem) + return; + if (wpabuf_tailroom(buf) < 2 + 2 + wpabuf_len(elem->payload)) { + wpa_printf(MSG_DEBUG, "ANQP: No room for InfoID %u payload", + infoid); + return; + } + + wpabuf_put_le16(buf, infoid); + wpabuf_put_le16(buf, wpabuf_len(elem->payload)); + wpabuf_put_buf(buf, elem->payload); +} + + +static int anqp_add_override(struct hostapd_data *hapd, struct wpabuf *buf, + u16 infoid) +{ + if (get_anqp_elem(hapd, infoid)) { + anqp_add_elem(hapd, buf, infoid); + return 1; + } + + return 0; +} + + static void anqp_add_capab_list(struct hostapd_data *hapd, struct wpabuf *buf) { u8 *len; + u16 id; + + if (anqp_add_override(hapd, buf, ANQP_CAPABILITY_LIST)) + return; len = gas_anqp_add_element(buf, ANQP_CAPABILITY_LIST); wpabuf_put_le16(buf, ANQP_CAPABILITY_LIST); - if (hapd->conf->venue_name) + if (hapd->conf->venue_name || get_anqp_elem(hapd, ANQP_VENUE_NAME)) wpabuf_put_le16(buf, ANQP_VENUE_NAME); - if (hapd->conf->network_auth_type) + if (get_anqp_elem(hapd, ANQP_EMERGENCY_CALL_NUMBER)) + wpabuf_put_le16(buf, ANQP_EMERGENCY_CALL_NUMBER); + if (hapd->conf->network_auth_type || + get_anqp_elem(hapd, ANQP_NETWORK_AUTH_TYPE)) wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE); - if (hapd->conf->roaming_consortium) + if (hapd->conf->roaming_consortium || + get_anqp_elem(hapd, ANQP_ROAMING_CONSORTIUM)) wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM); - if (hapd->conf->ipaddr_type_configured) + if (hapd->conf->ipaddr_type_configured || + get_anqp_elem(hapd, ANQP_IP_ADDR_TYPE_AVAILABILITY)) wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY); - if (hapd->conf->nai_realm_data) + if (hapd->conf->nai_realm_data || + get_anqp_elem(hapd, ANQP_NAI_REALM)) wpabuf_put_le16(buf, ANQP_NAI_REALM); - if (hapd->conf->anqp_3gpp_cell_net) + if (hapd->conf->anqp_3gpp_cell_net || + get_anqp_elem(hapd, ANQP_3GPP_CELLULAR_NETWORK)) wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK); - if (hapd->conf->domain_name) + if (get_anqp_elem(hapd, ANQP_AP_GEOSPATIAL_LOCATION)) + wpabuf_put_le16(buf, ANQP_AP_GEOSPATIAL_LOCATION); + if (get_anqp_elem(hapd, ANQP_AP_CIVIC_LOCATION)) + wpabuf_put_le16(buf, ANQP_AP_CIVIC_LOCATION); + if (get_anqp_elem(hapd, ANQP_AP_LOCATION_PUBLIC_URI)) + wpabuf_put_le16(buf, ANQP_AP_LOCATION_PUBLIC_URI); + if (hapd->conf->domain_name || get_anqp_elem(hapd, ANQP_DOMAIN_NAME)) wpabuf_put_le16(buf, ANQP_DOMAIN_NAME); + if (get_anqp_elem(hapd, ANQP_EMERGENCY_ALERT_URI)) + wpabuf_put_le16(buf, ANQP_EMERGENCY_ALERT_URI); + if (get_anqp_elem(hapd, ANQP_EMERGENCY_NAI)) + wpabuf_put_le16(buf, ANQP_EMERGENCY_NAI); + if (get_anqp_elem(hapd, ANQP_NEIGHBOR_REPORT)) + wpabuf_put_le16(buf, ANQP_NEIGHBOR_REPORT); + for (id = 273; id < 277; id++) { + if (get_anqp_elem(hapd, id)) + wpabuf_put_le16(buf, id); + } + if (get_anqp_elem(hapd, ANQP_VENUE_URL)) + wpabuf_put_le16(buf, ANQP_VENUE_URL); + if (get_anqp_elem(hapd, ANQP_ADVICE_OF_CHARGE)) + wpabuf_put_le16(buf, ANQP_ADVICE_OF_CHARGE); + if (get_anqp_elem(hapd, ANQP_LOCAL_CONTENT)) + wpabuf_put_le16(buf, ANQP_LOCAL_CONTENT); #ifdef CONFIG_HS20 anqp_add_hs_capab_list(hapd, buf); #endif /* CONFIG_HS20 */ @@ -197,6 +278,9 @@ static void anqp_add_capab_list(struct hostapd_data *hapd, static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf) { + if (anqp_add_override(hapd, buf, ANQP_VENUE_NAME)) + return; + if (hapd->conf->venue_name) { u8 *len; unsigned int i; @@ -218,6 +302,9 @@ static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf) static void anqp_add_network_auth_type(struct hostapd_data *hapd, struct wpabuf *buf) { + if (anqp_add_override(hapd, buf, ANQP_NETWORK_AUTH_TYPE)) + return; + if (hapd->conf->network_auth_type) { wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE); wpabuf_put_le16(buf, hapd->conf->network_auth_type_len); @@ -233,6 +320,9 @@ static void anqp_add_roaming_consortium(struct hostapd_data *hapd, unsigned int i; u8 *len; + if (anqp_add_override(hapd, buf, ANQP_ROAMING_CONSORTIUM)) + return; + len = gas_anqp_add_element(buf, ANQP_ROAMING_CONSORTIUM); for (i = 0; i < hapd->conf->roaming_consortium_count; i++) { struct hostapd_roaming_consortium *rc; @@ -247,6 +337,9 @@ static void anqp_add_roaming_consortium(struct hostapd_data *hapd, static void anqp_add_ip_addr_type_availability(struct hostapd_data *hapd, struct wpabuf *buf) { + if (anqp_add_override(hapd, buf, ANQP_IP_ADDR_TYPE_AVAILABILITY)) + return; + if (hapd->conf->ipaddr_type_configured) { wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY); wpabuf_put_le16(buf, 1); @@ -309,7 +402,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd, pos = home_realm; end = pos + home_realm_len; - if (pos + 1 > end) { + if (end - pos < 1) { wpa_hexdump(MSG_DEBUG, "Too short NAI Home Realm Query", home_realm, home_realm_len); return -1; @@ -317,7 +410,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd, num_realms = *pos++; for (i = 0; i < num_realms && num_matching < 10; i++) { - if (pos + 2 > end) { + if (end - pos < 2) { wpa_hexdump(MSG_DEBUG, "Truncated NAI Home Realm Query", home_realm, home_realm_len); @@ -325,7 +418,7 @@ static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd, } encoding = *pos++; realm_len = *pos++; - if (pos + realm_len > end) { + if (realm_len > end - pos) { wpa_hexdump(MSG_DEBUG, "Truncated NAI Home Realm Query", home_realm, home_realm_len); @@ -391,6 +484,10 @@ static void anqp_add_nai_realm(struct hostapd_data *hapd, struct wpabuf *buf, const u8 *home_realm, size_t home_realm_len, int nai_realm, int nai_home_realm) { + if (nai_realm && !nai_home_realm && + anqp_add_override(hapd, buf, ANQP_NAI_REALM)) + return; + if (nai_realm && hapd->conf->nai_realm_data) { u8 *len; unsigned int i, j; @@ -424,6 +521,9 @@ static void anqp_add_nai_realm(struct hostapd_data *hapd, struct wpabuf *buf, static void anqp_add_3gpp_cellular_network(struct hostapd_data *hapd, struct wpabuf *buf) { + if (anqp_add_override(hapd, buf, ANQP_3GPP_CELLULAR_NETWORK)) + return; + if (hapd->conf->anqp_3gpp_cell_net) { wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK); wpabuf_put_le16(buf, @@ -436,6 +536,9 @@ static void anqp_add_3gpp_cellular_network(struct hostapd_data *hapd, static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf) { + if (anqp_add_override(hapd, buf, ANQP_DOMAIN_NAME)) + return; + if (hapd->conf->domain_name) { wpabuf_put_le16(buf, ANQP_DOMAIN_NAME); wpabuf_put_le16(buf, hapd->conf->domain_name_len); @@ -683,20 +786,42 @@ static void anqp_add_icon_binary_file(struct hostapd_data *hapd, #endif /* CONFIG_HS20 */ +static size_t anqp_get_required_len(struct hostapd_data *hapd, + const u16 *infoid, + unsigned int num_infoid) +{ + size_t len = 0; + unsigned int i; + + for (i = 0; i < num_infoid; i++) { + struct anqp_element *elem = get_anqp_elem(hapd, infoid[i]); + + if (elem) + len += 2 + 2 + wpabuf_len(elem->payload); + } + + return len; +} + + static struct wpabuf * gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, unsigned int request, const u8 *home_realm, size_t home_realm_len, - const u8 *icon_name, size_t icon_name_len) + const u8 *icon_name, size_t icon_name_len, + const u16 *extra_req, + unsigned int num_extra_req) { struct wpabuf *buf; size_t len; + unsigned int i; len = 1400; if (request & (ANQP_REQ_NAI_REALM | ANQP_REQ_NAI_HOME_REALM)) len += 1000; if (request & ANQP_REQ_ICON_REQUEST) len += 65536; + len += anqp_get_required_len(hapd, extra_req, num_extra_req); buf = wpabuf_alloc(len); if (buf == NULL) @@ -706,6 +831,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, anqp_add_capab_list(hapd, buf); if (request & ANQP_REQ_VENUE_NAME) anqp_add_venue_name(hapd, buf); + if (request & ANQP_REQ_EMERGENCY_CALL_NUMBER) + anqp_add_elem(hapd, buf, ANQP_EMERGENCY_CALL_NUMBER); if (request & ANQP_REQ_NETWORK_AUTH_TYPE) anqp_add_network_auth_type(hapd, buf); if (request & ANQP_REQ_ROAMING_CONSORTIUM) @@ -718,8 +845,23 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, request & ANQP_REQ_NAI_HOME_REALM); if (request & ANQP_REQ_3GPP_CELLULAR_NETWORK) anqp_add_3gpp_cellular_network(hapd, buf); + if (request & ANQP_REQ_AP_GEOSPATIAL_LOCATION) + anqp_add_elem(hapd, buf, ANQP_AP_GEOSPATIAL_LOCATION); + if (request & ANQP_REQ_AP_CIVIC_LOCATION) + anqp_add_elem(hapd, buf, ANQP_AP_CIVIC_LOCATION); + if (request & ANQP_REQ_AP_LOCATION_PUBLIC_URI) + anqp_add_elem(hapd, buf, ANQP_AP_LOCATION_PUBLIC_URI); if (request & ANQP_REQ_DOMAIN_NAME) anqp_add_domain_name(hapd, buf); + if (request & ANQP_REQ_EMERGENCY_ALERT_URI) + anqp_add_elem(hapd, buf, ANQP_EMERGENCY_ALERT_URI); + if (request & ANQP_REQ_TDLS_CAPABILITY) + anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY); + if (request & ANQP_REQ_EMERGENCY_NAI) + anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI); + + for (i = 0; i < num_extra_req; i++) + anqp_add_elem(hapd, buf, extra_req[i]); #ifdef CONFIG_HS20 if (request & ANQP_REQ_HS_CAPABILITY_LIST) @@ -742,6 +884,8 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd, } +#define ANQP_MAX_EXTRA_REQ 20 + struct anqp_query_info { unsigned int request; const u8 *home_realm_query; @@ -749,6 +893,8 @@ struct anqp_query_info { const u8 *icon_name; size_t icon_name_len; int p2p_sd; + u16 extra_req[ANQP_MAX_EXTRA_REQ]; + unsigned int num_extra_req; }; @@ -776,6 +922,11 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id, set_anqp_req(ANQP_REQ_VENUE_NAME, "Venue Name", hapd->conf->venue_name != NULL, qi); break; + case ANQP_EMERGENCY_CALL_NUMBER: + set_anqp_req(ANQP_REQ_EMERGENCY_CALL_NUMBER, + "Emergency Call Number", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; case ANQP_NETWORK_AUTH_TYPE: set_anqp_req(ANQP_REQ_NETWORK_AUTH_TYPE, "Network Auth Type", hapd->conf->network_auth_type != NULL, qi); @@ -798,13 +949,55 @@ static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id, "3GPP Cellular Network", hapd->conf->anqp_3gpp_cell_net != NULL, qi); break; + case ANQP_AP_GEOSPATIAL_LOCATION: + set_anqp_req(ANQP_REQ_AP_GEOSPATIAL_LOCATION, + "AP Geospatial Location", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; + case ANQP_AP_CIVIC_LOCATION: + set_anqp_req(ANQP_REQ_AP_CIVIC_LOCATION, + "AP Civic Location", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; + case ANQP_AP_LOCATION_PUBLIC_URI: + set_anqp_req(ANQP_REQ_AP_LOCATION_PUBLIC_URI, + "AP Location Public URI", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; case ANQP_DOMAIN_NAME: set_anqp_req(ANQP_REQ_DOMAIN_NAME, "Domain Name", hapd->conf->domain_name != NULL, qi); break; + case ANQP_EMERGENCY_ALERT_URI: + set_anqp_req(ANQP_REQ_EMERGENCY_ALERT_URI, + "Emergency Alert URI", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; + case ANQP_TDLS_CAPABILITY: + set_anqp_req(ANQP_REQ_TDLS_CAPABILITY, + "TDLS Capability", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; + case ANQP_EMERGENCY_NAI: + set_anqp_req(ANQP_REQ_EMERGENCY_NAI, + "Emergency NAI", + get_anqp_elem(hapd, info_id) != NULL, qi); + break; default: - wpa_printf(MSG_DEBUG, "ANQP: Unsupported Info Id %u", - info_id); + if (!get_anqp_elem(hapd, info_id)) { + wpa_printf(MSG_DEBUG, "ANQP: Unsupported Info Id %u", + info_id); + break; + } + if (qi->num_extra_req == ANQP_MAX_EXTRA_REQ) { + wpa_printf(MSG_DEBUG, + "ANQP: No more room for extra requests - ignore Info Id %u", + info_id); + break; + } + wpa_printf(MSG_DEBUG, "ANQP: Info Id %u (local)", info_id); + qi->extra_req[qi->num_extra_req] = info_id; + qi->num_extra_req++; break; } } @@ -817,7 +1010,7 @@ static void rx_anqp_query_list(struct hostapd_data *hapd, wpa_printf(MSG_DEBUG, "ANQP: %u Info IDs requested in Query list", (unsigned int) (end - pos) / 2); - while (pos + 2 <= end) { + while (end - pos >= 2) { rx_anqp_query_list_id(hapd, WPA_GET_LE16(pos), qi); pos += 2; } @@ -906,7 +1099,7 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd, u32 oui; u8 subtype; - if (pos + 4 > end) { + if (end - pos < 4) { wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP " "Query element"); return; @@ -942,7 +1135,7 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd, } pos++; - if (pos + 1 >= end) + if (end - pos <= 1) return; subtype = *pos++; @@ -973,14 +1166,16 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd, static void gas_serv_req_local_processing(struct hostapd_data *hapd, const u8 *sa, u8 dialog_token, - struct anqp_query_info *qi, int prot) + struct anqp_query_info *qi, int prot, + int std_addr3) { struct wpabuf *buf, *tx_buf; buf = gas_serv_build_gas_resp_payload(hapd, qi->request, qi->home_realm_query, qi->home_realm_query_len, - qi->icon_name, qi->icon_name_len); + qi->icon_name, qi->icon_name_len, + qi->extra_req, qi->num_extra_req); wpa_hexdump_buf(MSG_MSGDUMP, "ANQP: Locally generated ANQP responses", buf); if (!buf) @@ -1033,15 +1228,22 @@ static void gas_serv_req_local_processing(struct hostapd_data *hapd, return; if (prot) convert_to_protected_dual(tx_buf); - hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, - wpabuf_head(tx_buf), wpabuf_len(tx_buf)); + if (std_addr3) + hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, + wpabuf_head(tx_buf), + wpabuf_len(tx_buf)); + else + hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa, + wpabuf_head(tx_buf), + wpabuf_len(tx_buf)); wpabuf_free(tx_buf); } static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, const u8 *sa, - const u8 *data, size_t len, int prot) + const u8 *data, size_t len, int prot, + int std_addr3) { const u8 *pos = data; const u8 *end = data + len; @@ -1069,12 +1271,12 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, adv_proto = pos++; slen = *pos++; - next = pos + slen; - if (next > end || slen < 2) { + if (slen > end - pos || slen < 2) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Invalid IE in GAS Initial Request"); return; } + next = pos + slen; pos++; /* skip QueryRespLenLimit and PAME-BI */ if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) { @@ -1093,19 +1295,26 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, wpabuf_put_le16(buf, 0); /* Query Response Length */ if (prot) convert_to_protected_dual(buf); - hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, - wpabuf_head(buf), wpabuf_len(buf)); + if (std_addr3) + hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, + wpabuf_head(buf), + wpabuf_len(buf)); + else + hostapd_drv_send_action_addr3_ap(hapd, + hapd->iface->freq, 0, + sa, wpabuf_head(buf), + wpabuf_len(buf)); wpabuf_free(buf); return; } pos = next; /* Query Request */ - if (pos + 2 > end) + if (end - pos < 2) return; slen = WPA_GET_LE16(pos); pos += 2; - if (pos + slen > end) + if (slen > end - pos) return; end = pos + slen; @@ -1113,7 +1322,7 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, while (pos < end) { u16 info_id, elen; - if (pos + 4 > end) + if (end - pos < 4) return; info_id = WPA_GET_LE16(pos); @@ -1121,7 +1330,7 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, elen = WPA_GET_LE16(pos); pos += 2; - if (pos + elen > end) { + if (elen > end - pos) { wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request"); return; } @@ -1144,13 +1353,15 @@ static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd, pos += elen; } - gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot); + gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot, + std_addr3); } static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd, const u8 *sa, - const u8 *data, size_t len, int prot) + const u8 *data, size_t len, int prot, + int std_addr3) { struct gas_dialog_info *dialog; struct wpabuf *buf, *tx_buf; @@ -1226,8 +1437,14 @@ static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd, send_resp: if (prot) convert_to_protected_dual(tx_buf); - hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, - wpabuf_head(tx_buf), wpabuf_len(tx_buf)); + if (std_addr3) + hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa, + wpabuf_head(tx_buf), + wpabuf_len(tx_buf)); + else + hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa, + wpabuf_head(tx_buf), + wpabuf_len(tx_buf)); wpabuf_free(tx_buf); } @@ -1238,7 +1455,7 @@ static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len, struct hostapd_data *hapd = ctx; const struct ieee80211_mgmt *mgmt; const u8 *sa, *data; - int prot; + int prot, std_addr3; mgmt = (const struct ieee80211_mgmt *) buf; if (len < IEEE80211_HDRLEN + 2) @@ -1253,14 +1470,22 @@ static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len, */ prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL; sa = mgmt->sa; + if (hapd->conf->gas_address3 == 1) + std_addr3 = 1; + else if (hapd->conf->gas_address3 == 2) + std_addr3 = 0; + else + std_addr3 = is_broadcast_ether_addr(mgmt->bssid); len -= IEEE80211_HDRLEN + 1; data = buf + IEEE80211_HDRLEN + 1; switch (data[0]) { case WLAN_PA_GAS_INITIAL_REQ: - gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot); + gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot, + std_addr3); break; case WLAN_PA_GAS_COMEBACK_REQ: - gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot); + gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot, + std_addr3); break; } } |