Home | History | Annotate | Download | only in ap
      1 /*
      2  * Generic advertisement service (GAS) server
      3  * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "includes.h"
     10 
     11 #include "common.h"
     12 #include "common/ieee802_11_defs.h"
     13 #include "common/gas.h"
     14 #include "utils/eloop.h"
     15 #include "hostapd.h"
     16 #include "ap_config.h"
     17 #include "ap_drv_ops.h"
     18 #include "sta_info.h"
     19 #include "gas_serv.h"
     20 
     21 
     22 static void convert_to_protected_dual(struct wpabuf *msg)
     23 {
     24 	u8 *categ = wpabuf_mhead_u8(msg);
     25 	*categ = WLAN_ACTION_PROTECTED_DUAL;
     26 }
     27 
     28 
     29 static struct gas_dialog_info *
     30 gas_dialog_create(struct hostapd_data *hapd, const u8 *addr, u8 dialog_token)
     31 {
     32 	struct sta_info *sta;
     33 	struct gas_dialog_info *dia = NULL;
     34 	int i, j;
     35 
     36 	sta = ap_get_sta(hapd, addr);
     37 	if (!sta) {
     38 		/*
     39 		 * We need a STA entry to be able to maintain state for
     40 		 * the GAS query.
     41 		 */
     42 		wpa_printf(MSG_DEBUG, "ANQP: Add a temporary STA entry for "
     43 			   "GAS query");
     44 		sta = ap_sta_add(hapd, addr);
     45 		if (!sta) {
     46 			wpa_printf(MSG_DEBUG, "Failed to add STA " MACSTR
     47 				   " for GAS query", MAC2STR(addr));
     48 			return NULL;
     49 		}
     50 		sta->flags |= WLAN_STA_GAS;
     51 		/*
     52 		 * The default inactivity is 300 seconds. We don't need
     53 		 * it to be that long. Use five second timeout and increase this
     54 		 * with the comeback_delay for testing cases.
     55 		 */
     56 		ap_sta_session_timeout(hapd, sta,
     57 				       hapd->conf->gas_comeback_delay / 1024 +
     58 				       5);
     59 	} else {
     60 		ap_sta_replenish_timeout(hapd, sta, 5);
     61 	}
     62 
     63 	if (sta->gas_dialog == NULL) {
     64 		sta->gas_dialog = os_calloc(GAS_DIALOG_MAX,
     65 					    sizeof(struct gas_dialog_info));
     66 		if (sta->gas_dialog == NULL)
     67 			return NULL;
     68 	}
     69 
     70 	for (i = sta->gas_dialog_next, j = 0; j < GAS_DIALOG_MAX; i++, j++) {
     71 		if (i == GAS_DIALOG_MAX)
     72 			i = 0;
     73 		if (sta->gas_dialog[i].valid)
     74 			continue;
     75 		dia = &sta->gas_dialog[i];
     76 		dia->valid = 1;
     77 		dia->dialog_token = dialog_token;
     78 		sta->gas_dialog_next = (++i == GAS_DIALOG_MAX) ? 0 : i;
     79 		return dia;
     80 	}
     81 
     82 	wpa_msg(hapd->msg_ctx, MSG_ERROR, "ANQP: Could not create dialog for "
     83 		MACSTR " dialog_token %u. Consider increasing "
     84 		"GAS_DIALOG_MAX.", MAC2STR(addr), dialog_token);
     85 
     86 	return NULL;
     87 }
     88 
     89 
     90 struct gas_dialog_info *
     91 gas_serv_dialog_find(struct hostapd_data *hapd, const u8 *addr,
     92 		     u8 dialog_token)
     93 {
     94 	struct sta_info *sta;
     95 	int i;
     96 
     97 	sta = ap_get_sta(hapd, addr);
     98 	if (!sta) {
     99 		wpa_printf(MSG_DEBUG, "ANQP: could not find STA " MACSTR,
    100 			   MAC2STR(addr));
    101 		return NULL;
    102 	}
    103 	for (i = 0; sta->gas_dialog && i < GAS_DIALOG_MAX; i++) {
    104 		if (sta->gas_dialog[i].dialog_token != dialog_token ||
    105 		    !sta->gas_dialog[i].valid)
    106 			continue;
    107 		ap_sta_replenish_timeout(hapd, sta, 5);
    108 		return &sta->gas_dialog[i];
    109 	}
    110 	wpa_printf(MSG_DEBUG, "ANQP: Could not find dialog for "
    111 		   MACSTR " dialog_token %u", MAC2STR(addr), dialog_token);
    112 	return NULL;
    113 }
    114 
    115 
    116 void gas_serv_dialog_clear(struct gas_dialog_info *dia)
    117 {
    118 	wpabuf_free(dia->sd_resp);
    119 	os_memset(dia, 0, sizeof(*dia));
    120 }
    121 
    122 
    123 static void gas_serv_free_dialogs(struct hostapd_data *hapd,
    124 				  const u8 *sta_addr)
    125 {
    126 	struct sta_info *sta;
    127 	int i;
    128 
    129 	sta = ap_get_sta(hapd, sta_addr);
    130 	if (sta == NULL || sta->gas_dialog == NULL)
    131 		return;
    132 
    133 	for (i = 0; i < GAS_DIALOG_MAX; i++) {
    134 		if (sta->gas_dialog[i].valid)
    135 			return;
    136 	}
    137 
    138 	os_free(sta->gas_dialog);
    139 	sta->gas_dialog = NULL;
    140 }
    141 
    142 
    143 #ifdef CONFIG_HS20
    144 static void anqp_add_hs_capab_list(struct hostapd_data *hapd,
    145 				   struct wpabuf *buf)
    146 {
    147 	u8 *len;
    148 
    149 	len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    150 	wpabuf_put_be24(buf, OUI_WFA);
    151 	wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    152 	wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
    153 	wpabuf_put_u8(buf, 0); /* Reserved */
    154 	wpabuf_put_u8(buf, HS20_STYPE_CAPABILITY_LIST);
    155 	if (hapd->conf->hs20_oper_friendly_name)
    156 		wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME);
    157 	if (hapd->conf->hs20_wan_metrics)
    158 		wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
    159 	if (hapd->conf->hs20_connection_capability)
    160 		wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
    161 	if (hapd->conf->nai_realm_data)
    162 		wpabuf_put_u8(buf, HS20_STYPE_NAI_HOME_REALM_QUERY);
    163 	if (hapd->conf->hs20_operating_class)
    164 		wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
    165 	if (hapd->conf->hs20_osu_providers_count)
    166 		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST);
    167 	if (hapd->conf->hs20_icons_count)
    168 		wpabuf_put_u8(buf, HS20_STYPE_ICON_REQUEST);
    169 	gas_anqp_set_element_len(buf, len);
    170 }
    171 #endif /* CONFIG_HS20 */
    172 
    173 
    174 static struct anqp_element * get_anqp_elem(struct hostapd_data *hapd,
    175 					   u16 infoid)
    176 {
    177 	struct anqp_element *elem;
    178 
    179 	dl_list_for_each(elem, &hapd->conf->anqp_elem, struct anqp_element,
    180 			 list) {
    181 		if (elem->infoid == infoid)
    182 			return elem;
    183 	}
    184 
    185 	return NULL;
    186 }
    187 
    188 
    189 static void anqp_add_elem(struct hostapd_data *hapd, struct wpabuf *buf,
    190 			  u16 infoid)
    191 {
    192 	struct anqp_element *elem;
    193 
    194 	elem = get_anqp_elem(hapd, infoid);
    195 	if (!elem)
    196 		return;
    197 	if (wpabuf_tailroom(buf) < 2 + 2 + wpabuf_len(elem->payload)) {
    198 		wpa_printf(MSG_DEBUG, "ANQP: No room for InfoID %u payload",
    199 			   infoid);
    200 		return;
    201 	}
    202 
    203 	wpabuf_put_le16(buf, infoid);
    204 	wpabuf_put_le16(buf, wpabuf_len(elem->payload));
    205 	wpabuf_put_buf(buf, elem->payload);
    206 }
    207 
    208 
    209 static int anqp_add_override(struct hostapd_data *hapd, struct wpabuf *buf,
    210 			     u16 infoid)
    211 {
    212 	if (get_anqp_elem(hapd, infoid)) {
    213 		anqp_add_elem(hapd, buf, infoid);
    214 		return 1;
    215 	}
    216 
    217 	return 0;
    218 }
    219 
    220 
    221 static void anqp_add_capab_list(struct hostapd_data *hapd,
    222 				struct wpabuf *buf)
    223 {
    224 	u8 *len;
    225 	u16 id;
    226 
    227 	if (anqp_add_override(hapd, buf, ANQP_CAPABILITY_LIST))
    228 		return;
    229 
    230 	len = gas_anqp_add_element(buf, ANQP_CAPABILITY_LIST);
    231 	wpabuf_put_le16(buf, ANQP_CAPABILITY_LIST);
    232 	if (hapd->conf->venue_name || get_anqp_elem(hapd, ANQP_VENUE_NAME))
    233 		wpabuf_put_le16(buf, ANQP_VENUE_NAME);
    234 	if (get_anqp_elem(hapd, ANQP_EMERGENCY_CALL_NUMBER))
    235 		wpabuf_put_le16(buf, ANQP_EMERGENCY_CALL_NUMBER);
    236 	if (hapd->conf->network_auth_type ||
    237 	    get_anqp_elem(hapd, ANQP_NETWORK_AUTH_TYPE))
    238 		wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE);
    239 	if (hapd->conf->roaming_consortium ||
    240 	    get_anqp_elem(hapd, ANQP_ROAMING_CONSORTIUM))
    241 		wpabuf_put_le16(buf, ANQP_ROAMING_CONSORTIUM);
    242 	if (hapd->conf->ipaddr_type_configured ||
    243 	    get_anqp_elem(hapd, ANQP_IP_ADDR_TYPE_AVAILABILITY))
    244 		wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY);
    245 	if (hapd->conf->nai_realm_data ||
    246 	    get_anqp_elem(hapd, ANQP_NAI_REALM))
    247 		wpabuf_put_le16(buf, ANQP_NAI_REALM);
    248 	if (hapd->conf->anqp_3gpp_cell_net ||
    249 	    get_anqp_elem(hapd, ANQP_3GPP_CELLULAR_NETWORK))
    250 		wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK);
    251 	if (get_anqp_elem(hapd, ANQP_AP_GEOSPATIAL_LOCATION))
    252 		wpabuf_put_le16(buf, ANQP_AP_GEOSPATIAL_LOCATION);
    253 	if (get_anqp_elem(hapd, ANQP_AP_CIVIC_LOCATION))
    254 		wpabuf_put_le16(buf, ANQP_AP_CIVIC_LOCATION);
    255 	if (get_anqp_elem(hapd, ANQP_AP_LOCATION_PUBLIC_URI))
    256 		wpabuf_put_le16(buf, ANQP_AP_LOCATION_PUBLIC_URI);
    257 	if (hapd->conf->domain_name || get_anqp_elem(hapd, ANQP_DOMAIN_NAME))
    258 		wpabuf_put_le16(buf, ANQP_DOMAIN_NAME);
    259 	if (get_anqp_elem(hapd, ANQP_EMERGENCY_ALERT_URI))
    260 		wpabuf_put_le16(buf, ANQP_EMERGENCY_ALERT_URI);
    261 	if (get_anqp_elem(hapd, ANQP_TDLS_CAPABILITY))
    262 		wpabuf_put_le16(buf, ANQP_TDLS_CAPABILITY);
    263 	if (get_anqp_elem(hapd, ANQP_EMERGENCY_NAI))
    264 		wpabuf_put_le16(buf, ANQP_EMERGENCY_NAI);
    265 	if (get_anqp_elem(hapd, ANQP_NEIGHBOR_REPORT))
    266 		wpabuf_put_le16(buf, ANQP_NEIGHBOR_REPORT);
    267 #ifdef CONFIG_FILS
    268 	if (!dl_list_empty(&hapd->conf->fils_realms) ||
    269 	    get_anqp_elem(hapd, ANQP_FILS_REALM_INFO))
    270 		wpabuf_put_le16(buf, ANQP_FILS_REALM_INFO);
    271 #endif /* CONFIG_FILS */
    272 	if (get_anqp_elem(hapd, ANQP_CAG))
    273 		wpabuf_put_le16(buf, ANQP_CAG);
    274 	if (get_anqp_elem(hapd, ANQP_VENUE_URL))
    275 		wpabuf_put_le16(buf, ANQP_VENUE_URL);
    276 	if (get_anqp_elem(hapd, ANQP_ADVICE_OF_CHARGE))
    277 		wpabuf_put_le16(buf, ANQP_ADVICE_OF_CHARGE);
    278 	if (get_anqp_elem(hapd, ANQP_LOCAL_CONTENT))
    279 		wpabuf_put_le16(buf, ANQP_LOCAL_CONTENT);
    280 	for (id = 280; id < 300; id++) {
    281 		if (get_anqp_elem(hapd, id))
    282 			wpabuf_put_le16(buf, id);
    283 	}
    284 #ifdef CONFIG_HS20
    285 	anqp_add_hs_capab_list(hapd, buf);
    286 #endif /* CONFIG_HS20 */
    287 	gas_anqp_set_element_len(buf, len);
    288 }
    289 
    290 
    291 static void anqp_add_venue_name(struct hostapd_data *hapd, struct wpabuf *buf)
    292 {
    293 	if (anqp_add_override(hapd, buf, ANQP_VENUE_NAME))
    294 		return;
    295 
    296 	if (hapd->conf->venue_name) {
    297 		u8 *len;
    298 		unsigned int i;
    299 		len = gas_anqp_add_element(buf, ANQP_VENUE_NAME);
    300 		wpabuf_put_u8(buf, hapd->conf->venue_group);
    301 		wpabuf_put_u8(buf, hapd->conf->venue_type);
    302 		for (i = 0; i < hapd->conf->venue_name_count; i++) {
    303 			struct hostapd_lang_string *vn;
    304 			vn = &hapd->conf->venue_name[i];
    305 			wpabuf_put_u8(buf, 3 + vn->name_len);
    306 			wpabuf_put_data(buf, vn->lang, 3);
    307 			wpabuf_put_data(buf, vn->name, vn->name_len);
    308 		}
    309 		gas_anqp_set_element_len(buf, len);
    310 	}
    311 }
    312 
    313 
    314 static void anqp_add_network_auth_type(struct hostapd_data *hapd,
    315 				       struct wpabuf *buf)
    316 {
    317 	if (anqp_add_override(hapd, buf, ANQP_NETWORK_AUTH_TYPE))
    318 		return;
    319 
    320 	if (hapd->conf->network_auth_type) {
    321 		wpabuf_put_le16(buf, ANQP_NETWORK_AUTH_TYPE);
    322 		wpabuf_put_le16(buf, hapd->conf->network_auth_type_len);
    323 		wpabuf_put_data(buf, hapd->conf->network_auth_type,
    324 				hapd->conf->network_auth_type_len);
    325 	}
    326 }
    327 
    328 
    329 static void anqp_add_roaming_consortium(struct hostapd_data *hapd,
    330 					struct wpabuf *buf)
    331 {
    332 	unsigned int i;
    333 	u8 *len;
    334 
    335 	if (anqp_add_override(hapd, buf, ANQP_ROAMING_CONSORTIUM))
    336 		return;
    337 
    338 	len = gas_anqp_add_element(buf, ANQP_ROAMING_CONSORTIUM);
    339 	for (i = 0; i < hapd->conf->roaming_consortium_count; i++) {
    340 		struct hostapd_roaming_consortium *rc;
    341 		rc = &hapd->conf->roaming_consortium[i];
    342 		wpabuf_put_u8(buf, rc->len);
    343 		wpabuf_put_data(buf, rc->oi, rc->len);
    344 	}
    345 	gas_anqp_set_element_len(buf, len);
    346 }
    347 
    348 
    349 static void anqp_add_ip_addr_type_availability(struct hostapd_data *hapd,
    350 					       struct wpabuf *buf)
    351 {
    352 	if (anqp_add_override(hapd, buf, ANQP_IP_ADDR_TYPE_AVAILABILITY))
    353 		return;
    354 
    355 	if (hapd->conf->ipaddr_type_configured) {
    356 		wpabuf_put_le16(buf, ANQP_IP_ADDR_TYPE_AVAILABILITY);
    357 		wpabuf_put_le16(buf, 1);
    358 		wpabuf_put_u8(buf, hapd->conf->ipaddr_type_availability);
    359 	}
    360 }
    361 
    362 
    363 static void anqp_add_nai_realm_eap(struct wpabuf *buf,
    364 				   struct hostapd_nai_realm_data *realm)
    365 {
    366 	unsigned int i, j;
    367 
    368 	wpabuf_put_u8(buf, realm->eap_method_count);
    369 
    370 	for (i = 0; i < realm->eap_method_count; i++) {
    371 		struct hostapd_nai_realm_eap *eap = &realm->eap_method[i];
    372 		wpabuf_put_u8(buf, 2 + (3 * eap->num_auths));
    373 		wpabuf_put_u8(buf, eap->eap_method);
    374 		wpabuf_put_u8(buf, eap->num_auths);
    375 		for (j = 0; j < eap->num_auths; j++) {
    376 			wpabuf_put_u8(buf, eap->auth_id[j]);
    377 			wpabuf_put_u8(buf, 1);
    378 			wpabuf_put_u8(buf, eap->auth_val[j]);
    379 		}
    380 	}
    381 }
    382 
    383 
    384 static void anqp_add_nai_realm_data(struct wpabuf *buf,
    385 				    struct hostapd_nai_realm_data *realm,
    386 				    unsigned int realm_idx)
    387 {
    388 	u8 *realm_data_len;
    389 
    390 	wpa_printf(MSG_DEBUG, "realm=%s, len=%d", realm->realm[realm_idx],
    391 		   (int) os_strlen(realm->realm[realm_idx]));
    392 	realm_data_len = wpabuf_put(buf, 2);
    393 	wpabuf_put_u8(buf, realm->encoding);
    394 	wpabuf_put_u8(buf, os_strlen(realm->realm[realm_idx]));
    395 	wpabuf_put_str(buf, realm->realm[realm_idx]);
    396 	anqp_add_nai_realm_eap(buf, realm);
    397 	gas_anqp_set_element_len(buf, realm_data_len);
    398 }
    399 
    400 
    401 static int hs20_add_nai_home_realm_matches(struct hostapd_data *hapd,
    402 					   struct wpabuf *buf,
    403 					   const u8 *home_realm,
    404 					   size_t home_realm_len)
    405 {
    406 	unsigned int i, j, k;
    407 	u8 num_realms, num_matching = 0, encoding, realm_len, *realm_list_len;
    408 	struct hostapd_nai_realm_data *realm;
    409 	const u8 *pos, *realm_name, *end;
    410 	struct {
    411 		unsigned int realm_data_idx;
    412 		unsigned int realm_idx;
    413 	} matches[10];
    414 
    415 	pos = home_realm;
    416 	end = pos + home_realm_len;
    417 	if (end - pos < 1) {
    418 		wpa_hexdump(MSG_DEBUG, "Too short NAI Home Realm Query",
    419 			    home_realm, home_realm_len);
    420 		return -1;
    421 	}
    422 	num_realms = *pos++;
    423 
    424 	for (i = 0; i < num_realms && num_matching < 10; i++) {
    425 		if (end - pos < 2) {
    426 			wpa_hexdump(MSG_DEBUG,
    427 				    "Truncated NAI Home Realm Query",
    428 				    home_realm, home_realm_len);
    429 			return -1;
    430 		}
    431 		encoding = *pos++;
    432 		realm_len = *pos++;
    433 		if (realm_len > end - pos) {
    434 			wpa_hexdump(MSG_DEBUG,
    435 				    "Truncated NAI Home Realm Query",
    436 				    home_realm, home_realm_len);
    437 			return -1;
    438 		}
    439 		realm_name = pos;
    440 		for (j = 0; j < hapd->conf->nai_realm_count &&
    441 			     num_matching < 10; j++) {
    442 			const u8 *rpos, *rend;
    443 			realm = &hapd->conf->nai_realm_data[j];
    444 			if (encoding != realm->encoding)
    445 				continue;
    446 
    447 			rpos = realm_name;
    448 			while (rpos < realm_name + realm_len &&
    449 			       num_matching < 10) {
    450 				for (rend = rpos;
    451 				     rend < realm_name + realm_len; rend++) {
    452 					if (*rend == ';')
    453 						break;
    454 				}
    455 				for (k = 0; k < MAX_NAI_REALMS &&
    456 					     realm->realm[k] &&
    457 					     num_matching < 10; k++) {
    458 					if ((int) os_strlen(realm->realm[k]) !=
    459 					    rend - rpos ||
    460 					    os_strncmp((char *) rpos,
    461 						       realm->realm[k],
    462 						       rend - rpos) != 0)
    463 						continue;
    464 					matches[num_matching].realm_data_idx =
    465 						j;
    466 					matches[num_matching].realm_idx = k;
    467 					num_matching++;
    468 				}
    469 				rpos = rend + 1;
    470 			}
    471 		}
    472 		pos += realm_len;
    473 	}
    474 
    475 	realm_list_len = gas_anqp_add_element(buf, ANQP_NAI_REALM);
    476 	wpabuf_put_le16(buf, num_matching);
    477 
    478 	/*
    479 	 * There are two ways to format. 1. each realm in a NAI Realm Data unit
    480 	 * 2. all realms that share the same EAP methods in a NAI Realm Data
    481 	 * unit. The first format is likely to be bigger in size than the
    482 	 * second, but may be easier to parse and process by the receiver.
    483 	 */
    484 	for (i = 0; i < num_matching; i++) {
    485 		wpa_printf(MSG_DEBUG, "realm_idx %d, realm_data_idx %d",
    486 			   matches[i].realm_data_idx, matches[i].realm_idx);
    487 		realm = &hapd->conf->nai_realm_data[matches[i].realm_data_idx];
    488 		anqp_add_nai_realm_data(buf, realm, matches[i].realm_idx);
    489 	}
    490 	gas_anqp_set_element_len(buf, realm_list_len);
    491 	return 0;
    492 }
    493 
    494 
    495 static void anqp_add_nai_realm(struct hostapd_data *hapd, struct wpabuf *buf,
    496 			       const u8 *home_realm, size_t home_realm_len,
    497 			       int nai_realm, int nai_home_realm)
    498 {
    499 	if (nai_realm && !nai_home_realm &&
    500 	    anqp_add_override(hapd, buf, ANQP_NAI_REALM))
    501 		return;
    502 
    503 	if (nai_realm && hapd->conf->nai_realm_data) {
    504 		u8 *len;
    505 		unsigned int i, j;
    506 		len = gas_anqp_add_element(buf, ANQP_NAI_REALM);
    507 		wpabuf_put_le16(buf, hapd->conf->nai_realm_count);
    508 		for (i = 0; i < hapd->conf->nai_realm_count; i++) {
    509 			u8 *realm_data_len, *realm_len;
    510 			struct hostapd_nai_realm_data *realm;
    511 
    512 			realm = &hapd->conf->nai_realm_data[i];
    513 			realm_data_len = wpabuf_put(buf, 2);
    514 			wpabuf_put_u8(buf, realm->encoding);
    515 			realm_len = wpabuf_put(buf, 1);
    516 			for (j = 0; realm->realm[j]; j++) {
    517 				if (j > 0)
    518 					wpabuf_put_u8(buf, ';');
    519 				wpabuf_put_str(buf, realm->realm[j]);
    520 			}
    521 			*realm_len = (u8 *) wpabuf_put(buf, 0) - realm_len - 1;
    522 			anqp_add_nai_realm_eap(buf, realm);
    523 			gas_anqp_set_element_len(buf, realm_data_len);
    524 		}
    525 		gas_anqp_set_element_len(buf, len);
    526 	} else if (nai_home_realm && hapd->conf->nai_realm_data && home_realm) {
    527 		hs20_add_nai_home_realm_matches(hapd, buf, home_realm,
    528 						home_realm_len);
    529 	}
    530 }
    531 
    532 
    533 static void anqp_add_3gpp_cellular_network(struct hostapd_data *hapd,
    534 					   struct wpabuf *buf)
    535 {
    536 	if (anqp_add_override(hapd, buf, ANQP_3GPP_CELLULAR_NETWORK))
    537 		return;
    538 
    539 	if (hapd->conf->anqp_3gpp_cell_net) {
    540 		wpabuf_put_le16(buf, ANQP_3GPP_CELLULAR_NETWORK);
    541 		wpabuf_put_le16(buf,
    542 				hapd->conf->anqp_3gpp_cell_net_len);
    543 		wpabuf_put_data(buf, hapd->conf->anqp_3gpp_cell_net,
    544 				hapd->conf->anqp_3gpp_cell_net_len);
    545 	}
    546 }
    547 
    548 
    549 static void anqp_add_domain_name(struct hostapd_data *hapd, struct wpabuf *buf)
    550 {
    551 	if (anqp_add_override(hapd, buf, ANQP_DOMAIN_NAME))
    552 		return;
    553 
    554 	if (hapd->conf->domain_name) {
    555 		wpabuf_put_le16(buf, ANQP_DOMAIN_NAME);
    556 		wpabuf_put_le16(buf, hapd->conf->domain_name_len);
    557 		wpabuf_put_data(buf, hapd->conf->domain_name,
    558 				hapd->conf->domain_name_len);
    559 	}
    560 }
    561 
    562 
    563 #ifdef CONFIG_FILS
    564 static void anqp_add_fils_realm_info(struct hostapd_data *hapd,
    565 				     struct wpabuf *buf)
    566 {
    567 	size_t count;
    568 
    569 	if (anqp_add_override(hapd, buf, ANQP_FILS_REALM_INFO))
    570 		return;
    571 
    572 	count = dl_list_len(&hapd->conf->fils_realms);
    573 	if (count > 10000)
    574 		count = 10000;
    575 	if (count) {
    576 		struct fils_realm *realm;
    577 
    578 		wpabuf_put_le16(buf, ANQP_FILS_REALM_INFO);
    579 		wpabuf_put_le16(buf, 2 * count);
    580 
    581 		dl_list_for_each(realm, &hapd->conf->fils_realms,
    582 				 struct fils_realm, list) {
    583 			if (count == 0)
    584 				break;
    585 			wpabuf_put_data(buf, realm->hash, 2);
    586 			count--;
    587 		}
    588 	}
    589 }
    590 #endif /* CONFIG_FILS */
    591 
    592 
    593 #ifdef CONFIG_HS20
    594 
    595 static void anqp_add_operator_friendly_name(struct hostapd_data *hapd,
    596 					    struct wpabuf *buf)
    597 {
    598 	if (hapd->conf->hs20_oper_friendly_name) {
    599 		u8 *len;
    600 		unsigned int i;
    601 		len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    602 		wpabuf_put_be24(buf, OUI_WFA);
    603 		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    604 		wpabuf_put_u8(buf, HS20_STYPE_OPERATOR_FRIENDLY_NAME);
    605 		wpabuf_put_u8(buf, 0); /* Reserved */
    606 		for (i = 0; i < hapd->conf->hs20_oper_friendly_name_count; i++)
    607 		{
    608 			struct hostapd_lang_string *vn;
    609 			vn = &hapd->conf->hs20_oper_friendly_name[i];
    610 			wpabuf_put_u8(buf, 3 + vn->name_len);
    611 			wpabuf_put_data(buf, vn->lang, 3);
    612 			wpabuf_put_data(buf, vn->name, vn->name_len);
    613 		}
    614 		gas_anqp_set_element_len(buf, len);
    615 	}
    616 }
    617 
    618 
    619 static void anqp_add_wan_metrics(struct hostapd_data *hapd,
    620 				 struct wpabuf *buf)
    621 {
    622 	if (hapd->conf->hs20_wan_metrics) {
    623 		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    624 		wpabuf_put_be24(buf, OUI_WFA);
    625 		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    626 		wpabuf_put_u8(buf, HS20_STYPE_WAN_METRICS);
    627 		wpabuf_put_u8(buf, 0); /* Reserved */
    628 		wpabuf_put_data(buf, hapd->conf->hs20_wan_metrics, 13);
    629 		gas_anqp_set_element_len(buf, len);
    630 	}
    631 }
    632 
    633 
    634 static void anqp_add_connection_capability(struct hostapd_data *hapd,
    635 					   struct wpabuf *buf)
    636 {
    637 	if (hapd->conf->hs20_connection_capability) {
    638 		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    639 		wpabuf_put_be24(buf, OUI_WFA);
    640 		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    641 		wpabuf_put_u8(buf, HS20_STYPE_CONNECTION_CAPABILITY);
    642 		wpabuf_put_u8(buf, 0); /* Reserved */
    643 		wpabuf_put_data(buf, hapd->conf->hs20_connection_capability,
    644 				hapd->conf->hs20_connection_capability_len);
    645 		gas_anqp_set_element_len(buf, len);
    646 	}
    647 }
    648 
    649 
    650 static void anqp_add_operating_class(struct hostapd_data *hapd,
    651 				     struct wpabuf *buf)
    652 {
    653 	if (hapd->conf->hs20_operating_class) {
    654 		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    655 		wpabuf_put_be24(buf, OUI_WFA);
    656 		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    657 		wpabuf_put_u8(buf, HS20_STYPE_OPERATING_CLASS);
    658 		wpabuf_put_u8(buf, 0); /* Reserved */
    659 		wpabuf_put_data(buf, hapd->conf->hs20_operating_class,
    660 				hapd->conf->hs20_operating_class_len);
    661 		gas_anqp_set_element_len(buf, len);
    662 	}
    663 }
    664 
    665 
    666 static void anqp_add_osu_provider(struct wpabuf *buf,
    667 				  struct hostapd_bss_config *bss,
    668 				  struct hs20_osu_provider *p)
    669 {
    670 	u8 *len, *len2, *count;
    671 	unsigned int i;
    672 
    673 	len = wpabuf_put(buf, 2); /* OSU Provider Length to be filled */
    674 
    675 	/* OSU Friendly Name Duples */
    676 	len2 = wpabuf_put(buf, 2);
    677 	for (i = 0; i < p->friendly_name_count; i++) {
    678 		struct hostapd_lang_string *s = &p->friendly_name[i];
    679 		wpabuf_put_u8(buf, 3 + s->name_len);
    680 		wpabuf_put_data(buf, s->lang, 3);
    681 		wpabuf_put_data(buf, s->name, s->name_len);
    682 	}
    683 	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);
    684 
    685 	/* OSU Server URI */
    686 	if (p->server_uri) {
    687 		wpabuf_put_u8(buf, os_strlen(p->server_uri));
    688 		wpabuf_put_str(buf, p->server_uri);
    689 	} else
    690 		wpabuf_put_u8(buf, 0);
    691 
    692 	/* OSU Method List */
    693 	count = wpabuf_put(buf, 1);
    694 	for (i = 0; p->method_list && p->method_list[i] >= 0; i++)
    695 		wpabuf_put_u8(buf, p->method_list[i]);
    696 	*count = i;
    697 
    698 	/* Icons Available */
    699 	len2 = wpabuf_put(buf, 2);
    700 	for (i = 0; i < p->icons_count; i++) {
    701 		size_t j;
    702 		struct hs20_icon *icon = NULL;
    703 
    704 		for (j = 0; j < bss->hs20_icons_count && !icon; j++) {
    705 			if (os_strcmp(p->icons[i], bss->hs20_icons[j].name) ==
    706 			    0)
    707 				icon = &bss->hs20_icons[j];
    708 		}
    709 		if (!icon)
    710 			continue; /* icon info not found */
    711 
    712 		wpabuf_put_le16(buf, icon->width);
    713 		wpabuf_put_le16(buf, icon->height);
    714 		wpabuf_put_data(buf, icon->language, 3);
    715 		wpabuf_put_u8(buf, os_strlen(icon->type));
    716 		wpabuf_put_str(buf, icon->type);
    717 		wpabuf_put_u8(buf, os_strlen(icon->name));
    718 		wpabuf_put_str(buf, icon->name);
    719 	}
    720 	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);
    721 
    722 	/* OSU_NAI */
    723 	if (p->osu_nai) {
    724 		wpabuf_put_u8(buf, os_strlen(p->osu_nai));
    725 		wpabuf_put_str(buf, p->osu_nai);
    726 	} else
    727 		wpabuf_put_u8(buf, 0);
    728 
    729 	/* OSU Service Description Duples */
    730 	len2 = wpabuf_put(buf, 2);
    731 	for (i = 0; i < p->service_desc_count; i++) {
    732 		struct hostapd_lang_string *s = &p->service_desc[i];
    733 		wpabuf_put_u8(buf, 3 + s->name_len);
    734 		wpabuf_put_data(buf, s->lang, 3);
    735 		wpabuf_put_data(buf, s->name, s->name_len);
    736 	}
    737 	WPA_PUT_LE16(len2, (u8 *) wpabuf_put(buf, 0) - len2 - 2);
    738 
    739 	WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
    740 }
    741 
    742 
    743 static void anqp_add_osu_providers_list(struct hostapd_data *hapd,
    744 					struct wpabuf *buf)
    745 {
    746 	if (hapd->conf->hs20_osu_providers_count) {
    747 		size_t i;
    748 		u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    749 		wpabuf_put_be24(buf, OUI_WFA);
    750 		wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    751 		wpabuf_put_u8(buf, HS20_STYPE_OSU_PROVIDERS_LIST);
    752 		wpabuf_put_u8(buf, 0); /* Reserved */
    753 
    754 		/* OSU SSID */
    755 		wpabuf_put_u8(buf, hapd->conf->osu_ssid_len);
    756 		wpabuf_put_data(buf, hapd->conf->osu_ssid,
    757 				hapd->conf->osu_ssid_len);
    758 
    759 		/* Number of OSU Providers */
    760 		wpabuf_put_u8(buf, hapd->conf->hs20_osu_providers_count);
    761 
    762 		for (i = 0; i < hapd->conf->hs20_osu_providers_count; i++) {
    763 			anqp_add_osu_provider(
    764 				buf, hapd->conf,
    765 				&hapd->conf->hs20_osu_providers[i]);
    766 		}
    767 
    768 		gas_anqp_set_element_len(buf, len);
    769 	}
    770 }
    771 
    772 
    773 static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
    774 				      struct wpabuf *buf,
    775 				      const u8 *name, size_t name_len)
    776 {
    777 	struct hs20_icon *icon;
    778 	size_t i;
    779 	u8 *len;
    780 
    781 	wpa_hexdump_ascii(MSG_DEBUG, "HS 2.0: Requested Icon Filename",
    782 			  name, name_len);
    783 	for (i = 0; i < hapd->conf->hs20_icons_count; i++) {
    784 		icon = &hapd->conf->hs20_icons[i];
    785 		if (name_len == os_strlen(icon->name) &&
    786 		    os_memcmp(name, icon->name, name_len) == 0)
    787 			break;
    788 	}
    789 
    790 	if (i < hapd->conf->hs20_icons_count)
    791 		icon = &hapd->conf->hs20_icons[i];
    792 	else
    793 		icon = NULL;
    794 
    795 	len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
    796 	wpabuf_put_be24(buf, OUI_WFA);
    797 	wpabuf_put_u8(buf, HS20_ANQP_OUI_TYPE);
    798 	wpabuf_put_u8(buf, HS20_STYPE_ICON_BINARY_FILE);
    799 	wpabuf_put_u8(buf, 0); /* Reserved */
    800 
    801 	if (icon) {
    802 		char *data;
    803 		size_t data_len;
    804 
    805 		data = os_readfile(icon->file, &data_len);
    806 		if (data == NULL || data_len > 65535) {
    807 			wpabuf_put_u8(buf, 2); /* Download Status:
    808 						* Unspecified file error */
    809 			wpabuf_put_u8(buf, 0);
    810 			wpabuf_put_le16(buf, 0);
    811 		} else {
    812 			wpabuf_put_u8(buf, 0); /* Download Status: Success */
    813 			wpabuf_put_u8(buf, os_strlen(icon->type));
    814 			wpabuf_put_str(buf, icon->type);
    815 			wpabuf_put_le16(buf, data_len);
    816 			wpabuf_put_data(buf, data, data_len);
    817 		}
    818 		os_free(data);
    819 	} else {
    820 		wpabuf_put_u8(buf, 1); /* Download Status: File not found */
    821 		wpabuf_put_u8(buf, 0);
    822 		wpabuf_put_le16(buf, 0);
    823 	}
    824 
    825 	gas_anqp_set_element_len(buf, len);
    826 }
    827 
    828 #endif /* CONFIG_HS20 */
    829 
    830 
    831 static size_t anqp_get_required_len(struct hostapd_data *hapd,
    832 				    const u16 *infoid,
    833 				    unsigned int num_infoid)
    834 {
    835 	size_t len = 0;
    836 	unsigned int i;
    837 
    838 	for (i = 0; i < num_infoid; i++) {
    839 		struct anqp_element *elem = get_anqp_elem(hapd, infoid[i]);
    840 
    841 		if (elem)
    842 			len += 2 + 2 + wpabuf_len(elem->payload);
    843 	}
    844 
    845 	return len;
    846 }
    847 
    848 
    849 static struct wpabuf *
    850 gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
    851 				unsigned int request,
    852 				const u8 *home_realm, size_t home_realm_len,
    853 				const u8 *icon_name, size_t icon_name_len,
    854 				const u16 *extra_req,
    855 				unsigned int num_extra_req)
    856 {
    857 	struct wpabuf *buf;
    858 	size_t len;
    859 	unsigned int i;
    860 
    861 	len = 1400;
    862 	if (request & (ANQP_REQ_NAI_REALM | ANQP_REQ_NAI_HOME_REALM))
    863 		len += 1000;
    864 	if (request & ANQP_REQ_ICON_REQUEST)
    865 		len += 65536;
    866 #ifdef CONFIG_FILS
    867 	if (request & ANQP_FILS_REALM_INFO)
    868 		len += 2 * dl_list_len(&hapd->conf->fils_realms);
    869 #endif /* CONFIG_FILS */
    870 	len += anqp_get_required_len(hapd, extra_req, num_extra_req);
    871 
    872 	buf = wpabuf_alloc(len);
    873 	if (buf == NULL)
    874 		return NULL;
    875 
    876 	if (request & ANQP_REQ_CAPABILITY_LIST)
    877 		anqp_add_capab_list(hapd, buf);
    878 	if (request & ANQP_REQ_VENUE_NAME)
    879 		anqp_add_venue_name(hapd, buf);
    880 	if (request & ANQP_REQ_EMERGENCY_CALL_NUMBER)
    881 		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_CALL_NUMBER);
    882 	if (request & ANQP_REQ_NETWORK_AUTH_TYPE)
    883 		anqp_add_network_auth_type(hapd, buf);
    884 	if (request & ANQP_REQ_ROAMING_CONSORTIUM)
    885 		anqp_add_roaming_consortium(hapd, buf);
    886 	if (request & ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY)
    887 		anqp_add_ip_addr_type_availability(hapd, buf);
    888 	if (request & (ANQP_REQ_NAI_REALM | ANQP_REQ_NAI_HOME_REALM))
    889 		anqp_add_nai_realm(hapd, buf, home_realm, home_realm_len,
    890 				   request & ANQP_REQ_NAI_REALM,
    891 				   request & ANQP_REQ_NAI_HOME_REALM);
    892 	if (request & ANQP_REQ_3GPP_CELLULAR_NETWORK)
    893 		anqp_add_3gpp_cellular_network(hapd, buf);
    894 	if (request & ANQP_REQ_AP_GEOSPATIAL_LOCATION)
    895 		anqp_add_elem(hapd, buf, ANQP_AP_GEOSPATIAL_LOCATION);
    896 	if (request & ANQP_REQ_AP_CIVIC_LOCATION)
    897 		anqp_add_elem(hapd, buf, ANQP_AP_CIVIC_LOCATION);
    898 	if (request & ANQP_REQ_AP_LOCATION_PUBLIC_URI)
    899 		anqp_add_elem(hapd, buf, ANQP_AP_LOCATION_PUBLIC_URI);
    900 	if (request & ANQP_REQ_DOMAIN_NAME)
    901 		anqp_add_domain_name(hapd, buf);
    902 	if (request & ANQP_REQ_EMERGENCY_ALERT_URI)
    903 		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_ALERT_URI);
    904 	if (request & ANQP_REQ_TDLS_CAPABILITY)
    905 		anqp_add_elem(hapd, buf, ANQP_TDLS_CAPABILITY);
    906 	if (request & ANQP_REQ_EMERGENCY_NAI)
    907 		anqp_add_elem(hapd, buf, ANQP_EMERGENCY_NAI);
    908 
    909 	for (i = 0; i < num_extra_req; i++) {
    910 #ifdef CONFIG_FILS
    911 		if (extra_req[i] == ANQP_FILS_REALM_INFO) {
    912 			anqp_add_fils_realm_info(hapd, buf);
    913 			continue;
    914 		}
    915 #endif /* CONFIG_FILS */
    916 		anqp_add_elem(hapd, buf, extra_req[i]);
    917 	}
    918 
    919 #ifdef CONFIG_HS20
    920 	if (request & ANQP_REQ_HS_CAPABILITY_LIST)
    921 		anqp_add_hs_capab_list(hapd, buf);
    922 	if (request & ANQP_REQ_OPERATOR_FRIENDLY_NAME)
    923 		anqp_add_operator_friendly_name(hapd, buf);
    924 	if (request & ANQP_REQ_WAN_METRICS)
    925 		anqp_add_wan_metrics(hapd, buf);
    926 	if (request & ANQP_REQ_CONNECTION_CAPABILITY)
    927 		anqp_add_connection_capability(hapd, buf);
    928 	if (request & ANQP_REQ_OPERATING_CLASS)
    929 		anqp_add_operating_class(hapd, buf);
    930 	if (request & ANQP_REQ_OSU_PROVIDERS_LIST)
    931 		anqp_add_osu_providers_list(hapd, buf);
    932 	if (request & ANQP_REQ_ICON_REQUEST)
    933 		anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
    934 #endif /* CONFIG_HS20 */
    935 
    936 	return buf;
    937 }
    938 
    939 
    940 #define ANQP_MAX_EXTRA_REQ 20
    941 
    942 struct anqp_query_info {
    943 	unsigned int request;
    944 	const u8 *home_realm_query;
    945 	size_t home_realm_query_len;
    946 	const u8 *icon_name;
    947 	size_t icon_name_len;
    948 	int p2p_sd;
    949 	u16 extra_req[ANQP_MAX_EXTRA_REQ];
    950 	unsigned int num_extra_req;
    951 };
    952 
    953 
    954 static void set_anqp_req(unsigned int bit, const char *name, int local,
    955 			 struct anqp_query_info *qi)
    956 {
    957 	qi->request |= bit;
    958 	if (local) {
    959 		wpa_printf(MSG_DEBUG, "ANQP: %s (local)", name);
    960 	} else {
    961 		wpa_printf(MSG_DEBUG, "ANQP: %s not available", name);
    962 	}
    963 }
    964 
    965 
    966 static void rx_anqp_query_list_id(struct hostapd_data *hapd, u16 info_id,
    967 				  struct anqp_query_info *qi)
    968 {
    969 	switch (info_id) {
    970 	case ANQP_CAPABILITY_LIST:
    971 		set_anqp_req(ANQP_REQ_CAPABILITY_LIST, "Capability List", 1,
    972 			     qi);
    973 		break;
    974 	case ANQP_VENUE_NAME:
    975 		set_anqp_req(ANQP_REQ_VENUE_NAME, "Venue Name",
    976 			     hapd->conf->venue_name != NULL, qi);
    977 		break;
    978 	case ANQP_EMERGENCY_CALL_NUMBER:
    979 		set_anqp_req(ANQP_REQ_EMERGENCY_CALL_NUMBER,
    980 			     "Emergency Call Number",
    981 			     get_anqp_elem(hapd, info_id) != NULL, qi);
    982 		break;
    983 	case ANQP_NETWORK_AUTH_TYPE:
    984 		set_anqp_req(ANQP_REQ_NETWORK_AUTH_TYPE, "Network Auth Type",
    985 			     hapd->conf->network_auth_type != NULL, qi);
    986 		break;
    987 	case ANQP_ROAMING_CONSORTIUM:
    988 		set_anqp_req(ANQP_REQ_ROAMING_CONSORTIUM, "Roaming Consortium",
    989 			     hapd->conf->roaming_consortium != NULL, qi);
    990 		break;
    991 	case ANQP_IP_ADDR_TYPE_AVAILABILITY:
    992 		set_anqp_req(ANQP_REQ_IP_ADDR_TYPE_AVAILABILITY,
    993 			     "IP Addr Type Availability",
    994 			     hapd->conf->ipaddr_type_configured, qi);
    995 		break;
    996 	case ANQP_NAI_REALM:
    997 		set_anqp_req(ANQP_REQ_NAI_REALM, "NAI Realm",
    998 			     hapd->conf->nai_realm_data != NULL, qi);
    999 		break;
   1000 	case ANQP_3GPP_CELLULAR_NETWORK:
   1001 		set_anqp_req(ANQP_REQ_3GPP_CELLULAR_NETWORK,
   1002 			     "3GPP Cellular Network",
   1003 			     hapd->conf->anqp_3gpp_cell_net != NULL, qi);
   1004 		break;
   1005 	case ANQP_AP_GEOSPATIAL_LOCATION:
   1006 		set_anqp_req(ANQP_REQ_AP_GEOSPATIAL_LOCATION,
   1007 			     "AP Geospatial Location",
   1008 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1009 		break;
   1010 	case ANQP_AP_CIVIC_LOCATION:
   1011 		set_anqp_req(ANQP_REQ_AP_CIVIC_LOCATION,
   1012 			     "AP Civic Location",
   1013 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1014 		break;
   1015 	case ANQP_AP_LOCATION_PUBLIC_URI:
   1016 		set_anqp_req(ANQP_REQ_AP_LOCATION_PUBLIC_URI,
   1017 			     "AP Location Public URI",
   1018 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1019 		break;
   1020 	case ANQP_DOMAIN_NAME:
   1021 		set_anqp_req(ANQP_REQ_DOMAIN_NAME, "Domain Name",
   1022 			     hapd->conf->domain_name != NULL, qi);
   1023 		break;
   1024 	case ANQP_EMERGENCY_ALERT_URI:
   1025 		set_anqp_req(ANQP_REQ_EMERGENCY_ALERT_URI,
   1026 			     "Emergency Alert URI",
   1027 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1028 		break;
   1029 	case ANQP_TDLS_CAPABILITY:
   1030 		set_anqp_req(ANQP_REQ_TDLS_CAPABILITY,
   1031 			     "TDLS Capability",
   1032 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1033 		break;
   1034 	case ANQP_EMERGENCY_NAI:
   1035 		set_anqp_req(ANQP_REQ_EMERGENCY_NAI,
   1036 			     "Emergency NAI",
   1037 			     get_anqp_elem(hapd, info_id) != NULL, qi);
   1038 		break;
   1039 	default:
   1040 #ifdef CONFIG_FILS
   1041 		if (info_id == ANQP_FILS_REALM_INFO &&
   1042 		    !dl_list_empty(&hapd->conf->fils_realms)) {
   1043 			wpa_printf(MSG_DEBUG,
   1044 				   "ANQP: FILS Realm Information (local)");
   1045 		} else
   1046 #endif /* CONFIG_FILS */
   1047 		if (!get_anqp_elem(hapd, info_id)) {
   1048 			wpa_printf(MSG_DEBUG, "ANQP: Unsupported Info Id %u",
   1049 				   info_id);
   1050 			break;
   1051 		}
   1052 		if (qi->num_extra_req == ANQP_MAX_EXTRA_REQ) {
   1053 			wpa_printf(MSG_DEBUG,
   1054 				   "ANQP: No more room for extra requests - ignore Info Id %u",
   1055 				   info_id);
   1056 			break;
   1057 		}
   1058 		wpa_printf(MSG_DEBUG, "ANQP: Info Id %u (local)", info_id);
   1059 		qi->extra_req[qi->num_extra_req] = info_id;
   1060 		qi->num_extra_req++;
   1061 		break;
   1062 	}
   1063 }
   1064 
   1065 
   1066 static void rx_anqp_query_list(struct hostapd_data *hapd,
   1067 			       const u8 *pos, const u8 *end,
   1068 			       struct anqp_query_info *qi)
   1069 {
   1070 	wpa_printf(MSG_DEBUG, "ANQP: %u Info IDs requested in Query list",
   1071 		   (unsigned int) (end - pos) / 2);
   1072 
   1073 	while (end - pos >= 2) {
   1074 		rx_anqp_query_list_id(hapd, WPA_GET_LE16(pos), qi);
   1075 		pos += 2;
   1076 	}
   1077 }
   1078 
   1079 
   1080 #ifdef CONFIG_HS20
   1081 
   1082 static void rx_anqp_hs_query_list(struct hostapd_data *hapd, u8 subtype,
   1083 				  struct anqp_query_info *qi)
   1084 {
   1085 	switch (subtype) {
   1086 	case HS20_STYPE_CAPABILITY_LIST:
   1087 		set_anqp_req(ANQP_REQ_HS_CAPABILITY_LIST, "HS Capability List",
   1088 			     1, qi);
   1089 		break;
   1090 	case HS20_STYPE_OPERATOR_FRIENDLY_NAME:
   1091 		set_anqp_req(ANQP_REQ_OPERATOR_FRIENDLY_NAME,
   1092 			     "Operator Friendly Name",
   1093 			     hapd->conf->hs20_oper_friendly_name != NULL, qi);
   1094 		break;
   1095 	case HS20_STYPE_WAN_METRICS:
   1096 		set_anqp_req(ANQP_REQ_WAN_METRICS, "WAN Metrics",
   1097 			     hapd->conf->hs20_wan_metrics != NULL, qi);
   1098 		break;
   1099 	case HS20_STYPE_CONNECTION_CAPABILITY:
   1100 		set_anqp_req(ANQP_REQ_CONNECTION_CAPABILITY,
   1101 			     "Connection Capability",
   1102 			     hapd->conf->hs20_connection_capability != NULL,
   1103 			     qi);
   1104 		break;
   1105 	case HS20_STYPE_OPERATING_CLASS:
   1106 		set_anqp_req(ANQP_REQ_OPERATING_CLASS, "Operating Class",
   1107 			     hapd->conf->hs20_operating_class != NULL, qi);
   1108 		break;
   1109 	case HS20_STYPE_OSU_PROVIDERS_LIST:
   1110 		set_anqp_req(ANQP_REQ_OSU_PROVIDERS_LIST, "OSU Providers list",
   1111 			     hapd->conf->hs20_osu_providers_count, qi);
   1112 		break;
   1113 	default:
   1114 		wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 subtype %u",
   1115 			   subtype);
   1116 		break;
   1117 	}
   1118 }
   1119 
   1120 
   1121 static void rx_anqp_hs_nai_home_realm(struct hostapd_data *hapd,
   1122 				      const u8 *pos, const u8 *end,
   1123 				      struct anqp_query_info *qi)
   1124 {
   1125 	qi->request |= ANQP_REQ_NAI_HOME_REALM;
   1126 	qi->home_realm_query = pos;
   1127 	qi->home_realm_query_len = end - pos;
   1128 	if (hapd->conf->nai_realm_data != NULL) {
   1129 		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 NAI Home Realm Query "
   1130 			   "(local)");
   1131 	} else {
   1132 		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 NAI Home Realm Query not "
   1133 			   "available");
   1134 	}
   1135 }
   1136 
   1137 
   1138 static void rx_anqp_hs_icon_request(struct hostapd_data *hapd,
   1139 				    const u8 *pos, const u8 *end,
   1140 				    struct anqp_query_info *qi)
   1141 {
   1142 	qi->request |= ANQP_REQ_ICON_REQUEST;
   1143 	qi->icon_name = pos;
   1144 	qi->icon_name_len = end - pos;
   1145 	if (hapd->conf->hs20_icons_count) {
   1146 		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Icon Request Query "
   1147 			   "(local)");
   1148 	} else {
   1149 		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Icon Request Query not "
   1150 			   "available");
   1151 	}
   1152 }
   1153 
   1154 
   1155 static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
   1156 				    const u8 *pos, const u8 *end,
   1157 				    struct anqp_query_info *qi)
   1158 {
   1159 	u32 oui;
   1160 	u8 subtype;
   1161 
   1162 	if (end - pos < 4) {
   1163 		wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
   1164 			   "Query element");
   1165 		return;
   1166 	}
   1167 
   1168 	oui = WPA_GET_BE24(pos);
   1169 	pos += 3;
   1170 	if (oui != OUI_WFA) {
   1171 		wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
   1172 			   oui);
   1173 		return;
   1174 	}
   1175 
   1176 #ifdef CONFIG_P2P
   1177 	if (*pos == P2P_OUI_TYPE) {
   1178 		/*
   1179 		 * This is for P2P SD and will be taken care of by the P2P
   1180 		 * implementation. This query needs to be ignored in the generic
   1181 		 * GAS server to avoid duplicated response.
   1182 		 */
   1183 		wpa_printf(MSG_DEBUG,
   1184 			   "ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
   1185 			   *pos);
   1186 		qi->p2p_sd = 1;
   1187 		return;
   1188 	}
   1189 #endif /* CONFIG_P2P */
   1190 
   1191 	if (*pos != HS20_ANQP_OUI_TYPE) {
   1192 		wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
   1193 			   *pos);
   1194 		return;
   1195 	}
   1196 	pos++;
   1197 
   1198 	if (end - pos <= 1)
   1199 		return;
   1200 
   1201 	subtype = *pos++;
   1202 	pos++; /* Reserved */
   1203 	switch (subtype) {
   1204 	case HS20_STYPE_QUERY_LIST:
   1205 		wpa_printf(MSG_DEBUG, "ANQP: HS 2.0 Query List");
   1206 		while (pos < end) {
   1207 			rx_anqp_hs_query_list(hapd, *pos, qi);
   1208 			pos++;
   1209 		}
   1210 		break;
   1211 	case HS20_STYPE_NAI_HOME_REALM_QUERY:
   1212 		rx_anqp_hs_nai_home_realm(hapd, pos, end, qi);
   1213 		break;
   1214 	case HS20_STYPE_ICON_REQUEST:
   1215 		rx_anqp_hs_icon_request(hapd, pos, end, qi);
   1216 		break;
   1217 	default:
   1218 		wpa_printf(MSG_DEBUG, "ANQP: Unsupported HS 2.0 query subtype "
   1219 			   "%u", subtype);
   1220 		break;
   1221 	}
   1222 }
   1223 
   1224 #endif /* CONFIG_HS20 */
   1225 
   1226 
   1227 static void gas_serv_req_local_processing(struct hostapd_data *hapd,
   1228 					  const u8 *sa, u8 dialog_token,
   1229 					  struct anqp_query_info *qi, int prot,
   1230 					  int std_addr3)
   1231 {
   1232 	struct wpabuf *buf, *tx_buf;
   1233 
   1234 	buf = gas_serv_build_gas_resp_payload(hapd, qi->request,
   1235 					      qi->home_realm_query,
   1236 					      qi->home_realm_query_len,
   1237 					      qi->icon_name, qi->icon_name_len,
   1238 					      qi->extra_req, qi->num_extra_req);
   1239 	wpa_hexdump_buf(MSG_MSGDUMP, "ANQP: Locally generated ANQP responses",
   1240 			buf);
   1241 	if (!buf)
   1242 		return;
   1243 #ifdef CONFIG_P2P
   1244 	if (wpabuf_len(buf) == 0 && qi->p2p_sd) {
   1245 		wpa_printf(MSG_DEBUG,
   1246 			   "ANQP: Do not send response to P2P SD from generic GAS service (P2P SD implementation will process this)");
   1247 		wpabuf_free(buf);
   1248 		return;
   1249 	}
   1250 #endif /* CONFIG_P2P */
   1251 
   1252 	if (wpabuf_len(buf) > hapd->conf->gas_frag_limit ||
   1253 	    hapd->conf->gas_comeback_delay) {
   1254 		struct gas_dialog_info *di;
   1255 		u16 comeback_delay = 1;
   1256 
   1257 		if (hapd->conf->gas_comeback_delay) {
   1258 			/* Testing - allow overriding of the delay value */
   1259 			comeback_delay = hapd->conf->gas_comeback_delay;
   1260 		}
   1261 
   1262 		wpa_printf(MSG_DEBUG, "ANQP: Too long response to fit in "
   1263 			   "initial response - use GAS comeback");
   1264 		di = gas_dialog_create(hapd, sa, dialog_token);
   1265 		if (!di) {
   1266 			wpa_printf(MSG_INFO, "ANQP: Could not create dialog "
   1267 				   "for " MACSTR " (dialog token %u)",
   1268 				   MAC2STR(sa), dialog_token);
   1269 			wpabuf_free(buf);
   1270 			tx_buf = gas_anqp_build_initial_resp_buf(
   1271 				dialog_token, WLAN_STATUS_UNSPECIFIED_FAILURE,
   1272 				0, NULL);
   1273 		} else {
   1274 			di->prot = prot;
   1275 			di->sd_resp = buf;
   1276 			di->sd_resp_pos = 0;
   1277 			tx_buf = gas_anqp_build_initial_resp_buf(
   1278 				dialog_token, WLAN_STATUS_SUCCESS,
   1279 				comeback_delay, NULL);
   1280 		}
   1281 	} else {
   1282 		wpa_printf(MSG_DEBUG, "ANQP: Initial response (no comeback)");
   1283 		tx_buf = gas_anqp_build_initial_resp_buf(
   1284 			dialog_token, WLAN_STATUS_SUCCESS, 0, buf);
   1285 		wpabuf_free(buf);
   1286 	}
   1287 	if (!tx_buf)
   1288 		return;
   1289 	if (prot)
   1290 		convert_to_protected_dual(tx_buf);
   1291 	if (std_addr3)
   1292 		hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
   1293 					wpabuf_head(tx_buf),
   1294 					wpabuf_len(tx_buf));
   1295 	else
   1296 		hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa,
   1297 						 wpabuf_head(tx_buf),
   1298 						 wpabuf_len(tx_buf));
   1299 	wpabuf_free(tx_buf);
   1300 }
   1301 
   1302 
   1303 static void gas_serv_rx_gas_initial_req(struct hostapd_data *hapd,
   1304 					const u8 *sa,
   1305 					const u8 *data, size_t len, int prot,
   1306 					int std_addr3)
   1307 {
   1308 	const u8 *pos = data;
   1309 	const u8 *end = data + len;
   1310 	const u8 *next;
   1311 	u8 dialog_token;
   1312 	u16 slen;
   1313 	struct anqp_query_info qi;
   1314 	const u8 *adv_proto;
   1315 
   1316 	if (len < 1 + 2)
   1317 		return;
   1318 
   1319 	os_memset(&qi, 0, sizeof(qi));
   1320 
   1321 	dialog_token = *pos++;
   1322 	wpa_msg(hapd->msg_ctx, MSG_DEBUG,
   1323 		"GAS: GAS Initial Request from " MACSTR " (dialog token %u) ",
   1324 		MAC2STR(sa), dialog_token);
   1325 
   1326 	if (*pos != WLAN_EID_ADV_PROTO) {
   1327 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
   1328 			"GAS: Unexpected IE in GAS Initial Request: %u", *pos);
   1329 		return;
   1330 	}
   1331 	adv_proto = pos++;
   1332 
   1333 	slen = *pos++;
   1334 	if (slen > end - pos || slen < 2) {
   1335 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
   1336 			"GAS: Invalid IE in GAS Initial Request");
   1337 		return;
   1338 	}
   1339 	next = pos + slen;
   1340 	pos++; /* skip QueryRespLenLimit and PAME-BI */
   1341 
   1342 	if (*pos != ACCESS_NETWORK_QUERY_PROTOCOL) {
   1343 		struct wpabuf *buf;
   1344 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
   1345 			"GAS: Unsupported GAS advertisement protocol id %u",
   1346 			*pos);
   1347 		if (sa[0] & 0x01)
   1348 			return; /* Invalid source address - drop silently */
   1349 		buf = gas_build_initial_resp(
   1350 			dialog_token, WLAN_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED,
   1351 			0, 2 + slen + 2);
   1352 		if (buf == NULL)
   1353 			return;
   1354 		wpabuf_put_data(buf, adv_proto, 2 + slen);
   1355 		wpabuf_put_le16(buf, 0); /* Query Response Length */
   1356 		if (prot)
   1357 			convert_to_protected_dual(buf);
   1358 		if (std_addr3)
   1359 			hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
   1360 						wpabuf_head(buf),
   1361 						wpabuf_len(buf));
   1362 		else
   1363 			hostapd_drv_send_action_addr3_ap(hapd,
   1364 							 hapd->iface->freq, 0,
   1365 							 sa, wpabuf_head(buf),
   1366 							 wpabuf_len(buf));
   1367 		wpabuf_free(buf);
   1368 		return;
   1369 	}
   1370 
   1371 	pos = next;
   1372 	/* Query Request */
   1373 	if (end - pos < 2)
   1374 		return;
   1375 	slen = WPA_GET_LE16(pos);
   1376 	pos += 2;
   1377 	if (slen > end - pos)
   1378 		return;
   1379 	end = pos + slen;
   1380 
   1381 	/* ANQP Query Request */
   1382 	while (pos < end) {
   1383 		u16 info_id, elen;
   1384 
   1385 		if (end - pos < 4)
   1386 			return;
   1387 
   1388 		info_id = WPA_GET_LE16(pos);
   1389 		pos += 2;
   1390 		elen = WPA_GET_LE16(pos);
   1391 		pos += 2;
   1392 
   1393 		if (elen > end - pos) {
   1394 			wpa_printf(MSG_DEBUG, "ANQP: Invalid Query Request");
   1395 			return;
   1396 		}
   1397 
   1398 		switch (info_id) {
   1399 		case ANQP_QUERY_LIST:
   1400 			rx_anqp_query_list(hapd, pos, pos + elen, &qi);
   1401 			break;
   1402 #ifdef CONFIG_HS20
   1403 		case ANQP_VENDOR_SPECIFIC:
   1404 			rx_anqp_vendor_specific(hapd, pos, pos + elen, &qi);
   1405 			break;
   1406 #endif /* CONFIG_HS20 */
   1407 		default:
   1408 			wpa_printf(MSG_DEBUG, "ANQP: Unsupported Query "
   1409 				   "Request element %u", info_id);
   1410 			break;
   1411 		}
   1412 
   1413 		pos += elen;
   1414 	}
   1415 
   1416 	gas_serv_req_local_processing(hapd, sa, dialog_token, &qi, prot,
   1417 				      std_addr3);
   1418 }
   1419 
   1420 
   1421 static void gas_serv_rx_gas_comeback_req(struct hostapd_data *hapd,
   1422 					 const u8 *sa,
   1423 					 const u8 *data, size_t len, int prot,
   1424 					 int std_addr3)
   1425 {
   1426 	struct gas_dialog_info *dialog;
   1427 	struct wpabuf *buf, *tx_buf;
   1428 	u8 dialog_token;
   1429 	size_t frag_len;
   1430 	int more = 0;
   1431 
   1432 	wpa_hexdump(MSG_DEBUG, "GAS: RX GAS Comeback Request", data, len);
   1433 	if (len < 1)
   1434 		return;
   1435 	dialog_token = *data;
   1436 	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Dialog Token: %u",
   1437 		dialog_token);
   1438 
   1439 	dialog = gas_serv_dialog_find(hapd, sa, dialog_token);
   1440 	if (!dialog) {
   1441 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: No pending SD "
   1442 			"response fragment for " MACSTR " dialog token %u",
   1443 			MAC2STR(sa), dialog_token);
   1444 
   1445 		if (sa[0] & 0x01)
   1446 			return; /* Invalid source address - drop silently */
   1447 		tx_buf = gas_anqp_build_comeback_resp_buf(
   1448 			dialog_token, WLAN_STATUS_NO_OUTSTANDING_GAS_REQ, 0, 0,
   1449 			0, NULL);
   1450 		if (tx_buf == NULL)
   1451 			return;
   1452 		goto send_resp;
   1453 	}
   1454 
   1455 	frag_len = wpabuf_len(dialog->sd_resp) - dialog->sd_resp_pos;
   1456 	if (frag_len > hapd->conf->gas_frag_limit) {
   1457 		frag_len = hapd->conf->gas_frag_limit;
   1458 		more = 1;
   1459 	}
   1460 	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: resp frag_len %u",
   1461 		(unsigned int) frag_len);
   1462 	buf = wpabuf_alloc_copy(wpabuf_head_u8(dialog->sd_resp) +
   1463 				dialog->sd_resp_pos, frag_len);
   1464 	if (buf == NULL) {
   1465 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Failed to allocate "
   1466 			"buffer");
   1467 		gas_serv_dialog_clear(dialog);
   1468 		return;
   1469 	}
   1470 	tx_buf = gas_anqp_build_comeback_resp_buf(dialog_token,
   1471 						  WLAN_STATUS_SUCCESS,
   1472 						  dialog->sd_frag_id,
   1473 						  more, 0, buf);
   1474 	wpabuf_free(buf);
   1475 	if (tx_buf == NULL) {
   1476 		gas_serv_dialog_clear(dialog);
   1477 		return;
   1478 	}
   1479 	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: Tx GAS Comeback Response "
   1480 		"(frag_id %d more=%d frag_len=%d)",
   1481 		dialog->sd_frag_id, more, (int) frag_len);
   1482 	dialog->sd_frag_id++;
   1483 	dialog->sd_resp_pos += frag_len;
   1484 
   1485 	if (more) {
   1486 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: %d more bytes remain "
   1487 			"to be sent",
   1488 			(int) (wpabuf_len(dialog->sd_resp) -
   1489 			       dialog->sd_resp_pos));
   1490 	} else {
   1491 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "GAS: All fragments of "
   1492 			"SD response sent");
   1493 		gas_serv_dialog_clear(dialog);
   1494 		gas_serv_free_dialogs(hapd, sa);
   1495 	}
   1496 
   1497 send_resp:
   1498 	if (prot)
   1499 		convert_to_protected_dual(tx_buf);
   1500 	if (std_addr3)
   1501 		hostapd_drv_send_action(hapd, hapd->iface->freq, 0, sa,
   1502 					wpabuf_head(tx_buf),
   1503 					wpabuf_len(tx_buf));
   1504 	else
   1505 		hostapd_drv_send_action_addr3_ap(hapd, hapd->iface->freq, 0, sa,
   1506 						 wpabuf_head(tx_buf),
   1507 						 wpabuf_len(tx_buf));
   1508 	wpabuf_free(tx_buf);
   1509 }
   1510 
   1511 
   1512 static void gas_serv_rx_public_action(void *ctx, const u8 *buf, size_t len,
   1513 				      int freq)
   1514 {
   1515 	struct hostapd_data *hapd = ctx;
   1516 	const struct ieee80211_mgmt *mgmt;
   1517 	const u8 *sa, *data;
   1518 	int prot, std_addr3;
   1519 
   1520 	mgmt = (const struct ieee80211_mgmt *) buf;
   1521 	if (len < IEEE80211_HDRLEN + 2)
   1522 		return;
   1523 	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
   1524 	    mgmt->u.action.category != WLAN_ACTION_PROTECTED_DUAL)
   1525 		return;
   1526 	/*
   1527 	 * Note: Public Action and Protected Dual of Public Action frames share
   1528 	 * the same payload structure, so it is fine to use definitions of
   1529 	 * Public Action frames to process both.
   1530 	 */
   1531 	prot = mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL;
   1532 	sa = mgmt->sa;
   1533 	if (hapd->conf->gas_address3 == 1)
   1534 		std_addr3 = 1;
   1535 	else if (hapd->conf->gas_address3 == 2)
   1536 		std_addr3 = 0;
   1537 	else
   1538 		std_addr3 = is_broadcast_ether_addr(mgmt->bssid);
   1539 	len -= IEEE80211_HDRLEN + 1;
   1540 	data = buf + IEEE80211_HDRLEN + 1;
   1541 	switch (data[0]) {
   1542 	case WLAN_PA_GAS_INITIAL_REQ:
   1543 		gas_serv_rx_gas_initial_req(hapd, sa, data + 1, len - 1, prot,
   1544 					    std_addr3);
   1545 		break;
   1546 	case WLAN_PA_GAS_COMEBACK_REQ:
   1547 		gas_serv_rx_gas_comeback_req(hapd, sa, data + 1, len - 1, prot,
   1548 					     std_addr3);
   1549 		break;
   1550 	}
   1551 }
   1552 
   1553 
   1554 int gas_serv_init(struct hostapd_data *hapd)
   1555 {
   1556 	hapd->public_action_cb2 = gas_serv_rx_public_action;
   1557 	hapd->public_action_cb2_ctx = hapd;
   1558 	return 0;
   1559 }
   1560 
   1561 
   1562 void gas_serv_deinit(struct hostapd_data *hapd)
   1563 {
   1564 }
   1565