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

Generated by: LCOV version 1.10