Home | History | Annotate | Download | only in ap
      1 /*
      2  * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
      3  * Copyright (c) 2002-2004, Instant802 Networks, Inc.
      4  * Copyright (c) 2005-2006, Devicescape Software, Inc.
      5  * Copyright (c) 2008-2009, Jouni Malinen <j (at) w1.fi>
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License version 2 as
      9  * published by the Free Software Foundation.
     10  *
     11  * Alternatively, this software may be distributed under the terms of BSD
     12  * license.
     13  *
     14  * See README and COPYING for more details.
     15  */
     16 
     17 #include "utils/includes.h"
     18 
     19 #ifndef CONFIG_NATIVE_WINDOWS
     20 
     21 #include "utils/common.h"
     22 #include "common/ieee802_11_defs.h"
     23 #include "common/ieee802_11_common.h"
     24 #include "drivers/driver.h"
     25 #include "wps/wps_defs.h"
     26 #include "p2p/p2p.h"
     27 #include "hostapd.h"
     28 #include "ieee802_11.h"
     29 #include "wpa_auth.h"
     30 #include "wmm.h"
     31 #include "ap_config.h"
     32 #include "sta_info.h"
     33 #include "p2p_hostapd.h"
     34 #include "ap_drv_ops.h"
     35 #include "beacon.h"
     36 
     37 
     38 #ifdef NEED_AP_MLME
     39 
     40 static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
     41 {
     42 	u8 erp = 0;
     43 
     44 	if (hapd->iface->current_mode == NULL ||
     45 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
     46 		return 0;
     47 
     48 	if (hapd->iface->olbc)
     49 		erp |= ERP_INFO_USE_PROTECTION;
     50 	if (hapd->iface->num_sta_non_erp > 0) {
     51 		erp |= ERP_INFO_NON_ERP_PRESENT |
     52 			ERP_INFO_USE_PROTECTION;
     53 	}
     54 	if (hapd->iface->num_sta_no_short_preamble > 0 ||
     55 	    hapd->iconf->preamble == LONG_PREAMBLE)
     56 		erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
     57 
     58 	return erp;
     59 }
     60 
     61 
     62 static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
     63 {
     64 	*eid++ = WLAN_EID_DS_PARAMS;
     65 	*eid++ = 1;
     66 	*eid++ = hapd->iconf->channel;
     67 	return eid;
     68 }
     69 
     70 
     71 static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
     72 {
     73 	if (hapd->iface->current_mode == NULL ||
     74 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
     75 		return eid;
     76 
     77 	/* Set NonERP_present and use_protection bits if there
     78 	 * are any associated NonERP stations. */
     79 	/* TODO: use_protection bit can be set to zero even if
     80 	 * there are NonERP stations present. This optimization
     81 	 * might be useful if NonERP stations are "quiet".
     82 	 * See 802.11g/D6 E-1 for recommended practice.
     83 	 * In addition, Non ERP present might be set, if AP detects Non ERP
     84 	 * operation on other APs. */
     85 
     86 	/* Add ERP Information element */
     87 	*eid++ = WLAN_EID_ERP_INFO;
     88 	*eid++ = 1;
     89 	*eid++ = ieee802_11_erp_info(hapd);
     90 
     91 	return eid;
     92 }
     93 
     94 
     95 static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
     96 				    struct hostapd_channel_data *start,
     97 				    struct hostapd_channel_data *prev)
     98 {
     99 	if (end - pos < 3)
    100 		return pos;
    101 
    102 	/* first channel number */
    103 	*pos++ = start->chan;
    104 	/* number of channels */
    105 	*pos++ = (prev->chan - start->chan) / chan_spacing + 1;
    106 	/* maximum transmit power level */
    107 	*pos++ = start->max_tx_power;
    108 
    109 	return pos;
    110 }
    111 
    112 
    113 static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
    114 				int max_len)
    115 {
    116 	u8 *pos = eid;
    117 	u8 *end = eid + max_len;
    118 	int i;
    119 	struct hostapd_hw_modes *mode;
    120 	struct hostapd_channel_data *start, *prev;
    121 	int chan_spacing = 1;
    122 
    123 	if (!hapd->iconf->ieee80211d || max_len < 6 ||
    124 	    hapd->iface->current_mode == NULL)
    125 		return eid;
    126 
    127 	*pos++ = WLAN_EID_COUNTRY;
    128 	pos++; /* length will be set later */
    129 	os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
    130 	pos += 3;
    131 
    132 	mode = hapd->iface->current_mode;
    133 	if (mode->mode == HOSTAPD_MODE_IEEE80211A)
    134 		chan_spacing = 4;
    135 
    136 	start = prev = NULL;
    137 	for (i = 0; i < mode->num_channels; i++) {
    138 		struct hostapd_channel_data *chan = &mode->channels[i];
    139 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
    140 			continue;
    141 		if (start && prev &&
    142 		    prev->chan + chan_spacing == chan->chan &&
    143 		    start->max_tx_power == chan->max_tx_power) {
    144 			prev = chan;
    145 			continue; /* can use same entry */
    146 		}
    147 
    148 		if (start) {
    149 			pos = hostapd_eid_country_add(pos, end, chan_spacing,
    150 						      start, prev);
    151 			start = NULL;
    152 		}
    153 
    154 		/* Start new group */
    155 		start = prev = chan;
    156 	}
    157 
    158 	if (start) {
    159 		pos = hostapd_eid_country_add(pos, end, chan_spacing,
    160 					      start, prev);
    161 	}
    162 
    163 	if ((pos - eid) & 1) {
    164 		if (end - pos < 1)
    165 			return eid;
    166 		*pos++ = 0; /* pad for 16-bit alignment */
    167 	}
    168 
    169 	eid[1] = (pos - eid) - 2;
    170 
    171 	return pos;
    172 }
    173 
    174 
    175 static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
    176 {
    177 	const u8 *ie;
    178 	size_t ielen;
    179 
    180 	ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
    181 	if (ie == NULL || ielen > len)
    182 		return eid;
    183 
    184 	os_memcpy(eid, ie, ielen);
    185 	return eid + ielen;
    186 }
    187 
    188 
    189 static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
    190 				   struct sta_info *sta,
    191 				   const struct ieee80211_mgmt *req,
    192 				   int is_p2p, size_t *resp_len)
    193 {
    194 	struct ieee80211_mgmt *resp;
    195 	u8 *pos, *epos;
    196 	size_t buflen;
    197 
    198 #define MAX_PROBERESP_LEN 768
    199 	buflen = MAX_PROBERESP_LEN;
    200 #ifdef CONFIG_WPS
    201 	if (hapd->wps_probe_resp_ie)
    202 		buflen += wpabuf_len(hapd->wps_probe_resp_ie);
    203 #endif /* CONFIG_WPS */
    204 #ifdef CONFIG_P2P
    205 	if (hapd->p2p_probe_resp_ie)
    206 		buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
    207 #endif /* CONFIG_P2P */
    208 	resp = os_zalloc(buflen);
    209 	if (resp == NULL)
    210 		return NULL;
    211 
    212 	epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
    213 
    214 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    215 					   WLAN_FC_STYPE_PROBE_RESP);
    216 	if (req)
    217 		os_memcpy(resp->da, req->sa, ETH_ALEN);
    218 	os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
    219 
    220 	os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
    221 	resp->u.probe_resp.beacon_int =
    222 		host_to_le16(hapd->iconf->beacon_int);
    223 
    224 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
    225 	resp->u.probe_resp.capab_info =
    226 		host_to_le16(hostapd_own_capab_info(hapd, sta, 1));
    227 
    228 	pos = resp->u.probe_resp.variable;
    229 	*pos++ = WLAN_EID_SSID;
    230 	*pos++ = hapd->conf->ssid.ssid_len;
    231 	os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
    232 	pos += hapd->conf->ssid.ssid_len;
    233 
    234 	/* Supported rates */
    235 	pos = hostapd_eid_supp_rates(hapd, pos);
    236 
    237 	/* DS Params */
    238 	pos = hostapd_eid_ds_params(hapd, pos);
    239 
    240 	pos = hostapd_eid_country(hapd, pos, epos - pos);
    241 
    242 	/* ERP Information element */
    243 	pos = hostapd_eid_erp_info(hapd, pos);
    244 
    245 	/* Extended supported rates */
    246 	pos = hostapd_eid_ext_supp_rates(hapd, pos);
    247 
    248 	/* RSN, MDIE, WPA */
    249 	pos = hostapd_eid_wpa(hapd, pos, epos - pos);
    250 
    251 #ifdef CONFIG_IEEE80211N
    252 	pos = hostapd_eid_ht_capabilities(hapd, pos);
    253 	pos = hostapd_eid_ht_operation(hapd, pos);
    254 #endif /* CONFIG_IEEE80211N */
    255 
    256 	pos = hostapd_eid_ext_capab(hapd, pos);
    257 
    258 	pos = hostapd_eid_time_adv(hapd, pos);
    259 	pos = hostapd_eid_time_zone(hapd, pos);
    260 
    261 	pos = hostapd_eid_interworking(hapd, pos);
    262 	pos = hostapd_eid_adv_proto(hapd, pos);
    263 	pos = hostapd_eid_roaming_consortium(hapd, pos);
    264 
    265 	/* Wi-Fi Alliance WMM */
    266 	pos = hostapd_eid_wmm(hapd, pos);
    267 
    268 #ifdef CONFIG_WPS
    269 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
    270 		os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
    271 			  wpabuf_len(hapd->wps_probe_resp_ie));
    272 		pos += wpabuf_len(hapd->wps_probe_resp_ie);
    273 	}
    274 #endif /* CONFIG_WPS */
    275 
    276 #ifdef CONFIG_P2P
    277 	if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p &&
    278 	    hapd->p2p_probe_resp_ie) {
    279 		os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
    280 			  wpabuf_len(hapd->p2p_probe_resp_ie));
    281 		pos += wpabuf_len(hapd->p2p_probe_resp_ie);
    282 	}
    283 #endif /* CONFIG_P2P */
    284 #ifdef CONFIG_P2P_MANAGER
    285 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
    286 	    P2P_MANAGE)
    287 		pos = hostapd_eid_p2p_manage(hapd, pos);
    288 #endif /* CONFIG_P2P_MANAGER */
    289 
    290 	*resp_len = pos - (u8 *) resp;
    291 	return (u8 *) resp;
    292 }
    293 
    294 
    295 void handle_probe_req(struct hostapd_data *hapd,
    296 		      const struct ieee80211_mgmt *mgmt, size_t len)
    297 {
    298 	u8 *resp;
    299 	struct ieee802_11_elems elems;
    300 	const u8 *ie;
    301 	size_t ie_len;
    302 	struct sta_info *sta = NULL;
    303 	size_t i, resp_len;
    304 	int noack;
    305 
    306 	ie = mgmt->u.probe_req.variable;
    307 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
    308 		return;
    309 	ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
    310 
    311 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
    312 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
    313 					    mgmt->sa, mgmt->da, mgmt->bssid,
    314 					    ie, ie_len) > 0)
    315 			return;
    316 
    317 	if (!hapd->iconf->send_probe_response)
    318 		return;
    319 
    320 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
    321 		wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
    322 			   MAC2STR(mgmt->sa));
    323 		return;
    324 	}
    325 
    326 	if ((!elems.ssid || !elems.supp_rates)) {
    327 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
    328 			   "without SSID or supported rates element",
    329 			   MAC2STR(mgmt->sa));
    330 		return;
    331 	}
    332 
    333 #ifdef CONFIG_P2P
    334 	if (hapd->p2p && elems.wps_ie) {
    335 		struct wpabuf *wps;
    336 		wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
    337 		if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
    338 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
    339 				   "due to mismatch with Requested Device "
    340 				   "Type");
    341 			wpabuf_free(wps);
    342 			return;
    343 		}
    344 		wpabuf_free(wps);
    345 	}
    346 
    347 	if (hapd->p2p && elems.p2p) {
    348 		struct wpabuf *p2p;
    349 		p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
    350 		if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
    351 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
    352 				   "due to mismatch with Device ID");
    353 			wpabuf_free(p2p);
    354 			return;
    355 		}
    356 		wpabuf_free(p2p);
    357 	}
    358 #endif /* CONFIG_P2P */
    359 
    360 	if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0) {
    361 		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
    362 			   "broadcast SSID ignored", MAC2STR(mgmt->sa));
    363 		return;
    364 	}
    365 
    366 	sta = ap_get_sta(hapd, mgmt->sa);
    367 
    368 #ifdef CONFIG_P2P
    369 	if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
    370 	    elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
    371 	    os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
    372 		      P2P_WILDCARD_SSID_LEN) == 0) {
    373 		/* Process P2P Wildcard SSID like Wildcard SSID */
    374 		elems.ssid_len = 0;
    375 	}
    376 #endif /* CONFIG_P2P */
    377 
    378 	if (elems.ssid_len == 0 ||
    379 	    (elems.ssid_len == hapd->conf->ssid.ssid_len &&
    380 	     os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
    381 	     0)) {
    382 		if (sta)
    383 			sta->ssid_probe = &hapd->conf->ssid;
    384 	} else {
    385 		if (!(mgmt->da[0] & 0x01)) {
    386 			char ssid_txt[33];
    387 			ieee802_11_print_ssid(ssid_txt, elems.ssid,
    388 					      elems.ssid_len);
    389 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
    390 				   " for foreign SSID '%s' (DA " MACSTR ")",
    391 				   MAC2STR(mgmt->sa), ssid_txt,
    392 				   MAC2STR(mgmt->da));
    393 		}
    394 		return;
    395 	}
    396 
    397 #ifdef CONFIG_INTERWORKING
    398 	if (elems.interworking && elems.interworking_len >= 1) {
    399 		u8 ant = elems.interworking[0] & 0x0f;
    400 		if (ant != INTERWORKING_ANT_WILDCARD &&
    401 		    ant != hapd->conf->access_network_type) {
    402 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
    403 				   " for mismatching ANT %u ignored",
    404 				   MAC2STR(mgmt->sa), ant);
    405 			return;
    406 		}
    407 	}
    408 
    409 	if (elems.interworking &&
    410 	    (elems.interworking_len == 7 || elems.interworking_len == 9)) {
    411 		const u8 *hessid;
    412 		if (elems.interworking_len == 7)
    413 			hessid = elems.interworking + 1;
    414 		else
    415 			hessid = elems.interworking + 1 + 2;
    416 		if (!is_broadcast_ether_addr(hessid) &&
    417 		    os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
    418 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
    419 				   " for mismatching HESSID " MACSTR
    420 				   " ignored",
    421 				   MAC2STR(mgmt->sa), MAC2STR(hessid));
    422 			return;
    423 		}
    424 	}
    425 #endif /* CONFIG_INTERWORKING */
    426 
    427 	/* TODO: verify that supp_rates contains at least one matching rate
    428 	 * with AP configuration */
    429 
    430 	resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL,
    431 				      &resp_len);
    432 	if (resp == NULL)
    433 		return;
    434 
    435 	/*
    436 	 * If this is a broadcast probe request, apply no ack policy to avoid
    437 	 * excessive retries.
    438 	 */
    439 	noack = !!(elems.ssid_len == 0 && is_broadcast_ether_addr(mgmt->da));
    440 
    441 	if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0)
    442 		perror("handle_probe_req: send");
    443 
    444 	os_free(resp);
    445 
    446 	wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
    447 		   "SSID", MAC2STR(mgmt->sa),
    448 		   elems.ssid_len == 0 ? "broadcast" : "our");
    449 }
    450 
    451 
    452 static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
    453 					size_t *resp_len)
    454 {
    455 	/* check probe response offloading caps and print warnings */
    456 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD))
    457 		return NULL;
    458 
    459 #ifdef CONFIG_WPS
    460 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie &&
    461 	    (!(hapd->iface->probe_resp_offloads &
    462 	       (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS |
    463 		WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2))))
    464 		wpa_printf(MSG_WARNING, "Device is trying to offload WPS "
    465 			   "Probe Response while not supporting this");
    466 #endif /* CONFIG_WPS */
    467 
    468 #ifdef CONFIG_P2P
    469 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie &&
    470 	    !(hapd->iface->probe_resp_offloads &
    471 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P))
    472 		wpa_printf(MSG_WARNING, "Device is trying to offload P2P "
    473 			   "Probe Response while not supporting this");
    474 #endif  /* CONFIG_P2P */
    475 
    476 	if (hapd->conf->interworking &&
    477 	    !(hapd->iface->probe_resp_offloads &
    478 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING))
    479 		wpa_printf(MSG_WARNING, "Device is trying to offload "
    480 			   "Interworking Probe Response while not supporting "
    481 			   "this");
    482 
    483 	/* Generate a Probe Response template for the non-P2P case */
    484 	return hostapd_gen_probe_resp(hapd, NULL, NULL, 0, resp_len);
    485 }
    486 
    487 #endif /* NEED_AP_MLME */
    488 
    489 
    490 void ieee802_11_set_beacon(struct hostapd_data *hapd)
    491 {
    492 	struct ieee80211_mgmt *head = NULL;
    493 	u8 *tail = NULL;
    494 	size_t head_len = 0, tail_len = 0;
    495 	u8 *resp = NULL;
    496 	size_t resp_len = 0;
    497 	struct wpa_driver_ap_params params;
    498 	struct wpabuf *beacon, *proberesp, *assocresp;
    499 #ifdef NEED_AP_MLME
    500 	u16 capab_info;
    501 	u8 *pos, *tailpos;
    502 #endif /* NEED_AP_MLME */
    503 
    504 	hapd->beacon_set_done = 1;
    505 
    506 #ifdef NEED_AP_MLME
    507 
    508 #define BEACON_HEAD_BUF_SIZE 256
    509 #define BEACON_TAIL_BUF_SIZE 512
    510 	head = os_zalloc(BEACON_HEAD_BUF_SIZE);
    511 	tail_len = BEACON_TAIL_BUF_SIZE;
    512 #ifdef CONFIG_WPS
    513 	if (hapd->conf->wps_state && hapd->wps_beacon_ie)
    514 		tail_len += wpabuf_len(hapd->wps_beacon_ie);
    515 #endif /* CONFIG_WPS */
    516 #ifdef CONFIG_P2P
    517 	if (hapd->p2p_beacon_ie)
    518 		tail_len += wpabuf_len(hapd->p2p_beacon_ie);
    519 #endif /* CONFIG_P2P */
    520 	tailpos = tail = os_malloc(tail_len);
    521 	if (head == NULL || tail == NULL) {
    522 		wpa_printf(MSG_ERROR, "Failed to set beacon data");
    523 		os_free(head);
    524 		os_free(tail);
    525 		return;
    526 	}
    527 
    528 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    529 					   WLAN_FC_STYPE_BEACON);
    530 	head->duration = host_to_le16(0);
    531 	os_memset(head->da, 0xff, ETH_ALEN);
    532 
    533 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
    534 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
    535 	head->u.beacon.beacon_int =
    536 		host_to_le16(hapd->iconf->beacon_int);
    537 
    538 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
    539 	capab_info = hostapd_own_capab_info(hapd, NULL, 0);
    540 	head->u.beacon.capab_info = host_to_le16(capab_info);
    541 	pos = &head->u.beacon.variable[0];
    542 
    543 	/* SSID */
    544 	*pos++ = WLAN_EID_SSID;
    545 	if (hapd->conf->ignore_broadcast_ssid == 2) {
    546 		/* clear the data, but keep the correct length of the SSID */
    547 		*pos++ = hapd->conf->ssid.ssid_len;
    548 		os_memset(pos, 0, hapd->conf->ssid.ssid_len);
    549 		pos += hapd->conf->ssid.ssid_len;
    550 	} else if (hapd->conf->ignore_broadcast_ssid) {
    551 		*pos++ = 0; /* empty SSID */
    552 	} else {
    553 		*pos++ = hapd->conf->ssid.ssid_len;
    554 		os_memcpy(pos, hapd->conf->ssid.ssid,
    555 			  hapd->conf->ssid.ssid_len);
    556 		pos += hapd->conf->ssid.ssid_len;
    557 	}
    558 
    559 	/* Supported rates */
    560 	pos = hostapd_eid_supp_rates(hapd, pos);
    561 
    562 	/* DS Params */
    563 	pos = hostapd_eid_ds_params(hapd, pos);
    564 
    565 	head_len = pos - (u8 *) head;
    566 
    567 	tailpos = hostapd_eid_country(hapd, tailpos,
    568 				      tail + BEACON_TAIL_BUF_SIZE - tailpos);
    569 
    570 	/* ERP Information element */
    571 	tailpos = hostapd_eid_erp_info(hapd, tailpos);
    572 
    573 	/* Extended supported rates */
    574 	tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
    575 
    576 	/* RSN, MDIE, WPA */
    577 	tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
    578 				  tailpos);
    579 
    580 #ifdef CONFIG_IEEE80211N
    581 	tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
    582 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
    583 #endif /* CONFIG_IEEE80211N */
    584 
    585 	tailpos = hostapd_eid_ext_capab(hapd, tailpos);
    586 
    587 	/*
    588 	 * TODO: Time Advertisement element should only be included in some
    589 	 * DTIM Beacon frames.
    590 	 */
    591 	tailpos = hostapd_eid_time_adv(hapd, tailpos);
    592 
    593 	tailpos = hostapd_eid_interworking(hapd, tailpos);
    594 	tailpos = hostapd_eid_adv_proto(hapd, tailpos);
    595 	tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
    596 
    597 	/* Wi-Fi Alliance WMM */
    598 	tailpos = hostapd_eid_wmm(hapd, tailpos);
    599 
    600 #ifdef CONFIG_WPS
    601 	if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
    602 		os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
    603 			  wpabuf_len(hapd->wps_beacon_ie));
    604 		tailpos += wpabuf_len(hapd->wps_beacon_ie);
    605 	}
    606 #endif /* CONFIG_WPS */
    607 
    608 #ifdef CONFIG_P2P
    609 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
    610 		os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
    611 			  wpabuf_len(hapd->p2p_beacon_ie));
    612 		tailpos += wpabuf_len(hapd->p2p_beacon_ie);
    613 	}
    614 #endif /* CONFIG_P2P */
    615 #ifdef CONFIG_P2P_MANAGER
    616 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
    617 	    P2P_MANAGE)
    618 		tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
    619 #endif /* CONFIG_P2P_MANAGER */
    620 
    621 	tail_len = tailpos > tail ? tailpos - tail : 0;
    622 
    623 	resp = hostapd_probe_resp_offloads(hapd, &resp_len);
    624 #endif /* NEED_AP_MLME */
    625 
    626 	os_memset(&params, 0, sizeof(params));
    627 	params.head = (u8 *) head;
    628 	params.head_len = head_len;
    629 	params.tail = tail;
    630 	params.tail_len = tail_len;
    631 	params.proberesp = resp;
    632 	params.proberesp_len = resp_len;
    633 	params.dtim_period = hapd->conf->dtim_period;
    634 	params.beacon_int = hapd->iconf->beacon_int;
    635 	params.basic_rates = hapd->iconf->basic_rates;
    636 	params.ssid = (u8 *) hapd->conf->ssid.ssid;
    637 	params.ssid_len = hapd->conf->ssid.ssid_len;
    638 	params.pairwise_ciphers = hapd->conf->rsn_pairwise ?
    639 		hapd->conf->rsn_pairwise : hapd->conf->wpa_pairwise;
    640 	params.group_cipher = hapd->conf->wpa_group;
    641 	params.key_mgmt_suites = hapd->conf->wpa_key_mgmt;
    642 	params.auth_algs = hapd->conf->auth_algs;
    643 	params.wpa_version = hapd->conf->wpa;
    644 	params.privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
    645 		(hapd->conf->ieee802_1x &&
    646 		 (hapd->conf->default_wep_key_len ||
    647 		  hapd->conf->individual_wep_key_len));
    648 	switch (hapd->conf->ignore_broadcast_ssid) {
    649 	case 0:
    650 		params.hide_ssid = NO_SSID_HIDING;
    651 		break;
    652 	case 1:
    653 		params.hide_ssid = HIDDEN_SSID_ZERO_LEN;
    654 		break;
    655 	case 2:
    656 		params.hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
    657 		break;
    658 	}
    659 	hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp);
    660 	params.beacon_ies = beacon;
    661 	params.proberesp_ies = proberesp;
    662 	params.assocresp_ies = assocresp;
    663 	params.isolate = hapd->conf->isolate;
    664 #ifdef NEED_AP_MLME
    665 	params.cts_protect = !!(ieee802_11_erp_info(hapd) &
    666 				ERP_INFO_USE_PROTECTION);
    667 	params.preamble = hapd->iface->num_sta_no_short_preamble == 0 &&
    668 		hapd->iconf->preamble == SHORT_PREAMBLE;
    669 	if (hapd->iface->current_mode &&
    670 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    671 		params.short_slot_time =
    672 			hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1;
    673 	else
    674 		params.short_slot_time = -1;
    675 	if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
    676 		params.ht_opmode = -1;
    677 	else
    678 		params.ht_opmode = hapd->iface->ht_op_mode;
    679 #endif /* NEED_AP_MLME */
    680 	params.interworking = hapd->conf->interworking;
    681 	if (hapd->conf->interworking &&
    682 	    !is_zero_ether_addr(hapd->conf->hessid))
    683 		params.hessid = hapd->conf->hessid;
    684 	params.access_network_type = hapd->conf->access_network_type;
    685 	if (hostapd_drv_set_ap(hapd, &params))
    686 		wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
    687 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
    688 
    689 	os_free(tail);
    690 	os_free(head);
    691 	os_free(resp);
    692 }
    693 
    694 
    695 void ieee802_11_set_beacons(struct hostapd_iface *iface)
    696 {
    697 	size_t i;
    698 	for (i = 0; i < iface->num_bss; i++)
    699 		ieee802_11_set_beacon(iface->bss[i]);
    700 }
    701 
    702 #endif /* CONFIG_NATIVE_WINDOWS */
    703