LCOV - code coverage report
Current view: top level - src/ap - beacon.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 502 559 89.8 %
Date: 2015-03-15 Functions: 21 21 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
       3             :  * Copyright (c) 2002-2004, Instant802 Networks, Inc.
       4             :  * Copyright (c) 2005-2006, Devicescape Software, Inc.
       5             :  * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
       6             :  *
       7             :  * This software may be distributed under the terms of the BSD license.
       8             :  * See README for more details.
       9             :  */
      10             : 
      11             : #include "utils/includes.h"
      12             : 
      13             : #ifndef CONFIG_NATIVE_WINDOWS
      14             : 
      15             : #include "utils/common.h"
      16             : #include "common/ieee802_11_defs.h"
      17             : #include "common/ieee802_11_common.h"
      18             : #include "common/hw_features_common.h"
      19             : #include "wps/wps_defs.h"
      20             : #include "p2p/p2p.h"
      21             : #include "hostapd.h"
      22             : #include "ieee802_11.h"
      23             : #include "wpa_auth.h"
      24             : #include "wmm.h"
      25             : #include "ap_config.h"
      26             : #include "sta_info.h"
      27             : #include "p2p_hostapd.h"
      28             : #include "ap_drv_ops.h"
      29             : #include "beacon.h"
      30             : #include "hs20.h"
      31             : #include "dfs.h"
      32             : 
      33             : 
      34             : #ifdef NEED_AP_MLME
      35             : 
      36        5314 : static u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
      37             :                                          size_t len)
      38             : {
      39        5314 :         if (!hapd->conf->radio_measurements || len < 2 + 4)
      40        5312 :                 return eid;
      41             : 
      42           2 :         *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
      43           2 :         *eid++ = 5;
      44           2 :         *eid++ = (hapd->conf->radio_measurements & BIT(0)) ?
      45             :                 WLAN_RRM_CAPS_NEIGHBOR_REPORT : 0x00;
      46           2 :         *eid++ = 0x00;
      47           2 :         *eid++ = 0x00;
      48           2 :         *eid++ = 0x00;
      49           2 :         *eid++ = 0x00;
      50           2 :         return eid;
      51             : }
      52             : 
      53             : 
      54        5314 : static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
      55             : {
      56        5314 :         if (len < 2 + 5)
      57           0 :                 return eid;
      58             : 
      59             : #ifdef CONFIG_TESTING_OPTIONS
      60        5314 :         if (hapd->conf->bss_load_test_set) {
      61          11 :                 *eid++ = WLAN_EID_BSS_LOAD;
      62          11 :                 *eid++ = 5;
      63          11 :                 os_memcpy(eid, hapd->conf->bss_load_test, 5);
      64          11 :                 eid += 5;
      65          11 :                 return eid;
      66             :         }
      67             : #endif /* CONFIG_TESTING_OPTIONS */
      68        5303 :         if (hapd->conf->bss_load_update_period) {
      69           7 :                 *eid++ = WLAN_EID_BSS_LOAD;
      70           7 :                 *eid++ = 5;
      71           7 :                 WPA_PUT_LE16(eid, hapd->num_sta);
      72           7 :                 eid += 2;
      73           7 :                 *eid++ = hapd->iface->channel_utilization;
      74           7 :                 WPA_PUT_LE16(eid, 0); /* no available admission capabity */
      75           7 :                 eid += 2;
      76             :         }
      77        5303 :         return eid;
      78             : }
      79             : 
      80             : 
      81        8059 : static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
      82             : {
      83        8059 :         u8 erp = 0;
      84             : 
      85       16108 :         if (hapd->iface->current_mode == NULL ||
      86        8049 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
      87         136 :                 return 0;
      88             : 
      89        7923 :         if (hapd->iface->olbc)
      90           2 :                 erp |= ERP_INFO_USE_PROTECTION;
      91        7923 :         if (hapd->iface->num_sta_non_erp > 0) {
      92           0 :                 erp |= ERP_INFO_NON_ERP_PRESENT |
      93             :                         ERP_INFO_USE_PROTECTION;
      94             :         }
      95       15846 :         if (hapd->iface->num_sta_no_short_preamble > 0 ||
      96        7923 :             hapd->iconf->preamble == LONG_PREAMBLE)
      97        7920 :                 erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
      98             : 
      99        7923 :         return erp;
     100             : }
     101             : 
     102             : 
     103        5314 : static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
     104             : {
     105        5314 :         *eid++ = WLAN_EID_DS_PARAMS;
     106        5314 :         *eid++ = 1;
     107        5314 :         *eid++ = hapd->iconf->channel;
     108        5314 :         return eid;
     109             : }
     110             : 
     111             : 
     112        5314 : static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
     113             : {
     114       10618 :         if (hapd->iface->current_mode == NULL ||
     115        5304 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
     116         189 :                 return eid;
     117             : 
     118             :         /* Set NonERP_present and use_protection bits if there
     119             :          * are any associated NonERP stations. */
     120             :         /* TODO: use_protection bit can be set to zero even if
     121             :          * there are NonERP stations present. This optimization
     122             :          * might be useful if NonERP stations are "quiet".
     123             :          * See 802.11g/D6 E-1 for recommended practice.
     124             :          * In addition, Non ERP present might be set, if AP detects Non ERP
     125             :          * operation on other APs. */
     126             : 
     127             :         /* Add ERP Information element */
     128        5125 :         *eid++ = WLAN_EID_ERP_INFO;
     129        5125 :         *eid++ = 1;
     130        5125 :         *eid++ = ieee802_11_erp_info(hapd);
     131             : 
     132        5125 :         return eid;
     133             : }
     134             : 
     135             : 
     136        5314 : static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
     137             : {
     138        5314 :         u8 *pos = eid;
     139        5314 :         u8 local_pwr_constraint = 0;
     140             :         int dfs;
     141             : 
     142       10618 :         if (hapd->iface->current_mode == NULL ||
     143        5304 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
     144        5145 :                 return eid;
     145             : 
     146             :         /* Let host drivers add this IE if DFS support is offloaded */
     147         169 :         if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
     148           0 :                 return eid;
     149             : 
     150             :         /*
     151             :          * There is no DFS support and power constraint was not directly
     152             :          * requested by config option.
     153             :          */
     154         309 :         if (!hapd->iconf->ieee80211h &&
     155         140 :             hapd->iconf->local_pwr_constraint == -1)
     156         138 :                 return eid;
     157             : 
     158             :         /* Check if DFS is required by regulatory. */
     159          31 :         dfs = hostapd_is_dfs_required(hapd->iface);
     160          31 :         if (dfs < 0) {
     161           0 :                 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
     162             :                            dfs);
     163           0 :                 dfs = 0;
     164             :         }
     165             : 
     166          31 :         if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1)
     167          14 :                 return eid;
     168             : 
     169             :         /*
     170             :          * ieee80211h (DFS) is enabled so Power Constraint element shall
     171             :          * be added when running on DFS channel whenever local_pwr_constraint
     172             :          * is configured or not. In order to meet regulations when TPC is not
     173             :          * implemented using a transmit power that is below the legal maximum
     174             :          * (including any mitigation factor) should help. In this case,
     175             :          * indicate 3 dB below maximum allowed transmit power.
     176             :          */
     177          17 :         if (hapd->iconf->local_pwr_constraint == -1)
     178          15 :                 local_pwr_constraint = 3;
     179             : 
     180             :         /*
     181             :          * A STA that is not an AP shall use a transmit power less than or
     182             :          * equal to the local maximum transmit power level for the channel.
     183             :          * The local maximum transmit power can be calculated from the formula:
     184             :          * local max TX pwr = max TX pwr - local pwr constraint
     185             :          * Where max TX pwr is maximum transmit power level specified for
     186             :          * channel in Country element and local pwr constraint is specified
     187             :          * for channel in this Power Constraint element.
     188             :          */
     189             : 
     190             :         /* Element ID */
     191          17 :         *pos++ = WLAN_EID_PWR_CONSTRAINT;
     192             :         /* Length */
     193          17 :         *pos++ = 1;
     194             :         /* Local Power Constraint */
     195          17 :         if (local_pwr_constraint)
     196          15 :                 *pos++ = local_pwr_constraint;
     197             :         else
     198           2 :                 *pos++ = hapd->iconf->local_pwr_constraint;
     199             : 
     200          17 :         return pos;
     201             : }
     202             : 
     203             : 
     204          70 : static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
     205             :                                     struct hostapd_channel_data *start,
     206             :                                     struct hostapd_channel_data *prev)
     207             : {
     208          70 :         if (end - pos < 3)
     209           0 :                 return pos;
     210             : 
     211             :         /* first channel number */
     212          70 :         *pos++ = start->chan;
     213             :         /* number of channels */
     214          70 :         *pos++ = (prev->chan - start->chan) / chan_spacing + 1;
     215             :         /* maximum transmit power level */
     216          70 :         *pos++ = start->max_tx_power;
     217             : 
     218          70 :         return pos;
     219             : }
     220             : 
     221             : 
     222        5314 : static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
     223             :                                 int max_len)
     224             : {
     225        5314 :         u8 *pos = eid;
     226        5314 :         u8 *end = eid + max_len;
     227             :         int i;
     228             :         struct hostapd_hw_modes *mode;
     229             :         struct hostapd_channel_data *start, *prev;
     230        5314 :         int chan_spacing = 1;
     231             : 
     232        5352 :         if (!hapd->iconf->ieee80211d || max_len < 6 ||
     233          38 :             hapd->iface->current_mode == NULL)
     234        5276 :                 return eid;
     235             : 
     236          38 :         *pos++ = WLAN_EID_COUNTRY;
     237          38 :         pos++; /* length will be set later */
     238          38 :         os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
     239          38 :         pos += 3;
     240             : 
     241          38 :         mode = hapd->iface->current_mode;
     242          38 :         if (mode->mode == HOSTAPD_MODE_IEEE80211A)
     243          35 :                 chan_spacing = 4;
     244             : 
     245          38 :         start = prev = NULL;
     246         920 :         for (i = 0; i < mode->num_channels; i++) {
     247         882 :                 struct hostapd_channel_data *chan = &mode->channels[i];
     248         882 :                 if (chan->flag & HOSTAPD_CHAN_DISABLED)
     249         286 :                         continue;
     250        1154 :                 if (start && prev &&
     251        1087 :                     prev->chan + chan_spacing == chan->chan &&
     252         529 :                     start->max_tx_power == chan->max_tx_power) {
     253         526 :                         prev = chan;
     254         526 :                         continue; /* can use same entry */
     255             :                 }
     256             : 
     257          70 :                 if (start && prev) {
     258          32 :                         pos = hostapd_eid_country_add(pos, end, chan_spacing,
     259             :                                                       start, prev);
     260          32 :                         start = NULL;
     261             :                 }
     262             : 
     263             :                 /* Start new group */
     264          70 :                 start = prev = chan;
     265             :         }
     266             : 
     267          38 :         if (start) {
     268          38 :                 pos = hostapd_eid_country_add(pos, end, chan_spacing,
     269             :                                               start, prev);
     270             :         }
     271             : 
     272          38 :         if ((pos - eid) & 1) {
     273          26 :                 if (end - pos < 1)
     274           0 :                         return eid;
     275          26 :                 *pos++ = 0; /* pad for 16-bit alignment */
     276             :         }
     277             : 
     278          38 :         eid[1] = (pos - eid) - 2;
     279             : 
     280          38 :         return pos;
     281             : }
     282             : 
     283             : 
     284        5314 : static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
     285             : {
     286             :         const u8 *ie;
     287             :         size_t ielen;
     288             : 
     289        5314 :         ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
     290        5314 :         if (ie == NULL || ielen > len)
     291        1279 :                 return eid;
     292             : 
     293        4035 :         os_memcpy(eid, ie, ielen);
     294        4035 :         return eid + ielen;
     295             : }
     296             : 
     297             : 
     298        5314 : static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
     299             : {
     300             :         u8 chan;
     301             : 
     302        5314 :         if (!hapd->cs_freq_params.freq)
     303        5291 :                 return eid;
     304             : 
     305          23 :         if (ieee80211_freq_to_chan(hapd->cs_freq_params.freq, &chan) ==
     306             :             NUM_HOSTAPD_MODES)
     307           0 :                 return eid;
     308             : 
     309          23 :         *eid++ = WLAN_EID_CHANNEL_SWITCH;
     310          23 :         *eid++ = 3;
     311          23 :         *eid++ = hapd->cs_block_tx;
     312          23 :         *eid++ = chan;
     313          23 :         *eid++ = hapd->cs_count;
     314             : 
     315          23 :         return eid;
     316             : }
     317             : 
     318             : 
     319          23 : static u8 * hostapd_eid_secondary_channel(struct hostapd_data *hapd, u8 *eid)
     320             : {
     321             :         u8 sec_ch;
     322             : 
     323          23 :         if (!hapd->cs_freq_params.sec_channel_offset)
     324          14 :                 return eid;
     325             : 
     326           9 :         if (hapd->cs_freq_params.sec_channel_offset == -1)
     327           2 :                 sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
     328           7 :         else if (hapd->cs_freq_params.sec_channel_offset == 1)
     329           6 :                 sec_ch = HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
     330             :         else
     331           1 :                 return eid;
     332             : 
     333           8 :         *eid++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET;
     334           8 :         *eid++ = 1;
     335           8 :         *eid++ = sec_ch;
     336             : 
     337           8 :         return eid;
     338             : }
     339             : 
     340             : 
     341        5314 : static u8 * hostapd_add_csa_elems(struct hostapd_data *hapd, u8 *pos,
     342             :                                   u8 *start, unsigned int *csa_counter_off)
     343             : {
     344        5314 :         u8 *old_pos = pos;
     345             : 
     346        5314 :         if (!csa_counter_off)
     347           0 :                 return pos;
     348             : 
     349        5314 :         *csa_counter_off = 0;
     350        5314 :         pos = hostapd_eid_csa(hapd, pos);
     351             : 
     352        5314 :         if (pos != old_pos) {
     353             :                 /* save an offset to the counter - should be last byte */
     354          23 :                 *csa_counter_off = pos - start - 1;
     355          23 :                 pos = hostapd_eid_secondary_channel(hapd, pos);
     356             :         }
     357             : 
     358        5314 :         return pos;
     359             : }
     360             : 
     361             : 
     362        2380 : static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
     363             :                                    struct sta_info *sta,
     364             :                                    const struct ieee80211_mgmt *req,
     365             :                                    int is_p2p, size_t *resp_len)
     366             : {
     367             :         struct ieee80211_mgmt *resp;
     368             :         u8 *pos, *epos;
     369             :         size_t buflen;
     370             : 
     371             : #define MAX_PROBERESP_LEN 768
     372        2380 :         buflen = MAX_PROBERESP_LEN;
     373             : #ifdef CONFIG_WPS
     374        2380 :         if (hapd->wps_probe_resp_ie)
     375         665 :                 buflen += wpabuf_len(hapd->wps_probe_resp_ie);
     376             : #endif /* CONFIG_WPS */
     377             : #ifdef CONFIG_P2P
     378         384 :         if (hapd->p2p_probe_resp_ie)
     379         358 :                 buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
     380             : #endif /* CONFIG_P2P */
     381        2380 :         if (hapd->conf->vendor_elements)
     382           1 :                 buflen += wpabuf_len(hapd->conf->vendor_elements);
     383        2380 :         if (hapd->conf->vendor_vht) {
     384           2 :                 buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
     385             :                         2 + sizeof(struct ieee80211_vht_operation);
     386             :         }
     387        2380 :         resp = os_zalloc(buflen);
     388        2380 :         if (resp == NULL)
     389           0 :                 return NULL;
     390             : 
     391        2380 :         epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
     392             : 
     393        2380 :         resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
     394             :                                            WLAN_FC_STYPE_PROBE_RESP);
     395        2380 :         if (req)
     396        2380 :                 os_memcpy(resp->da, req->sa, ETH_ALEN);
     397        2380 :         os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
     398             : 
     399        2380 :         os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
     400        2380 :         resp->u.probe_resp.beacon_int =
     401        2380 :                 host_to_le16(hapd->iconf->beacon_int);
     402             : 
     403             :         /* hardware or low-level driver will setup seq_ctrl and timestamp */
     404        2380 :         resp->u.probe_resp.capab_info =
     405        2380 :                 host_to_le16(hostapd_own_capab_info(hapd, sta, 1));
     406             : 
     407        2380 :         pos = resp->u.probe_resp.variable;
     408        2380 :         *pos++ = WLAN_EID_SSID;
     409        2380 :         *pos++ = hapd->conf->ssid.ssid_len;
     410        2380 :         os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
     411        2380 :         pos += hapd->conf->ssid.ssid_len;
     412             : 
     413             :         /* Supported rates */
     414        2380 :         pos = hostapd_eid_supp_rates(hapd, pos);
     415             : 
     416             :         /* DS Params */
     417        2380 :         pos = hostapd_eid_ds_params(hapd, pos);
     418             : 
     419        2380 :         pos = hostapd_eid_country(hapd, pos, epos - pos);
     420             : 
     421             :         /* Power Constraint element */
     422        2380 :         pos = hostapd_eid_pwr_constraint(hapd, pos);
     423             : 
     424             :         /* ERP Information element */
     425        2380 :         pos = hostapd_eid_erp_info(hapd, pos);
     426             : 
     427             :         /* Extended supported rates */
     428        2380 :         pos = hostapd_eid_ext_supp_rates(hapd, pos);
     429             : 
     430             :         /* RSN, MDIE, WPA */
     431        2380 :         pos = hostapd_eid_wpa(hapd, pos, epos - pos);
     432             : 
     433        2380 :         pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
     434             : 
     435        2380 :         pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
     436             : 
     437             : #ifdef CONFIG_IEEE80211N
     438        2380 :         pos = hostapd_eid_ht_capabilities(hapd, pos);
     439        2380 :         pos = hostapd_eid_ht_operation(hapd, pos);
     440             : #endif /* CONFIG_IEEE80211N */
     441             : 
     442        2380 :         pos = hostapd_eid_ext_capab(hapd, pos);
     443             : 
     444        2380 :         pos = hostapd_eid_time_adv(hapd, pos);
     445        2380 :         pos = hostapd_eid_time_zone(hapd, pos);
     446             : 
     447        2380 :         pos = hostapd_eid_interworking(hapd, pos);
     448        2380 :         pos = hostapd_eid_adv_proto(hapd, pos);
     449        2380 :         pos = hostapd_eid_roaming_consortium(hapd, pos);
     450             : 
     451        2380 :         pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp,
     452             :                                     &hapd->cs_c_off_proberesp);
     453             : #ifdef CONFIG_IEEE80211AC
     454        1996 :         if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
     455          15 :                 pos = hostapd_eid_vht_capabilities(hapd, pos);
     456          15 :                 pos = hostapd_eid_vht_operation(hapd, pos);
     457             :         }
     458        1996 :         if (hapd->conf->vendor_vht)
     459           2 :                 pos = hostapd_eid_vendor_vht(hapd, pos);
     460             : #endif /* CONFIG_IEEE80211AC */
     461             : 
     462             :         /* Wi-Fi Alliance WMM */
     463        2380 :         pos = hostapd_eid_wmm(hapd, pos);
     464             : 
     465             : #ifdef CONFIG_WPS
     466        2380 :         if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
     467         665 :                 os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
     468             :                           wpabuf_len(hapd->wps_probe_resp_ie));
     469         665 :                 pos += wpabuf_len(hapd->wps_probe_resp_ie);
     470             :         }
     471             : #endif /* CONFIG_WPS */
     472             : 
     473             : #ifdef CONFIG_P2P
     474         719 :         if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p &&
     475         335 :             hapd->p2p_probe_resp_ie) {
     476         335 :                 os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
     477             :                           wpabuf_len(hapd->p2p_probe_resp_ie));
     478         335 :                 pos += wpabuf_len(hapd->p2p_probe_resp_ie);
     479             :         }
     480             : #endif /* CONFIG_P2P */
     481             : #ifdef CONFIG_P2P_MANAGER
     482        1996 :         if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
     483             :             P2P_MANAGE)
     484           6 :                 pos = hostapd_eid_p2p_manage(hapd, pos);
     485             : #endif /* CONFIG_P2P_MANAGER */
     486             : 
     487             : #ifdef CONFIG_HS20
     488        2380 :         pos = hostapd_eid_hs20_indication(hapd, pos);
     489        2380 :         pos = hostapd_eid_osen(hapd, pos);
     490             : #endif /* CONFIG_HS20 */
     491             : 
     492        2380 :         if (hapd->conf->vendor_elements) {
     493           1 :                 os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
     494             :                           wpabuf_len(hapd->conf->vendor_elements));
     495           1 :                 pos += wpabuf_len(hapd->conf->vendor_elements);
     496             :         }
     497             : 
     498        2380 :         *resp_len = pos - (u8 *) resp;
     499        2380 :         return (u8 *) resp;
     500             : }
     501             : 
     502             : 
     503             : enum ssid_match_result {
     504             :         NO_SSID_MATCH,
     505             :         EXACT_SSID_MATCH,
     506             :         WILDCARD_SSID_MATCH
     507             : };
     508             : 
     509        2526 : static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
     510             :                                          const u8 *ssid, size_t ssid_len,
     511             :                                          const u8 *ssid_list,
     512             :                                          size_t ssid_list_len)
     513             : {
     514             :         const u8 *pos, *end;
     515        2526 :         int wildcard = 0;
     516             : 
     517        2526 :         if (ssid_len == 0)
     518        1987 :                 wildcard = 1;
     519        2955 :         if (ssid_len == hapd->conf->ssid.ssid_len &&
     520         429 :             os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
     521         409 :                 return EXACT_SSID_MATCH;
     522             : 
     523        2117 :         if (ssid_list == NULL)
     524        2117 :                 return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
     525             : 
     526           0 :         pos = ssid_list;
     527           0 :         end = ssid_list + ssid_list_len;
     528           0 :         while (pos + 1 <= end) {
     529           0 :                 if (pos + 2 + pos[1] > end)
     530           0 :                         break;
     531           0 :                 if (pos[1] == 0)
     532           0 :                         wildcard = 1;
     533           0 :                 if (pos[1] == hapd->conf->ssid.ssid_len &&
     534           0 :                     os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
     535           0 :                         return EXACT_SSID_MATCH;
     536           0 :                 pos += 2 + pos[1];
     537             :         }
     538             : 
     539           0 :         return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
     540             : }
     541             : 
     542             : 
     543        2549 : void handle_probe_req(struct hostapd_data *hapd,
     544             :                       const struct ieee80211_mgmt *mgmt, size_t len,
     545             :                       int ssi_signal)
     546             : {
     547             :         u8 *resp;
     548             :         struct ieee802_11_elems elems;
     549             :         const u8 *ie;
     550             :         size_t ie_len;
     551        2549 :         struct sta_info *sta = NULL;
     552             :         size_t i, resp_len;
     553             :         int noack;
     554             :         enum ssid_match_result res;
     555             : 
     556        2549 :         ie = mgmt->u.probe_req.variable;
     557        2549 :         if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
     558         169 :                 return;
     559        2549 :         ie_len = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
     560             : 
     561        3638 :         for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
     562        2178 :                 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
     563        1089 :                                             mgmt->sa, mgmt->da, mgmt->bssid,
     564             :                                             ie, ie_len, ssi_signal) > 0)
     565           0 :                         return;
     566             : 
     567        2549 :         if (!hapd->iconf->send_probe_response)
     568           0 :                 return;
     569             : 
     570        2549 :         if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
     571           0 :                 wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
     572           0 :                            MAC2STR(mgmt->sa));
     573           0 :                 return;
     574             :         }
     575             : 
     576        2549 :         if ((!elems.ssid || !elems.supp_rates)) {
     577           0 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
     578             :                            "without SSID or supported rates element",
     579           0 :                            MAC2STR(mgmt->sa));
     580           0 :                 return;
     581             :         }
     582             : 
     583             :         /*
     584             :          * No need to reply if the Probe Request frame was sent on an adjacent
     585             :          * channel. IEEE Std 802.11-2012 describes this as a requirement for an
     586             :          * AP with dot11RadioMeasurementActivated set to true, but strictly
     587             :          * speaking does not allow such ignoring of Probe Request frames if
     588             :          * dot11RadioMeasurementActivated is false. Anyway, this can help reduce
     589             :          * number of unnecessary Probe Response frames for cases where the STA
     590             :          * is less likely to see them (Probe Request frame sent on a
     591             :          * neighboring, but partially overlapping, channel).
     592             :          */
     593        4832 :         if (elems.ds_params && elems.ds_params_len == 1 &&
     594        4566 :             hapd->iface->current_mode &&
     595        2285 :             (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G ||
     596        2285 :              hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B) &&
     597        2283 :             hapd->iconf->channel != elems.ds_params[0]) {
     598           0 :                 wpa_printf(MSG_DEBUG,
     599             :                            "Ignore Probe Request due to DS Params mismatch: chan=%u != ds.chan=%u",
     600           0 :                            hapd->iconf->channel, elems.ds_params[0]);
     601           0 :                 return;
     602             :         }
     603             : 
     604             : #ifdef CONFIG_P2P
     605         400 :         if (hapd->p2p && elems.wps_ie) {
     606             :                 struct wpabuf *wps;
     607         369 :                 wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
     608         369 :                 if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
     609           2 :                         wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
     610             :                                    "due to mismatch with Requested Device "
     611             :                                    "Type");
     612           2 :                         wpabuf_free(wps);
     613           2 :                         return;
     614             :                 }
     615         367 :                 wpabuf_free(wps);
     616             :         }
     617             : 
     618         398 :         if (hapd->p2p && elems.p2p) {
     619             :                 struct wpabuf *p2p;
     620         365 :                 p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
     621         365 :                 if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
     622           4 :                         wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
     623             :                                    "due to mismatch with Device ID");
     624           4 :                         wpabuf_free(p2p);
     625           4 :                         return;
     626             :                 }
     627         361 :                 wpabuf_free(p2p);
     628             :         }
     629             : #endif /* CONFIG_P2P */
     630             : 
     631        2560 :         if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
     632          17 :             elems.ssid_list_len == 0) {
     633         102 :                 wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
     634         102 :                            "broadcast SSID ignored", MAC2STR(mgmt->sa));
     635          17 :                 return;
     636             :         }
     637             : 
     638        2526 :         sta = ap_get_sta(hapd, mgmt->sa);
     639             : 
     640             : #ifdef CONFIG_P2P
     641         762 :         if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
     642         497 :             elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
     643         129 :             os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
     644             :                       P2P_WILDCARD_SSID_LEN) == 0) {
     645             :                 /* Process P2P Wildcard SSID like Wildcard SSID */
     646         129 :                 elems.ssid_len = 0;
     647             :         }
     648             : #endif /* CONFIG_P2P */
     649             : 
     650        2526 :         res = ssid_match(hapd, elems.ssid, elems.ssid_len,
     651        2526 :                          elems.ssid_list, elems.ssid_list_len);
     652        2526 :         if (res != NO_SSID_MATCH) {
     653        2396 :                 if (sta)
     654         260 :                         sta->ssid_probe = &hapd->conf->ssid;
     655             :         } else {
     656         130 :                 if (!(mgmt->da[0] & 0x01)) {
     657           0 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     658             :                                    " for foreign SSID '%s' (DA " MACSTR ")%s",
     659           0 :                                    MAC2STR(mgmt->sa),
     660           0 :                                    wpa_ssid_txt(elems.ssid, elems.ssid_len),
     661           0 :                                    MAC2STR(mgmt->da),
     662           0 :                                    elems.ssid_list ? " (SSID list)" : "");
     663             :                 }
     664         130 :                 return;
     665             :         }
     666             : 
     667             : #ifdef CONFIG_INTERWORKING
     668        2707 :         if (hapd->conf->interworking &&
     669         589 :             elems.interworking && elems.interworking_len >= 1) {
     670         278 :                 u8 ant = elems.interworking[0] & 0x0f;
     671         288 :                 if (ant != INTERWORKING_ANT_WILDCARD &&
     672          10 :                     ant != hapd->conf->access_network_type) {
     673          35 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     674             :                                    " for mismatching ANT %u ignored",
     675          30 :                                    MAC2STR(mgmt->sa), ant);
     676           5 :                         return;
     677             :                 }
     678             :         }
     679             : 
     680        2664 :         if (hapd->conf->interworking && elems.interworking &&
     681         541 :             (elems.interworking_len == 7 || elems.interworking_len == 9)) {
     682             :                 const u8 *hessid;
     683           5 :                 if (elems.interworking_len == 7)
     684           5 :                         hessid = elems.interworking + 1;
     685             :                 else
     686           0 :                         hessid = elems.interworking + 1 + 2;
     687          10 :                 if (!is_broadcast_ether_addr(hessid) &&
     688           5 :                     os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
     689          36 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     690             :                                    " for mismatching HESSID " MACSTR
     691             :                                    " ignored",
     692          36 :                                    MAC2STR(mgmt->sa), MAC2STR(hessid));
     693           3 :                         return;
     694             :                 }
     695             :         }
     696             : #endif /* CONFIG_INTERWORKING */
     697             : 
     698             : #ifdef CONFIG_P2P
     699         742 :         if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
     700         358 :             supp_rates_11b_only(&elems)) {
     701             :                 /* Indicates support for 11b rates only */
     702           0 :                 wpa_printf(MSG_EXCESSIVE, "P2P: Ignore Probe Request from "
     703             :                            MACSTR " with only 802.11b rates",
     704           0 :                            MAC2STR(mgmt->sa));
     705           0 :                 return;
     706             :         }
     707             : #endif /* CONFIG_P2P */
     708             : 
     709             :         /* TODO: verify that supp_rates contains at least one matching rate
     710             :          * with AP configuration */
     711             : 
     712             : #ifdef CONFIG_TESTING_OPTIONS
     713        2399 :         if (hapd->iconf->ignore_probe_probability > 0.0 &&
     714          11 :             drand48() < hapd->iconf->ignore_probe_probability) {
     715          48 :                 wpa_printf(MSG_INFO,
     716             :                            "TESTING: ignoring probe request from " MACSTR,
     717          48 :                            MAC2STR(mgmt->sa));
     718           8 :                 return;
     719             :         }
     720             : #endif /* CONFIG_TESTING_OPTIONS */
     721             : 
     722        2380 :         resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL,
     723             :                                       &resp_len);
     724        2380 :         if (resp == NULL)
     725           0 :                 return;
     726             : 
     727             :         /*
     728             :          * If this is a broadcast probe request, apply no ack policy to avoid
     729             :          * excessive retries.
     730             :          */
     731        4351 :         noack = !!(res == WILDCARD_SSID_MATCH &&
     732        1971 :                    is_broadcast_ether_addr(mgmt->da));
     733             : 
     734        2380 :         if (hostapd_drv_send_mlme(hapd, resp, resp_len, noack) < 0)
     735           4 :                 wpa_printf(MSG_INFO, "handle_probe_req: send failed");
     736             : 
     737        2380 :         os_free(resp);
     738             : 
     739       16660 :         wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
     740       14280 :                    "SSID", MAC2STR(mgmt->sa),
     741        2380 :                    elems.ssid_len == 0 ? "broadcast" : "our");
     742             : }
     743             : 
     744             : 
     745        2934 : static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
     746             :                                         size_t *resp_len)
     747             : {
     748             :         /* check probe response offloading caps and print warnings */
     749        2934 :         if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD))
     750        2934 :                 return NULL;
     751             : 
     752             : #ifdef CONFIG_WPS
     753           0 :         if (hapd->conf->wps_state && hapd->wps_probe_resp_ie &&
     754           0 :             (!(hapd->iface->probe_resp_offloads &
     755             :                (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS |
     756             :                 WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2))))
     757           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload WPS "
     758             :                            "Probe Response while not supporting this");
     759             : #endif /* CONFIG_WPS */
     760             : 
     761             : #ifdef CONFIG_P2P
     762           0 :         if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie &&
     763           0 :             !(hapd->iface->probe_resp_offloads &
     764             :               WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P))
     765           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload P2P "
     766             :                            "Probe Response while not supporting this");
     767             : #endif  /* CONFIG_P2P */
     768             : 
     769           0 :         if (hapd->conf->interworking &&
     770           0 :             !(hapd->iface->probe_resp_offloads &
     771             :               WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING))
     772           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload "
     773             :                            "Interworking Probe Response while not supporting "
     774             :                            "this");
     775             : 
     776             :         /* Generate a Probe Response template for the non-P2P case */
     777           0 :         return hostapd_gen_probe_resp(hapd, NULL, NULL, 0, resp_len);
     778             : }
     779             : 
     780             : #endif /* NEED_AP_MLME */
     781             : 
     782             : 
     783        2936 : int ieee802_11_build_ap_params(struct hostapd_data *hapd,
     784             :                                struct wpa_driver_ap_params *params)
     785             : {
     786        2936 :         struct ieee80211_mgmt *head = NULL;
     787        2936 :         u8 *tail = NULL;
     788        2936 :         size_t head_len = 0, tail_len = 0;
     789        2936 :         u8 *resp = NULL;
     790        2936 :         size_t resp_len = 0;
     791             : #ifdef NEED_AP_MLME
     792             :         u16 capab_info;
     793             :         u8 *pos, *tailpos;
     794             : 
     795             : #define BEACON_HEAD_BUF_SIZE 256
     796             : #define BEACON_TAIL_BUF_SIZE 512
     797        2936 :         head = os_zalloc(BEACON_HEAD_BUF_SIZE);
     798        2936 :         tail_len = BEACON_TAIL_BUF_SIZE;
     799             : #ifdef CONFIG_WPS
     800        2936 :         if (hapd->conf->wps_state && hapd->wps_beacon_ie)
     801        1826 :                 tail_len += wpabuf_len(hapd->wps_beacon_ie);
     802             : #endif /* CONFIG_WPS */
     803             : #ifdef CONFIG_P2P
     804        1530 :         if (hapd->p2p_beacon_ie)
     805        1494 :                 tail_len += wpabuf_len(hapd->p2p_beacon_ie);
     806             : #endif /* CONFIG_P2P */
     807        2936 :         if (hapd->conf->vendor_elements)
     808           1 :                 tail_len += wpabuf_len(hapd->conf->vendor_elements);
     809             : 
     810             : #ifdef CONFIG_IEEE80211AC
     811        1406 :         if (hapd->conf->vendor_vht) {
     812           1 :                 tail_len += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
     813             :                         2 + sizeof(struct ieee80211_vht_operation);
     814             :         }
     815             : #endif /* CONFIG_IEEE80211AC */
     816             : 
     817        2936 :         tailpos = tail = os_malloc(tail_len);
     818        2936 :         if (head == NULL || tail == NULL) {
     819           2 :                 wpa_printf(MSG_ERROR, "Failed to set beacon data");
     820           2 :                 os_free(head);
     821           2 :                 os_free(tail);
     822           2 :                 return -1;
     823             :         }
     824             : 
     825        2934 :         head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
     826             :                                            WLAN_FC_STYPE_BEACON);
     827        2934 :         head->duration = host_to_le16(0);
     828        2934 :         os_memset(head->da, 0xff, ETH_ALEN);
     829             : 
     830        2934 :         os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
     831        2934 :         os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
     832        2934 :         head->u.beacon.beacon_int =
     833        2934 :                 host_to_le16(hapd->iconf->beacon_int);
     834             : 
     835             :         /* hardware or low-level driver will setup seq_ctrl and timestamp */
     836        2934 :         capab_info = hostapd_own_capab_info(hapd, NULL, 0);
     837        2934 :         head->u.beacon.capab_info = host_to_le16(capab_info);
     838        2934 :         pos = &head->u.beacon.variable[0];
     839             : 
     840             :         /* SSID */
     841        2934 :         *pos++ = WLAN_EID_SSID;
     842        2934 :         if (hapd->conf->ignore_broadcast_ssid == 2) {
     843             :                 /* clear the data, but keep the correct length of the SSID */
     844           1 :                 *pos++ = hapd->conf->ssid.ssid_len;
     845           1 :                 os_memset(pos, 0, hapd->conf->ssid.ssid_len);
     846           1 :                 pos += hapd->conf->ssid.ssid_len;
     847        2933 :         } else if (hapd->conf->ignore_broadcast_ssid) {
     848           8 :                 *pos++ = 0; /* empty SSID */
     849             :         } else {
     850        2925 :                 *pos++ = hapd->conf->ssid.ssid_len;
     851        2925 :                 os_memcpy(pos, hapd->conf->ssid.ssid,
     852             :                           hapd->conf->ssid.ssid_len);
     853        2925 :                 pos += hapd->conf->ssid.ssid_len;
     854             :         }
     855             : 
     856             :         /* Supported rates */
     857        2934 :         pos = hostapd_eid_supp_rates(hapd, pos);
     858             : 
     859             :         /* DS Params */
     860        2934 :         pos = hostapd_eid_ds_params(hapd, pos);
     861             : 
     862        2934 :         head_len = pos - (u8 *) head;
     863             : 
     864        2934 :         tailpos = hostapd_eid_country(hapd, tailpos,
     865        2934 :                                       tail + BEACON_TAIL_BUF_SIZE - tailpos);
     866             : 
     867             :         /* Power Constraint element */
     868        2934 :         tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
     869             : 
     870             :         /* ERP Information element */
     871        2934 :         tailpos = hostapd_eid_erp_info(hapd, tailpos);
     872             : 
     873             :         /* Extended supported rates */
     874        2934 :         tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
     875             : 
     876             :         /* RSN, MDIE, WPA */
     877        2934 :         tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
     878             :                                   tailpos);
     879             : 
     880        2934 :         tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
     881        2934 :                                                tail + BEACON_TAIL_BUF_SIZE -
     882             :                                                tailpos);
     883             : 
     884        2934 :         tailpos = hostapd_eid_bss_load(hapd, tailpos,
     885        2934 :                                        tail + BEACON_TAIL_BUF_SIZE - tailpos);
     886             : 
     887             : #ifdef CONFIG_IEEE80211N
     888        2934 :         tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
     889        2934 :         tailpos = hostapd_eid_ht_operation(hapd, tailpos);
     890             : #endif /* CONFIG_IEEE80211N */
     891             : 
     892        2934 :         tailpos = hostapd_eid_ext_capab(hapd, tailpos);
     893             : 
     894             :         /*
     895             :          * TODO: Time Advertisement element should only be included in some
     896             :          * DTIM Beacon frames.
     897             :          */
     898        2934 :         tailpos = hostapd_eid_time_adv(hapd, tailpos);
     899             : 
     900        2934 :         tailpos = hostapd_eid_interworking(hapd, tailpos);
     901        2934 :         tailpos = hostapd_eid_adv_proto(hapd, tailpos);
     902        2934 :         tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
     903        2934 :         tailpos = hostapd_add_csa_elems(hapd, tailpos, tail,
     904             :                                         &hapd->cs_c_off_beacon);
     905             : #ifdef CONFIG_IEEE80211AC
     906        1404 :         if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
     907          18 :                 tailpos = hostapd_eid_vht_capabilities(hapd, tailpos);
     908          18 :                 tailpos = hostapd_eid_vht_operation(hapd, tailpos);
     909             :         }
     910        1404 :         if (hapd->conf->vendor_vht)
     911           1 :                 tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
     912             : #endif /* CONFIG_IEEE80211AC */
     913             : 
     914             :         /* Wi-Fi Alliance WMM */
     915        2934 :         tailpos = hostapd_eid_wmm(hapd, tailpos);
     916             : 
     917             : #ifdef CONFIG_WPS
     918        2934 :         if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
     919        1826 :                 os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
     920             :                           wpabuf_len(hapd->wps_beacon_ie));
     921        1826 :                 tailpos += wpabuf_len(hapd->wps_beacon_ie);
     922             :         }
     923             : #endif /* CONFIG_WPS */
     924             : 
     925             : #ifdef CONFIG_P2P
     926        1530 :         if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
     927        1494 :                 os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
     928             :                           wpabuf_len(hapd->p2p_beacon_ie));
     929        1494 :                 tailpos += wpabuf_len(hapd->p2p_beacon_ie);
     930             :         }
     931             : #endif /* CONFIG_P2P */
     932             : #ifdef CONFIG_P2P_MANAGER
     933        1404 :         if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
     934             :             P2P_MANAGE)
     935           5 :                 tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
     936             : #endif /* CONFIG_P2P_MANAGER */
     937             : 
     938             : #ifdef CONFIG_HS20
     939        2934 :         tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
     940        2934 :         tailpos = hostapd_eid_osen(hapd, tailpos);
     941             : #endif /* CONFIG_HS20 */
     942             : 
     943        2934 :         if (hapd->conf->vendor_elements) {
     944           1 :                 os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
     945             :                           wpabuf_len(hapd->conf->vendor_elements));
     946           1 :                 tailpos += wpabuf_len(hapd->conf->vendor_elements);
     947             :         }
     948             : 
     949        2934 :         tail_len = tailpos > tail ? tailpos - tail : 0;
     950             : 
     951        2934 :         resp = hostapd_probe_resp_offloads(hapd, &resp_len);
     952             : #endif /* NEED_AP_MLME */
     953             : 
     954        2934 :         os_memset(params, 0, sizeof(*params));
     955        2934 :         params->head = (u8 *) head;
     956        2934 :         params->head_len = head_len;
     957        2934 :         params->tail = tail;
     958        2934 :         params->tail_len = tail_len;
     959        2934 :         params->proberesp = resp;
     960        2934 :         params->proberesp_len = resp_len;
     961        2934 :         params->dtim_period = hapd->conf->dtim_period;
     962        2934 :         params->beacon_int = hapd->iconf->beacon_int;
     963        2934 :         params->basic_rates = hapd->iface->basic_rates;
     964        2934 :         params->ssid = hapd->conf->ssid.ssid;
     965        2934 :         params->ssid_len = hapd->conf->ssid.ssid_len;
     966        5868 :         params->pairwise_ciphers = hapd->conf->wpa_pairwise |
     967        2934 :                 hapd->conf->rsn_pairwise;
     968        2934 :         params->group_cipher = hapd->conf->wpa_group;
     969        2934 :         params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
     970        2934 :         params->auth_algs = hapd->conf->auth_algs;
     971        2934 :         params->wpa_version = hapd->conf->wpa;
     972        5870 :         params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
     973         499 :                 (hapd->conf->ieee802_1x &&
     974           8 :                  (hapd->conf->default_wep_key_len ||
     975           3 :                   hapd->conf->individual_wep_key_len));
     976        2934 :         switch (hapd->conf->ignore_broadcast_ssid) {
     977             :         case 0:
     978        2925 :                 params->hide_ssid = NO_SSID_HIDING;
     979        2925 :                 break;
     980             :         case 1:
     981           8 :                 params->hide_ssid = HIDDEN_SSID_ZERO_LEN;
     982           8 :                 break;
     983             :         case 2:
     984           1 :                 params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
     985           1 :                 break;
     986             :         }
     987        2934 :         params->isolate = hapd->conf->isolate;
     988        2934 :         params->smps_mode = hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_MASK;
     989             : #ifdef NEED_AP_MLME
     990        2934 :         params->cts_protect = !!(ieee802_11_erp_info(hapd) &
     991             :                                 ERP_INFO_USE_PROTECTION);
     992        5826 :         params->preamble = hapd->iface->num_sta_no_short_preamble == 0 &&
     993        2892 :                 hapd->iconf->preamble == SHORT_PREAMBLE;
     994        5858 :         if (hapd->iface->current_mode &&
     995        2924 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
     996        2798 :                 params->short_slot_time =
     997        2798 :                         hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1;
     998             :         else
     999         136 :                 params->short_slot_time = -1;
    1000        2934 :         if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
    1001         121 :                 params->ht_opmode = -1;
    1002             :         else
    1003        2813 :                 params->ht_opmode = hapd->iface->ht_op_mode;
    1004             : #endif /* NEED_AP_MLME */
    1005        2934 :         params->interworking = hapd->conf->interworking;
    1006        3054 :         if (hapd->conf->interworking &&
    1007         120 :             !is_zero_ether_addr(hapd->conf->hessid))
    1008          54 :                 params->hessid = hapd->conf->hessid;
    1009        2934 :         params->access_network_type = hapd->conf->access_network_type;
    1010        2934 :         params->ap_max_inactivity = hapd->conf->ap_max_inactivity;
    1011             : #ifdef CONFIG_P2P
    1012        1530 :         params->p2p_go_ctwindow = hapd->iconf->p2p_go_ctwindow;
    1013             : #endif /* CONFIG_P2P */
    1014             : #ifdef CONFIG_HS20
    1015        2934 :         params->disable_dgaf = hapd->conf->disable_dgaf;
    1016        2934 :         if (hapd->conf->osen) {
    1017           1 :                 params->privacy = 1;
    1018           1 :                 params->osen = 1;
    1019             :         }
    1020             : #endif /* CONFIG_HS20 */
    1021        2934 :         return 0;
    1022             : }
    1023             : 
    1024             : 
    1025        2934 : void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
    1026             : {
    1027        2934 :         os_free(params->tail);
    1028        2934 :         params->tail = NULL;
    1029        2934 :         os_free(params->head);
    1030        2934 :         params->head = NULL;
    1031        2934 :         os_free(params->proberesp);
    1032        2934 :         params->proberesp = NULL;
    1033        2934 : }
    1034             : 
    1035             : 
    1036        2890 : int ieee802_11_set_beacon(struct hostapd_data *hapd)
    1037             : {
    1038             :         struct wpa_driver_ap_params params;
    1039             :         struct hostapd_freq_params freq;
    1040        2890 :         struct hostapd_iface *iface = hapd->iface;
    1041        2890 :         struct hostapd_config *iconf = iface->conf;
    1042             :         struct wpabuf *beacon, *proberesp, *assocresp;
    1043        2890 :         int res, ret = -1;
    1044             : 
    1045        2890 :         if (hapd->csa_in_progress) {
    1046           0 :                 wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
    1047           0 :                 return -1;
    1048             :         }
    1049             : 
    1050        2890 :         hapd->beacon_set_done = 1;
    1051             : 
    1052        2890 :         if (ieee802_11_build_ap_params(hapd, &params) < 0)
    1053           2 :                 return -1;
    1054             : 
    1055        2888 :         if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
    1056             :             0)
    1057           0 :                 goto fail;
    1058             : 
    1059        2888 :         params.beacon_ies = beacon;
    1060        2888 :         params.proberesp_ies = proberesp;
    1061        2888 :         params.assocresp_ies = assocresp;
    1062        2888 :         params.reenable = hapd->reenable_beacon;
    1063        2888 :         hapd->reenable_beacon = 0;
    1064             : 
    1065        5766 :         if (iface->current_mode &&
    1066       14390 :             hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
    1067        2878 :                                     iconf->channel, iconf->ieee80211n,
    1068             :                                     iconf->ieee80211ac,
    1069             :                                     iconf->secondary_channel,
    1070        2878 :                                     iconf->vht_oper_chwidth,
    1071        2878 :                                     iconf->vht_oper_centr_freq_seg0_idx,
    1072        2878 :                                     iconf->vht_oper_centr_freq_seg1_idx,
    1073        2878 :                                     iface->current_mode->vht_capab) == 0)
    1074        2878 :                 params.freq = &freq;
    1075             : 
    1076        2888 :         res = hostapd_drv_set_ap(hapd, &params);
    1077        2888 :         hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
    1078        2888 :         if (res)
    1079           9 :                 wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
    1080             :         else
    1081        2879 :                 ret = 0;
    1082             : fail:
    1083        2888 :         ieee802_11_free_ap_params(&params);
    1084        2888 :         return ret;
    1085             : }
    1086             : 
    1087             : 
    1088         792 : int ieee802_11_set_beacons(struct hostapd_iface *iface)
    1089             : {
    1090             :         size_t i;
    1091         792 :         int ret = 0;
    1092             : 
    1093        1588 :         for (i = 0; i < iface->num_bss; i++) {
    1094        1592 :                 if (iface->bss[i]->started &&
    1095         796 :                     ieee802_11_set_beacon(iface->bss[i]) < 0)
    1096           8 :                         ret = -1;
    1097             :         }
    1098             : 
    1099         792 :         return ret;
    1100             : }
    1101             : 
    1102             : 
    1103             : /* only update beacons if started */
    1104           5 : int ieee802_11_update_beacons(struct hostapd_iface *iface)
    1105             : {
    1106             :         size_t i;
    1107           5 :         int ret = 0;
    1108             : 
    1109          10 :         for (i = 0; i < iface->num_bss; i++) {
    1110          10 :                 if (iface->bss[i]->beacon_set_done && iface->bss[i]->started &&
    1111           5 :                     ieee802_11_set_beacon(iface->bss[i]) < 0)
    1112           0 :                         ret = -1;
    1113             :         }
    1114             : 
    1115           5 :         return ret;
    1116             : }
    1117             : 
    1118             : #endif /* CONFIG_NATIVE_WINDOWS */

Generated by: LCOV version 1.10