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

Generated by: LCOV version 1.10