13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright (c) 2002-2004, Instant802 Networks, Inc. 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright (c) 2005-2006, Devicescape Software, Inc. 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi> 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This software may be distributed under the terms of the BSD license. 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See README for more details. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "utils/includes.h" 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef CONFIG_NATIVE_WINDOWS 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "utils/common.h" 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "common/ieee802_11_defs.h" 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "common/ieee802_11_common.h" 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "wps/wps_defs.h" 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "p2p/p2p.h" 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "hostapd.h" 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "ieee802_11.h" 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "wpa_auth.h" 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "wmm.h" 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "ap_config.h" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sta_info.h" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "p2p_hostapd.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "ap_drv_ops.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "beacon.h" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "hs20.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "dfs.h" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef NEED_AP_MLME 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len) 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_TESTING_OPTIONS 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->bss_load_test_set) { 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (2 + 5 > len) 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = WLAN_EID_BSS_LOAD; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = 5; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(eid, hapd->conf->bss_load_test, 5); 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry eid += 5; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_TESTING_OPTIONS */ 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 ieee802_11_erp_info(struct hostapd_data *hapd) 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 erp = 0; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->current_mode == NULL || 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->olbc) 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry erp |= ERP_INFO_USE_PROTECTION; 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->num_sta_non_erp > 0) { 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry erp |= ERP_INFO_NON_ERP_PRESENT | 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ERP_INFO_USE_PROTECTION; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->num_sta_no_short_preamble > 0 || 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iconf->preamble == LONG_PREAMBLE) 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry erp |= ERP_INFO_BARKER_PREAMBLE_MODE; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return erp; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid) 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = WLAN_EID_DS_PARAMS; 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = 1; 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = hapd->iconf->channel; 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid) 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->current_mode == NULL || 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Set NonERP_present and use_protection bits if there 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * are any associated NonERP stations. */ 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* TODO: use_protection bit can be set to zero even if 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * there are NonERP stations present. This optimization 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * might be useful if NonERP stations are "quiet". 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See 802.11g/D6 E-1 for recommended practice. 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In addition, Non ERP present might be set, if AP detects Non ERP 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * operation on other APs. */ 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Add ERP Information element */ 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = WLAN_EID_ERP_INFO; 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = 1; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = ieee802_11_erp_info(hapd); 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *pos = eid; 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 local_pwr_constraint = 0; 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int dfs; 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->current_mode == NULL || 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A) 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Let host drivers add this IE if DFS support is offloaded */ 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * There is no DFS support and power constraint was not directly 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * requested by config option. 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->iconf->ieee80211h && 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iconf->local_pwr_constraint == -1) 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Check if DFS is required by regulatory. */ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dfs = hostapd_is_dfs_required(hapd->iface); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (dfs < 0) { 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d", 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dfs); 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dfs = 0; 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1) 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ieee80211h (DFS) is enabled so Power Constraint element shall 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * be added when running on DFS channel whenever local_pwr_constraint 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is configured or not. In order to meet regulations when TPC is not 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * implemented using a transmit power that is below the legal maximum 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * (including any mitigation factor) should help. In this case, 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * indicate 3 dB below maximum allowed transmit power. 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iconf->local_pwr_constraint == -1) 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry local_pwr_constraint = 3; 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A STA that is not an AP shall use a transmit power less than or 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * equal to the local maximum transmit power level for the channel. 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The local maximum transmit power can be calculated from the formula: 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * local max TX pwr = max TX pwr - local pwr constraint 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Where max TX pwr is maximum transmit power level specified for 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * channel in Country element and local pwr constraint is specified 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * for channel in this Power Constraint element. 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Element ID */ 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = WLAN_EID_PWR_CONSTRAINT; 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Length */ 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = 1; 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Local Power Constraint */ 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (local_pwr_constraint) 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = local_pwr_constraint; 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = hapd->iconf->local_pwr_constraint; 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing, 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_channel_data *start, 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_channel_data *prev) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (end - pos < 3) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* first channel number */ 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = start->chan; 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* number of channels */ 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = (prev->chan - start->chan) / chan_spacing + 1; 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* maximum transmit power level */ 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = start->max_tx_power; 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid, 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int max_len) 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *pos = eid; 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *end = eid + max_len; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int i; 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_hw_modes *mode; 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_channel_data *start, *prev; 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int chan_spacing = 1; 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->iconf->ieee80211d || max_len < 6 || 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->current_mode == NULL) 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = WLAN_EID_COUNTRY; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos++; /* length will be set later */ 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */ 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += 3; 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mode = hapd->iface->current_mode; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (mode->mode == HOSTAPD_MODE_IEEE80211A) 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry chan_spacing = 4; 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start = prev = NULL; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i = 0; i < mode->num_channels; i++) { 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_channel_data *chan = &mode->channels[i]; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (chan->flag & HOSTAPD_CHAN_DISABLED) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (start && prev && 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prev->chan + chan_spacing == chan->chan && 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start->max_tx_power == chan->max_tx_power) { 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry prev = chan; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; /* can use same entry */ 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (start && prev) { 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_country_add(pos, end, chan_spacing, 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start, prev); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start = NULL; 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Start new group */ 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start = prev = chan; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (start) { 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_country_add(pos, end, chan_spacing, 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry start, prev); 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((pos - eid) & 1) { 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (end - pos < 1) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = 0; /* pad for 16-bit alignment */ 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry eid[1] = (pos - eid) - 2; 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len) 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *ie; 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t ielen; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen); 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ie == NULL || ielen > len) 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(eid, ie, ielen); 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid + ielen; 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid) 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 chan; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->cs_freq_params.freq) 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ieee80211_freq_to_chan(hapd->cs_freq_params.freq, &chan) == 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry NUM_HOSTAPD_MODES) 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = WLAN_EID_CHANNEL_SWITCH; 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = 3; 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = hapd->cs_block_tx; 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = chan; 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = hapd->cs_count; 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid) 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 sec_ch; 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->cs_freq_params.sec_channel_offset) 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->cs_freq_params.sec_channel_offset == -1) 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW; 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (hapd->cs_freq_params.sec_channel_offset == 1) 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE; 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = 1; 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *eid++ = sec_ch; 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return eid; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_add_csa_elems(struct hostapd_data *hapd, u8 *pos, 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *start, unsigned int *csa_counter_off) 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *old_pos = pos; 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!csa_counter_off) 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *csa_counter_off = 0; 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_csa(hapd, pos); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pos != old_pos) { 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* save an offset to the counter - should be last byte */ 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *csa_counter_off = pos - start - 1; 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_secondary_channel(hapd, pos); 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos; 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct sta_info *sta, 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct ieee80211_mgmt *req, 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int is_p2p, size_t *resp_len) 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct ieee80211_mgmt *resp; 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *pos, *epos; 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t buflen; 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define MAX_PROBERESP_LEN 768 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buflen = MAX_PROBERESP_LEN; 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_WPS 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->wps_probe_resp_ie) 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buflen += wpabuf_len(hapd->wps_probe_resp_ie); 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_WPS */ 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->p2p_probe_resp_ie) 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buflen += wpabuf_len(hapd->p2p_probe_resp_ie); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->vendor_elements) 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buflen += wpabuf_len(hapd->conf->vendor_elements); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp = os_zalloc(buflen); 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resp == NULL) 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return NULL; 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry epos = ((u8 *) resp) + MAX_PROBERESP_LEN; 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WLAN_FC_STYPE_PROBE_RESP); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (req) 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(resp->da, req->sa, ETH_ALEN); 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp->u.probe_resp.beacon_int = 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry host_to_le16(hapd->iconf->beacon_int); 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* hardware or low-level driver will setup seq_ctrl and timestamp */ 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp->u.probe_resp.capab_info = 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = resp->u.probe_resp.variable; 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = WLAN_EID_SSID; 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = hapd->conf->ssid.ssid_len; 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += hapd->conf->ssid.ssid_len; 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Supported rates */ 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_supp_rates(hapd, pos); 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* DS Params */ 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ds_params(hapd, pos); 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_country(hapd, pos, epos - pos); 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Power Constraint element */ 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_pwr_constraint(hapd, pos); 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* ERP Information element */ 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_erp_info(hapd, pos); 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Extended supported rates */ 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ext_supp_rates(hapd, pos); 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* RSN, MDIE, WPA */ 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_wpa(hapd, pos, epos - pos); 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_bss_load(hapd, pos, epos - pos); 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_IEEE80211N 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ht_capabilities(hapd, pos); 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ht_operation(hapd, pos); 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_IEEE80211N */ 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ext_capab(hapd, pos); 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_time_adv(hapd, pos); 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_time_zone(hapd, pos); 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_interworking(hapd, pos); 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_adv_proto(hapd, pos); 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_roaming_consortium(hapd, pos); 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp, 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &hapd->cs_c_off_proberesp); 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_IEEE80211AC 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_vht_capabilities(hapd, pos); 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_vht_operation(hapd, pos); 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_IEEE80211AC */ 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Wi-Fi Alliance WMM */ 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_wmm(hapd, pos); 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_WPS 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->wps_probe_resp_ie)); 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += wpabuf_len(hapd->wps_probe_resp_ie); 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_WPS */ 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p && 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->p2p_probe_resp_ie) { 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->p2p_probe_resp_ie)); 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += wpabuf_len(hapd->p2p_probe_resp_ie); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P_MANAGER 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry P2P_MANAGE) 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_p2p_manage(hapd, pos); 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P_MANAGER */ 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_HS20 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_hs20_indication(hapd, pos); 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_osen(hapd, pos); 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_HS20 */ 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->vendor_elements) { 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements), 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->conf->vendor_elements)); 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += wpabuf_len(hapd->conf->vendor_elements); 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *resp_len = pos - (u8 *) resp; 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (u8 *) resp; 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ssid_match_result { 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry NO_SSID_MATCH, 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EXACT_SSID_MATCH, 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WILDCARD_SSID_MATCH 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic enum ssid_match_result ssid_match(struct hostapd_data *hapd, 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *ssid, size_t ssid_len, 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *ssid_list, 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t ssid_list_len) 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *pos, *end; 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int wildcard = 0; 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ssid_len == 0) 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wildcard = 1; 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ssid_len == hapd->conf->ssid.ssid_len && 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0) 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return EXACT_SSID_MATCH; 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ssid_list == NULL) 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH; 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = ssid_list; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry end = ssid_list + ssid_list_len; 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (pos + 1 <= end) { 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pos + 2 + pos[1] > end) 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pos[1] == 0) 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wildcard = 1; 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pos[1] == hapd->conf->ssid.ssid_len && 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0) 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return EXACT_SSID_MATCH; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += 2 + pos[1]; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH; 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid handle_probe_req(struct hostapd_data *hapd, 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct ieee80211_mgmt *mgmt, size_t len, 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int ssi_signal) 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *resp; 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct ieee802_11_elems elems; 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *ie; 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t ie_len; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct sta_info *sta = NULL; 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t i, resp_len; 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int noack; 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum ssid_match_result res; 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ie = mgmt->u.probe_req.variable; 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx, 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mgmt->sa, mgmt->da, mgmt->bssid, 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ie, ie_len, ssi_signal) > 0) 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->iconf->send_probe_response) 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) { 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR, 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa)); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((!elems.ssid || !elems.supp_rates)) { 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request " 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "without SSID or supported rates element", 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa)); 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->p2p && elems.wps_ie) { 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct wpabuf *wps; 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA); 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) { 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request " 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "due to mismatch with Requested Device " 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Type"); 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_free(wps); 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_free(wps); 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->p2p && elems.p2p) { 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct wpabuf *p2p; 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE); 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) { 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request " 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "due to mismatch with Device ID"); 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_free(p2p); 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_free(p2p); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 && 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_list_len == 0) { 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for " 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "broadcast SSID ignored", MAC2STR(mgmt->sa)); 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sta = ap_get_sta(hapd, mgmt->sa); 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & P2P_GROUP_OWNER) && 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_len == P2P_WILDCARD_SSID_LEN && 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcmp(elems.ssid, P2P_WILDCARD_SSID, 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry P2P_WILDCARD_SSID_LEN) == 0) { 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Process P2P Wildcard SSID like Wildcard SSID */ 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_len = 0; 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry res = ssid_match(hapd, elems.ssid, elems.ssid_len, 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_list, elems.ssid_list_len); 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (res != NO_SSID_MATCH) { 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (sta) 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sta->ssid_probe = &hapd->conf->ssid; 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } else { 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!(mgmt->da[0] & 0x01)) { 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for foreign SSID '%s' (DA " MACSTR ")%s", 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa), 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_ssid_txt(elems.ssid, elems.ssid_len), 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->da), 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_list ? " (SSID list)" : ""); 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_INTERWORKING 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->interworking && 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.interworking && elems.interworking_len >= 1) { 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 ant = elems.interworking[0] & 0x0f; 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ant != INTERWORKING_ANT_WILDCARD && 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ant != hapd->conf->access_network_type) { 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for mismatching ANT %u ignored", 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa), ant); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->interworking && elems.interworking && 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (elems.interworking_len == 7 || elems.interworking_len == 9)) { 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const u8 *hessid; 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (elems.interworking_len == 7) 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hessid = elems.interworking + 1; 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hessid = elems.interworking + 1 + 2; 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!is_broadcast_ether_addr(hessid) && 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) { 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for mismatching HESSID " MACSTR 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ignored", 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa), MAC2STR(hessid)); 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_INTERWORKING */ 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & P2P_GROUP_OWNER) && 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry supp_rates_11b_only(&elems)) { 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Indicates support for 11b rates only */ 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_EXCESSIVE, "P2P: Ignore Probe Request from " 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MACSTR " with only 802.11b rates", 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa)); 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* TODO: verify that supp_rates contains at least one matching rate 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * with AP configuration */ 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_TESTING_OPTIONS 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iconf->ignore_probe_probability > 0.0 && 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drand48() < hapd->iconf->ignore_probe_probability) { 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_INFO, 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "TESTING: ignoring probe request from " MACSTR, 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAC2STR(mgmt->sa)); 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_TESTING_OPTIONS */ 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL, 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &resp_len); 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resp == NULL) 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * If this is a broadcast probe request, apply no ack policy to avoid 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * excessive retries. 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry noack = !!(res == WILDCARD_SSID_MATCH && 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry is_broadcast_ether_addr(mgmt->da)); 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0) 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_INFO, "handle_probe_req: send failed"); 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(resp); 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s " 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "SSID", MAC2STR(mgmt->sa), 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry elems.ssid_len == 0 ? "broadcast" : "our"); 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd, 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t *resp_len) 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* check probe response offloading caps and print warnings */ 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD)) 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return NULL; 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_WPS 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->wps_state && hapd->wps_probe_resp_ie && 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (!(hapd->iface->probe_resp_offloads & 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS | 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2)))) 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_WARNING, "Device is trying to offload WPS " 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Probe Response while not supporting this"); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_WPS */ 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie && 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !(hapd->iface->probe_resp_offloads & 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P)) 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_WARNING, "Device is trying to offload P2P " 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Probe Response while not supporting this"); 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->interworking && 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !(hapd->iface->probe_resp_offloads & 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING)) 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_WARNING, "Device is trying to offload " 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Interworking Probe Response while not supporting " 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "this"); 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Generate a Probe Response template for the non-P2P case */ 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return hostapd_gen_probe_resp(hapd, NULL, NULL, 0, resp_len); 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* NEED_AP_MLME */ 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ieee802_11_build_ap_params(struct hostapd_data *hapd, 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct wpa_driver_ap_params *params) 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct ieee80211_mgmt *head = NULL; 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *tail = NULL; 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t head_len = 0, tail_len = 0; 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *resp = NULL; 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t resp_len = 0; 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef NEED_AP_MLME 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u16 capab_info; 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry u8 *pos, *tailpos; 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define BEACON_HEAD_BUF_SIZE 256 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define BEACON_TAIL_BUF_SIZE 512 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head = os_zalloc(BEACON_HEAD_BUF_SIZE); 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail_len = BEACON_TAIL_BUF_SIZE; 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_WPS 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->wps_state && hapd->wps_beacon_ie) 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail_len += wpabuf_len(hapd->wps_beacon_ie); 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_WPS */ 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->p2p_beacon_ie) 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail_len += wpabuf_len(hapd->p2p_beacon_ie); 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->vendor_elements) 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail_len += wpabuf_len(hapd->conf->vendor_elements); 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = tail = os_malloc(tail_len); 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (head == NULL || tail == NULL) { 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_ERROR, "Failed to set beacon data"); 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(head); 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(tail); 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WLAN_FC_STYPE_BEACON); 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head->duration = host_to_le16(0); 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memset(head->da, 0xff, ETH_ALEN); 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(head->sa, hapd->own_addr, ETH_ALEN); 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN); 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head->u.beacon.beacon_int = 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry host_to_le16(hapd->iconf->beacon_int); 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* hardware or low-level driver will setup seq_ctrl and timestamp */ 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry capab_info = hostapd_own_capab_info(hapd, NULL, 0); 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head->u.beacon.capab_info = host_to_le16(capab_info); 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = &head->u.beacon.variable[0]; 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* SSID */ 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = WLAN_EID_SSID; 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->ignore_broadcast_ssid == 2) { 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* clear the data, but keep the correct length of the SSID */ 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = hapd->conf->ssid.ssid_len; 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memset(pos, 0, hapd->conf->ssid.ssid_len); 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += hapd->conf->ssid.ssid_len; 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } else if (hapd->conf->ignore_broadcast_ssid) { 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = 0; /* empty SSID */ 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } else { 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *pos++ = hapd->conf->ssid.ssid_len; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(pos, hapd->conf->ssid.ssid, 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->conf->ssid.ssid_len); 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos += hapd->conf->ssid.ssid_len; 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Supported rates */ 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_supp_rates(hapd, pos); 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* DS Params */ 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pos = hostapd_eid_ds_params(hapd, pos); 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry head_len = pos - (u8 *) head; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_country(hapd, tailpos, 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail + BEACON_TAIL_BUF_SIZE - tailpos); 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Power Constraint element */ 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_pwr_constraint(hapd, tailpos); 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* ERP Information element */ 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_erp_info(hapd, tailpos); 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Extended supported rates */ 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos); 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* RSN, MDIE, WPA */ 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos); 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_bss_load(hapd, tailpos, 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail + BEACON_TAIL_BUF_SIZE - tailpos); 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_IEEE80211N 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_ht_operation(hapd, tailpos); 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_IEEE80211N */ 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_ext_capab(hapd, tailpos); 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * TODO: Time Advertisement element should only be included in some 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * DTIM Beacon frames. 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_time_adv(hapd, tailpos); 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_interworking(hapd, tailpos); 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_adv_proto(hapd, tailpos); 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_roaming_consortium(hapd, tailpos); 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_add_csa_elems(hapd, tailpos, tail, 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &hapd->cs_c_off_beacon); 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_IEEE80211AC 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_vht_capabilities(hapd, tailpos); 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_vht_operation(hapd, tailpos); 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_IEEE80211AC */ 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Wi-Fi Alliance WMM */ 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_wmm(hapd, tailpos); 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_WPS 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->wps_state && hapd->wps_beacon_ie) { 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie), 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->wps_beacon_ie)); 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos += wpabuf_len(hapd->wps_beacon_ie); 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_WPS */ 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) { 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie), 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->p2p_beacon_ie)); 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos += wpabuf_len(hapd->p2p_beacon_ie); 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P */ 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_P2P_MANAGER 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry P2P_MANAGE) 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_p2p_manage(hapd, tailpos); 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_P2P_MANAGER */ 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_HS20 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_hs20_indication(hapd, tailpos); 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos = hostapd_eid_osen(hapd, tailpos); 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_HS20 */ 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->vendor_elements) { 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements), 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpabuf_len(hapd->conf->vendor_elements)); 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tailpos += wpabuf_len(hapd->conf->vendor_elements); 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tail_len = tailpos > tail ? tailpos - tail : 0; 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resp = hostapd_probe_resp_offloads(hapd, &resp_len); 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* NEED_AP_MLME */ 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_memset(params, 0, sizeof(*params)); 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->head = (u8 *) head; 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->head_len = head_len; 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->tail = tail; 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->tail_len = tail_len; 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->proberesp = resp; 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->proberesp_len = resp_len; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->dtim_period = hapd->conf->dtim_period; 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->beacon_int = hapd->iconf->beacon_int; 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->basic_rates = hapd->iface->basic_rates; 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->ssid = hapd->conf->ssid.ssid; 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->ssid_len = hapd->conf->ssid.ssid_len; 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->pairwise_ciphers = hapd->conf->wpa_pairwise | 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->conf->rsn_pairwise; 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->group_cipher = hapd->conf->wpa_group; 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->key_mgmt_suites = hapd->conf->wpa_key_mgmt; 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->auth_algs = hapd->conf->auth_algs; 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->wpa_version = hapd->conf->wpa; 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa || 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (hapd->conf->ieee802_1x && 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (hapd->conf->default_wep_key_len || 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->conf->individual_wep_key_len)); 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (hapd->conf->ignore_broadcast_ssid) { 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 0: 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->hide_ssid = NO_SSID_HIDING; 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 1: 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->hide_ssid = HIDDEN_SSID_ZERO_LEN; 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case 2: 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS; 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->isolate = hapd->conf->isolate; 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef NEED_AP_MLME 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->cts_protect = !!(ieee802_11_erp_info(hapd) & 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ERP_INFO_USE_PROTECTION); 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->preamble = hapd->iface->num_sta_no_short_preamble == 0 && 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iconf->preamble == SHORT_PREAMBLE; 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->iface->current_mode && 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->short_slot_time = 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1; 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->short_slot_time = -1; 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n) 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->ht_opmode = -1; 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->ht_opmode = hapd->iface->ht_op_mode; 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* NEED_AP_MLME */ 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->interworking = hapd->conf->interworking; 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->interworking && 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !is_zero_ether_addr(hapd->conf->hessid)) 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->hessid = hapd->conf->hessid; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->access_network_type = hapd->conf->access_network_type; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->ap_max_inactivity = hapd->conf->ap_max_inactivity; 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifdef CONFIG_HS20 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->disable_dgaf = hapd->conf->disable_dgaf; 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->conf->osen) { 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->privacy = 1; 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->osen = 1; 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_HS20 */ 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ieee802_11_free_ap_params(struct wpa_driver_ap_params *params) 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(params->tail); 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->tail = NULL; 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(params->head); 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->head = NULL; 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry os_free(params->proberesp); 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params->proberesp = NULL; 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ieee802_11_set_beacon(struct hostapd_data *hapd) 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct wpa_driver_ap_params params; 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_freq_params freq; 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_iface *iface = hapd->iface; 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct hostapd_config *iconf = iface->conf; 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct wpabuf *beacon, *proberesp, *assocresp; 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int res, ret = -1; 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hapd->csa_in_progress) { 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period"); 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hapd->beacon_set_done = 1; 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ieee802_11_build_ap_params(hapd, ¶ms) < 0) 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) < 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0) 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry goto fail; 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params.beacon_ies = beacon; 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params.proberesp_ies = proberesp; 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params.assocresp_ies = assocresp; 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iface->current_mode && 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq, 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->channel, iconf->ieee80211n, 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->ieee80211ac, 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->secondary_channel, 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->vht_oper_chwidth, 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->vht_oper_centr_freq_seg0_idx, 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iconf->vht_oper_centr_freq_seg1_idx, 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iface->current_mode->vht_capab) == 0) 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry params.freq = &freq; 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry res = hostapd_drv_set_ap(hapd, ¶ms); 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp); 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (res) 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry wpa_printf(MSG_ERROR, "Failed to set beacon parameters"); 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = 0; 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfail: 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ieee802_11_free_ap_params(¶ms); 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ieee802_11_set_beacons(struct hostapd_iface *iface) 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t i; 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int ret = 0; 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i = 0; i < iface->num_bss; i++) { 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iface->bss[i]->started && 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ieee802_11_set_beacon(iface->bss[i]) < 0) 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = -1; 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* only update beacons if started */ 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint ieee802_11_update_beacons(struct hostapd_iface *iface) 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size_t i; 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int ret = 0; 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i = 0; i < iface->num_bss; i++) { 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (iface->bss[i]->beacon_set_done && iface->bss[i]->started && 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ieee802_11_set_beacon(iface->bss[i]) < 0) 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ret = -1; 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ret; 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif /* CONFIG_NATIVE_WINDOWS */ 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry