18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2004, Instant802 Networks, Inc. 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2005-2006, Devicescape Software, Inc. 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2008-2009, Jouni Malinen <j@w1.fi> 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_defs.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wmm.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 ieee802_11_erp_info(struct hostapd_data *hapd) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 erp = 0; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode == NULL || 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hapd->iconf->cts_protection_type) { 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CTS_PROTECTION_FORCE_ENABLED: 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt erp |= ERP_INFO_NON_ERP_PRESENT | ERP_INFO_USE_PROTECTION; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CTS_PROTECTION_FORCE_DISABLED: 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt erp = 0; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CTS_PROTECTION_AUTOMATIC: 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->olbc) 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt erp |= ERP_INFO_USE_PROTECTION; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* continue */ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CTS_PROTECTION_AUTOMATIC_NO_OLBC: 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_non_erp > 0) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt erp |= ERP_INFO_NON_ERP_PRESENT | 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERP_INFO_USE_PROTECTION; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->num_sta_no_short_preamble > 0 || 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->preamble == LONG_PREAMBLE) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt erp |= ERP_INFO_BARKER_PREAMBLE_MODE; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return erp; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = WLAN_EID_DS_PARAMS; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = 1; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = hapd->iconf->channel; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iface->current_mode == NULL || 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set NonERP_present and use_protection bits if there 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * are any associated NonERP stations. */ 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: use_protection bit can be set to zero even if 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * there are NonERP stations present. This optimization 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * might be useful if NonERP stations are "quiet". 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See 802.11g/D6 E-1 for recommended practice. 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * In addition, Non ERP present might be set, if AP detects Non ERP 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * operation on other APs. */ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add ERP Information element */ 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = WLAN_EID_ERP_INFO; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = 1; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *eid++ = ieee802_11_erp_info(hapd); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing, 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_channel_data *start, 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_channel_data *prev) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 3) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* first channel number */ 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = start->chan; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* number of channels */ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = (prev->chan - start->chan) / chan_spacing + 1; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* maximum transmit power level */ 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = start->max_tx_power; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int max_len) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = eid; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *end = eid + max_len; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_hw_modes *mode; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_channel_data *start, *prev; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int chan_spacing = 1; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hapd->iconf->ieee80211d || max_len < 6 || 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->current_mode == NULL) 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_COUNTRY; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; /* length will be set later */ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = hapd->iface->current_mode; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mode->mode == HOSTAPD_MODE_IEEE80211A) 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt chan_spacing = 4; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = prev = NULL; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < mode->num_channels; i++) { 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_channel_data *chan = &mode->channels[i]; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (chan->flag & HOSTAPD_CHAN_DISABLED) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (start && prev && 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->chan + chan_spacing == chan->chan && 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start->max_tx_power == chan->max_tx_power) { 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = chan; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; /* can use same entry */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (start) { 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_country_add(pos, end, chan_spacing, 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start, prev); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = NULL; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start new group */ 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = prev = chan; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (start) { 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_country_add(pos, end, chan_spacing, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start, prev); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((pos - eid) & 1) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (end - pos < 1) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0; /* pad for 16-bit alignment */ 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eid[1] = (pos - eid) - 2; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ielen; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie == NULL || ielen > len) 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(eid, ie, ielen); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eid + ielen; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid handle_probe_req(struct hostapd_data *hapd, 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct ieee80211_mgmt *mgmt, size_t len) 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *resp; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ssid; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *epos; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ssid_len, ie_len; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct sta_info *sta = NULL; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = mgmt->u.probe_req.variable; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt#ifndef ANDROID_BRCM_P2P_PATCH 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mgmt->sa, ie, ie_len) > 0) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 223497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt#endif 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hapd->iconf->send_probe_response) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR, 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = NULL; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = 0; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((!elems.ssid || !elems.supp_rates)) { 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request " 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "without SSID or supported rates element", 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa)); 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->p2p && elems.wps_ie) { 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) { 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request " 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "due to mismatch with Requested Device " 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Type"); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for " 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "broadcast SSID ignored", MAC2STR(mgmt->sa)); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta = ap_get_sta(hapd, mgmt->sa); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & P2P_GROUP_OWNER) && 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ssid_len == P2P_WILDCARD_SSID_LEN && 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, P2P_WILDCARD_SSID, 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_WILDCARD_SSID_LEN) == 0) { 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Process P2P Wildcard SSID like Wildcard SSID */ 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ssid_len = 0; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid_len == 0 || 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (elems.ssid_len == hapd->conf->ssid.ssid_len && 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) == 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0)) { 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = hapd->conf->ssid.ssid; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = hapd->conf->ssid.ssid_len; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta) 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->ssid_probe = &hapd->conf->ssid; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ssid) { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(mgmt->da[0] & 0x01)) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ssid_txt[33]; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_print_ssid(ssid_txt, elems.ssid, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ssid_len); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for foreign SSID '%s' (DA " MACSTR ")", 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->sa), ssid_txt, 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mgmt->da)); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: verify that supp_rates contains at least one matching rate 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with AP configuration */ 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MAX_PROBERESP_LEN 768 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = MAX_PROBERESP_LEN; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->wps_probe_resp_ie) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen += wpabuf_len(hapd->wps_probe_resp_ie); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->p2p_probe_resp_ie) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen += wpabuf_len(hapd->p2p_probe_resp_ie); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = os_zalloc(buflen); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt epos = ((u8 *) resp) + MAX_PROBERESP_LEN; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_PROBE_RESP); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->da, mgmt->sa, ETH_ALEN); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.beacon_int = 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(hapd->iconf->beacon_int); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp->u.probe_resp.capab_info = 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = resp->u.probe_resp.variable; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SSID; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ssid_len; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, ssid, ssid_len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ssid_len; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supported rates */ 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_supp_rates(hapd, pos); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* DS Params */ 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ds_params(hapd, pos); 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_country(hapd, pos, epos - pos); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ERP Information element */ 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_erp_info(hapd, pos); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extended supported rates */ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ext_supp_rates(hapd, pos); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RSN, MDIE, WPA */ 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_wpa(hapd, pos, epos - pos, sta); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ht_capabilities(hapd, pos); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ht_operation(hapd, pos); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ext_capab(hapd, pos); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wi-Fi Alliance WMM */ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_wmm(hapd, pos); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(hapd->wps_probe_resp_ie)); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpabuf_len(hapd->wps_probe_resp_ie); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & P2P_ENABLED) && elems.p2p && 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie) { 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(hapd->p2p_probe_resp_ie)); 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += wpabuf_len(hapd->p2p_probe_resp_ie); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_MANAGE) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_p2p_manage(hapd, pos); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_send_mlme(hapd, resp, pos - (u8 *) resp) < 0) 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("handle_probe_req: send"); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(resp); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s " 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SSID", MAC2STR(mgmt->sa), 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.ssid_len == 0 ? "broadcast" : "our"); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_set_beacon(struct hostapd_data *hapd) 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee80211_mgmt *head; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos, *tail, *tailpos; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 capab_info; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t head_len, tail_len; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & (P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_ENABLED) 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto no_beacon; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define BEACON_HEAD_BUF_SIZE 256 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define BEACON_TAIL_BUF_SIZE 512 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head = os_zalloc(BEACON_HEAD_BUF_SIZE); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail_len = BEACON_TAIL_BUF_SIZE; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && hapd->wps_beacon_ie) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail_len += wpabuf_len(hapd->wps_beacon_ie); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->p2p_beacon_ie) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail_len += wpabuf_len(hapd->p2p_beacon_ie); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = tail = os_malloc(tail_len); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (head == NULL || tail == NULL) { 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set beacon data"); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(head); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tail); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_FC_STYPE_BEACON); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head->duration = host_to_le16(0); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(head->da, 0xff, ETH_ALEN); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(head->sa, hapd->own_addr, ETH_ALEN); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN); 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head->u.beacon.beacon_int = 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt host_to_le16(hapd->iconf->beacon_int); 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* hardware or low-level driver will setup seq_ctrl and timestamp */ 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt capab_info = hostapd_own_capab_info(hapd, NULL, 0); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head->u.beacon.capab_info = host_to_le16(capab_info); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = &head->u.beacon.variable[0]; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* SSID */ 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SSID; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ignore_broadcast_ssid == 2) { 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* clear the data, but keep the correct length of the SSID */ 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = hapd->conf->ssid.ssid_len; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0, hapd->conf->ssid.ssid_len); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += hapd->conf->ssid.ssid_len; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->conf->ignore_broadcast_ssid) { 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0; /* empty SSID */ 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = hapd->conf->ssid.ssid_len; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, hapd->conf->ssid.ssid, 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid_len); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += hapd->conf->ssid.ssid_len; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Supported rates */ 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_supp_rates(hapd, pos); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* DS Params */ 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = hostapd_eid_ds_params(hapd, pos); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt head_len = pos - (u8 *) head; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_country(hapd, tailpos, 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail + BEACON_TAIL_BUF_SIZE - tailpos); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ERP Information element */ 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_erp_info(hapd, tailpos); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Extended supported rates */ 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* RSN, MDIE, WPA */ 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos, NULL); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211N 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_ht_operation(hapd, tailpos); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_ext_capab(hapd, tailpos); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wi-Fi Alliance WMM */ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_wmm(hapd, tailpos); 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wps_state && hapd->wps_beacon_ie) { 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie), 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(hapd->wps_beacon_ie)); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos += wpabuf_len(hapd->wps_beacon_ie); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) { 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie), 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(hapd->p2p_beacon_ie)); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos += wpabuf_len(hapd->p2p_beacon_ie); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_MANAGE) 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tailpos = hostapd_eid_p2p_manage(hapd, tailpos); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail_len = tailpos > tail ? tailpos - tail : 0; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_beacon(hapd, (u8 *) head, head_len, 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tail, tail_len, hapd->conf->dtim_period, 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->beacon_int)) 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set beacon head/tail or DTIM " 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "period"); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(tail); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(head); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtno_beacon: 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_bss_params(hapd, !!(ieee802_11_erp_info(hapd) & 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ERP_INFO_USE_PROTECTION)); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ieee802_11_set_beacons(struct hostapd_iface *iface) 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacon(iface->bss[i]); 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 537