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