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 1475438200 Lines: 633 694 91.2 %
Date: 2016-10-02 Functions: 27 27 100.0 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
       3             :  * Copyright (c) 2002-2004, Instant802 Networks, Inc.
       4             :  * Copyright (c) 2005-2006, Devicescape Software, Inc.
       5             :  * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
       6             :  *
       7             :  * This software may be distributed under the terms of the BSD license.
       8             :  * See README for more details.
       9             :  */
      10             : 
      11             : #include "utils/includes.h"
      12             : 
      13             : #ifndef CONFIG_NATIVE_WINDOWS
      14             : 
      15             : #include "utils/common.h"
      16             : #include "common/ieee802_11_defs.h"
      17             : #include "common/ieee802_11_common.h"
      18             : #include "common/hw_features_common.h"
      19             : #include "wps/wps_defs.h"
      20             : #include "p2p/p2p.h"
      21             : #include "hostapd.h"
      22             : #include "ieee802_11.h"
      23             : #include "wpa_auth.h"
      24             : #include "wmm.h"
      25             : #include "ap_config.h"
      26             : #include "sta_info.h"
      27             : #include "p2p_hostapd.h"
      28             : #include "ap_drv_ops.h"
      29             : #include "beacon.h"
      30             : #include "hs20.h"
      31             : #include "dfs.h"
      32             : #include "taxonomy.h"
      33             : 
      34             : 
      35             : #ifdef NEED_AP_MLME
      36             : 
      37       10167 : static u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
      38             :                                          size_t len)
      39             : {
      40             :         size_t i;
      41             : 
      42       60967 :         for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
      43       50807 :                 if (hapd->conf->radio_measurements[i])
      44           7 :                         break;
      45             :         }
      46             : 
      47       10167 :         if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
      48       10160 :                 return eid;
      49             : 
      50           7 :         *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
      51           7 :         *eid++ = RRM_CAPABILITIES_IE_LEN;
      52           7 :         os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
      53             : 
      54           7 :         return eid + RRM_CAPABILITIES_IE_LEN;
      55             : }
      56             : 
      57             : 
      58       10167 : static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
      59             : {
      60       10167 :         if (len < 2 + 5)
      61           0 :                 return eid;
      62             : 
      63             : #ifdef CONFIG_TESTING_OPTIONS
      64       10167 :         if (hapd->conf->bss_load_test_set) {
      65          27 :                 *eid++ = WLAN_EID_BSS_LOAD;
      66          27 :                 *eid++ = 5;
      67          27 :                 os_memcpy(eid, hapd->conf->bss_load_test, 5);
      68          27 :                 eid += 5;
      69          27 :                 return eid;
      70             :         }
      71             : #endif /* CONFIG_TESTING_OPTIONS */
      72       10140 :         if (hapd->conf->bss_load_update_period) {
      73           8 :                 *eid++ = WLAN_EID_BSS_LOAD;
      74           8 :                 *eid++ = 5;
      75           8 :                 WPA_PUT_LE16(eid, hapd->num_sta);
      76           8 :                 eid += 2;
      77           8 :                 *eid++ = hapd->iface->channel_utilization;
      78           8 :                 WPA_PUT_LE16(eid, 0); /* no available admission capabity */
      79           8 :                 eid += 2;
      80             :         }
      81       10140 :         return eid;
      82             : }
      83             : 
      84             : 
      85       14651 : static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
      86             : {
      87       14651 :         u8 erp = 0;
      88             : 
      89       29290 :         if (hapd->iface->current_mode == NULL ||
      90       14639 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
      91         640 :                 return 0;
      92             : 
      93       14011 :         if (hapd->iface->olbc)
      94           2 :                 erp |= ERP_INFO_USE_PROTECTION;
      95       14011 :         if (hapd->iface->num_sta_non_erp > 0) {
      96           0 :                 erp |= ERP_INFO_NON_ERP_PRESENT |
      97             :                         ERP_INFO_USE_PROTECTION;
      98             :         }
      99       28022 :         if (hapd->iface->num_sta_no_short_preamble > 0 ||
     100       14011 :             hapd->iconf->preamble == LONG_PREAMBLE)
     101       14008 :                 erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
     102             : 
     103       14011 :         return erp;
     104             : }
     105             : 
     106             : 
     107       10167 : static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
     108             : {
     109       10167 :         *eid++ = WLAN_EID_DS_PARAMS;
     110       10167 :         *eid++ = 1;
     111       10167 :         *eid++ = hapd->iconf->channel;
     112       10167 :         return eid;
     113             : }
     114             : 
     115             : 
     116       10167 : static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
     117             : {
     118       20322 :         if (hapd->iface->current_mode == NULL ||
     119       10155 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
     120         882 :                 return eid;
     121             : 
     122             :         /* Set NonERP_present and use_protection bits if there
     123             :          * are any associated NonERP stations. */
     124             :         /* TODO: use_protection bit can be set to zero even if
     125             :          * there are NonERP stations present. This optimization
     126             :          * might be useful if NonERP stations are "quiet".
     127             :          * See 802.11g/D6 E-1 for recommended practice.
     128             :          * In addition, Non ERP present might be set, if AP detects Non ERP
     129             :          * operation on other APs. */
     130             : 
     131             :         /* Add ERP Information element */
     132        9285 :         *eid++ = WLAN_EID_ERP_INFO;
     133        9285 :         *eid++ = 1;
     134        9285 :         *eid++ = ieee802_11_erp_info(hapd);
     135             : 
     136        9285 :         return eid;
     137             : }
     138             : 
     139             : 
     140       10167 : static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
     141             : {
     142       10167 :         u8 *pos = eid;
     143       10167 :         u8 local_pwr_constraint = 0;
     144             :         int dfs;
     145             : 
     146       20322 :         if (hapd->iface->current_mode == NULL ||
     147       10155 :             hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
     148        9323 :                 return eid;
     149             : 
     150             :         /* Let host drivers add this IE if DFS support is offloaded */
     151         844 :         if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
     152           0 :                 return eid;
     153             : 
     154             :         /*
     155             :          * There is no DFS support and power constraint was not directly
     156             :          * requested by config option.
     157             :          */
     158        1660 :         if (!hapd->iconf->ieee80211h &&
     159         816 :             hapd->iconf->local_pwr_constraint == -1)
     160         812 :                 return eid;
     161             : 
     162             :         /* Check if DFS is required by regulatory. */
     163          32 :         dfs = hostapd_is_dfs_required(hapd->iface);
     164          32 :         if (dfs < 0) {
     165           0 :                 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
     166             :                            dfs);
     167           0 :                 dfs = 0;
     168             :         }
     169             : 
     170          32 :         if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1)
     171          16 :                 return eid;
     172             : 
     173             :         /*
     174             :          * ieee80211h (DFS) is enabled so Power Constraint element shall
     175             :          * be added when running on DFS channel whenever local_pwr_constraint
     176             :          * is configured or not. In order to meet regulations when TPC is not
     177             :          * implemented using a transmit power that is below the legal maximum
     178             :          * (including any mitigation factor) should help. In this case,
     179             :          * indicate 3 dB below maximum allowed transmit power.
     180             :          */
     181          16 :         if (hapd->iconf->local_pwr_constraint == -1)
     182          12 :                 local_pwr_constraint = 3;
     183             : 
     184             :         /*
     185             :          * A STA that is not an AP shall use a transmit power less than or
     186             :          * equal to the local maximum transmit power level for the channel.
     187             :          * The local maximum transmit power can be calculated from the formula:
     188             :          * local max TX pwr = max TX pwr - local pwr constraint
     189             :          * Where max TX pwr is maximum transmit power level specified for
     190             :          * channel in Country element and local pwr constraint is specified
     191             :          * for channel in this Power Constraint element.
     192             :          */
     193             : 
     194             :         /* Element ID */
     195          16 :         *pos++ = WLAN_EID_PWR_CONSTRAINT;
     196             :         /* Length */
     197          16 :         *pos++ = 1;
     198             :         /* Local Power Constraint */
     199          16 :         if (local_pwr_constraint)
     200          12 :                 *pos++ = local_pwr_constraint;
     201             :         else
     202           4 :                 *pos++ = hapd->iconf->local_pwr_constraint;
     203             : 
     204          16 :         return pos;
     205             : }
     206             : 
     207             : 
     208         157 : static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
     209             :                                     struct hostapd_channel_data *start,
     210             :                                     struct hostapd_channel_data *prev)
     211             : {
     212         157 :         if (end - pos < 3)
     213           0 :                 return pos;
     214             : 
     215             :         /* first channel number */
     216         157 :         *pos++ = start->chan;
     217             :         /* number of channels */
     218         157 :         *pos++ = (prev->chan - start->chan) / chan_spacing + 1;
     219             :         /* maximum transmit power level */
     220         157 :         *pos++ = start->max_tx_power;
     221             : 
     222         157 :         return pos;
     223             : }
     224             : 
     225             : 
     226       10167 : static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
     227             :                                 int max_len)
     228             : {
     229       10167 :         u8 *pos = eid;
     230       10167 :         u8 *end = eid + max_len;
     231             :         int i;
     232             :         struct hostapd_hw_modes *mode;
     233             :         struct hostapd_channel_data *start, *prev;
     234       10167 :         int chan_spacing = 1;
     235             : 
     236       10289 :         if (!hapd->iconf->ieee80211d || max_len < 6 ||
     237         122 :             hapd->iface->current_mode == NULL)
     238       10045 :                 return eid;
     239             : 
     240         122 :         *pos++ = WLAN_EID_COUNTRY;
     241         122 :         pos++; /* length will be set later */
     242         122 :         os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
     243         122 :         pos += 3;
     244             : 
     245         122 :         mode = hapd->iface->current_mode;
     246         122 :         if (mode->mode == HOSTAPD_MODE_IEEE80211A)
     247          53 :                 chan_spacing = 4;
     248             : 
     249         122 :         start = prev = NULL;
     250        2360 :         for (i = 0; i < mode->num_channels; i++) {
     251        2238 :                 struct hostapd_channel_data *chan = &mode->channels[i];
     252        2238 :                 if (chan->flag & HOSTAPD_CHAN_DISABLED)
     253         697 :                         continue;
     254        2960 :                 if (start && prev &&
     255        2803 :                     prev->chan + chan_spacing == chan->chan &&
     256        1384 :                     start->max_tx_power == chan->max_tx_power) {
     257        1384 :                         prev = chan;
     258        1384 :                         continue; /* can use same entry */
     259             :                 }
     260             : 
     261         157 :                 if (start && prev) {
     262          35 :                         pos = hostapd_eid_country_add(pos, end, chan_spacing,
     263             :                                                       start, prev);
     264          35 :                         start = NULL;
     265             :                 }
     266             : 
     267             :                 /* Start new group */
     268         157 :                 start = prev = chan;
     269             :         }
     270             : 
     271         122 :         if (start) {
     272         122 :                 pos = hostapd_eid_country_add(pos, end, chan_spacing,
     273             :                                               start, prev);
     274             :         }
     275             : 
     276         122 :         if ((pos - eid) & 1) {
     277          29 :                 if (end - pos < 1)
     278           0 :                         return eid;
     279          29 :                 *pos++ = 0; /* pad for 16-bit alignment */
     280             :         }
     281             : 
     282         122 :         eid[1] = (pos - eid) - 2;
     283             : 
     284         122 :         return pos;
     285             : }
     286             : 
     287             : 
     288       10167 : static u8 * hostapd_eid_wpa(struct hostapd_data *hapd, u8 *eid, size_t len)
     289             : {
     290             :         const u8 *ie;
     291             :         size_t ielen;
     292             : 
     293       10167 :         ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
     294       10167 :         if (ie == NULL || ielen > len)
     295        2921 :                 return eid;
     296             : 
     297        7246 :         os_memcpy(eid, ie, ielen);
     298        7246 :         return eid + ielen;
     299             : }
     300             : 
     301             : 
     302       10167 : static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
     303             : {
     304             : #ifdef CONFIG_TESTING_OPTIONS
     305       10167 :         if (hapd->iface->cs_oper_class && hapd->iconf->ecsa_ie_only)
     306           3 :                 return eid;
     307             : #endif /* CONFIG_TESTING_OPTIONS */
     308             : 
     309       10164 :         if (!hapd->cs_freq_params.channel)
     310       10136 :                 return eid;
     311             : 
     312          28 :         *eid++ = WLAN_EID_CHANNEL_SWITCH;
     313          28 :         *eid++ = 3;
     314          28 :         *eid++ = hapd->cs_block_tx;
     315          28 :         *eid++ = hapd->cs_freq_params.channel;
     316          28 :         *eid++ = hapd->cs_count;
     317             : 
     318          28 :         return eid;
     319             : }
     320             : 
     321             : 
     322       10167 : static u8 * hostapd_eid_ecsa(struct hostapd_data *hapd, u8 *eid)
     323             : {
     324       10167 :         if (!hapd->cs_freq_params.channel || !hapd->iface->cs_oper_class)
     325       10140 :                 return eid;
     326             : 
     327          27 :         *eid++ = WLAN_EID_EXT_CHANSWITCH_ANN;
     328          27 :         *eid++ = 4;
     329          27 :         *eid++ = hapd->cs_block_tx;
     330          27 :         *eid++ = hapd->iface->cs_oper_class;
     331          27 :         *eid++ = hapd->cs_freq_params.channel;
     332          27 :         *eid++ = hapd->cs_count;
     333             : 
     334          27 :         return eid;
     335             : }
     336             : 
     337             : 
     338       10167 : static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
     339             : {
     340             :         u8 op_class, channel;
     341             : 
     342       20322 :         if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) ||
     343       10155 :             !hapd->iface->freq)
     344          17 :                 return eid;
     345             : 
     346       20300 :         if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
     347       10150 :                                           hapd->iconf->secondary_channel,
     348       10150 :                                           hapd->iconf->vht_oper_chwidth,
     349             :                                           &op_class, &channel) ==
     350             :             NUM_HOSTAPD_MODES)
     351           9 :                 return eid;
     352             : 
     353       10141 :         *eid++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES;
     354       10141 :         *eid++ = 2;
     355             : 
     356             :         /* Current Operating Class */
     357       10141 :         *eid++ = op_class;
     358             : 
     359             :         /* TODO: Advertise all the supported operating classes */
     360       10141 :         *eid++ = 0;
     361             : 
     362       10141 :         return eid;
     363             : }
     364             : 
     365             : 
     366        4801 : static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
     367             :                                    const struct ieee80211_mgmt *req,
     368             :                                    int is_p2p, size_t *resp_len)
     369             : {
     370             :         struct ieee80211_mgmt *resp;
     371             :         u8 *pos, *epos, *csa_pos;
     372             :         size_t buflen;
     373             : 
     374             : #define MAX_PROBERESP_LEN 768
     375        4801 :         buflen = MAX_PROBERESP_LEN;
     376             : #ifdef CONFIG_WPS
     377        4801 :         if (hapd->wps_probe_resp_ie)
     378        1838 :                 buflen += wpabuf_len(hapd->wps_probe_resp_ie);
     379             : #endif /* CONFIG_WPS */
     380             : #ifdef CONFIG_P2P
     381         555 :         if (hapd->p2p_probe_resp_ie)
     382         512 :                 buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
     383             : #endif /* CONFIG_P2P */
     384             : #ifdef CONFIG_FST
     385        4801 :         if (hapd->iface->fst_ies)
     386         264 :                 buflen += wpabuf_len(hapd->iface->fst_ies);
     387             : #endif /* CONFIG_FST */
     388        4801 :         if (hapd->conf->vendor_elements)
     389          21 :                 buflen += wpabuf_len(hapd->conf->vendor_elements);
     390        4801 :         if (hapd->conf->vendor_vht) {
     391           2 :                 buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
     392             :                         2 + sizeof(struct ieee80211_vht_operation);
     393             :         }
     394             : 
     395        4801 :         buflen += hostapd_mbo_ie_len(hapd);
     396             : 
     397        4801 :         resp = os_zalloc(buflen);
     398        4801 :         if (resp == NULL)
     399           0 :                 return NULL;
     400             : 
     401        4801 :         epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
     402             : 
     403        4801 :         resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
     404             :                                            WLAN_FC_STYPE_PROBE_RESP);
     405        4801 :         if (req)
     406        4801 :                 os_memcpy(resp->da, req->sa, ETH_ALEN);
     407        4801 :         os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
     408             : 
     409        4801 :         os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
     410        4801 :         resp->u.probe_resp.beacon_int =
     411        4801 :                 host_to_le16(hapd->iconf->beacon_int);
     412             : 
     413             :         /* hardware or low-level driver will setup seq_ctrl and timestamp */
     414        4801 :         resp->u.probe_resp.capab_info =
     415        4801 :                 host_to_le16(hostapd_own_capab_info(hapd));
     416             : 
     417        4801 :         pos = resp->u.probe_resp.variable;
     418        4801 :         *pos++ = WLAN_EID_SSID;
     419        4801 :         *pos++ = hapd->conf->ssid.ssid_len;
     420        4801 :         os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
     421        4801 :         pos += hapd->conf->ssid.ssid_len;
     422             : 
     423             :         /* Supported rates */
     424        4801 :         pos = hostapd_eid_supp_rates(hapd, pos);
     425             : 
     426             :         /* DS Params */
     427        4801 :         pos = hostapd_eid_ds_params(hapd, pos);
     428             : 
     429        4801 :         pos = hostapd_eid_country(hapd, pos, epos - pos);
     430             : 
     431             :         /* Power Constraint element */
     432        4801 :         pos = hostapd_eid_pwr_constraint(hapd, pos);
     433             : 
     434             :         /* CSA IE */
     435        4801 :         csa_pos = hostapd_eid_csa(hapd, pos);
     436        4801 :         if (csa_pos != pos)
     437           0 :                 hapd->cs_c_off_proberesp = csa_pos - (u8 *) resp - 1;
     438        4801 :         pos = csa_pos;
     439             : 
     440             :         /* ERP Information element */
     441        4801 :         pos = hostapd_eid_erp_info(hapd, pos);
     442             : 
     443             :         /* Extended supported rates */
     444        4801 :         pos = hostapd_eid_ext_supp_rates(hapd, pos);
     445             : 
     446             :         /* RSN, MDIE, WPA */
     447        4801 :         pos = hostapd_eid_wpa(hapd, pos, epos - pos);
     448             : 
     449        4801 :         pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
     450             : 
     451        4801 :         pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
     452             : 
     453             :         /* eCSA IE */
     454        4801 :         csa_pos = hostapd_eid_ecsa(hapd, pos);
     455        4801 :         if (csa_pos != pos)
     456           0 :                 hapd->cs_c_off_ecsa_proberesp = csa_pos - (u8 *) resp - 1;
     457        4801 :         pos = csa_pos;
     458             : 
     459        4801 :         pos = hostapd_eid_supported_op_classes(hapd, pos);
     460             : 
     461             : #ifdef CONFIG_IEEE80211N
     462             :         /* Secondary Channel Offset element */
     463             :         /* TODO: The standard doesn't specify a position for this element. */
     464        4801 :         pos = hostapd_eid_secondary_channel(hapd, pos);
     465             : 
     466        4801 :         pos = hostapd_eid_ht_capabilities(hapd, pos);
     467        4801 :         pos = hostapd_eid_ht_operation(hapd, pos);
     468             : #endif /* CONFIG_IEEE80211N */
     469             : 
     470        4801 :         pos = hostapd_eid_ext_capab(hapd, pos);
     471             : 
     472        4801 :         pos = hostapd_eid_time_adv(hapd, pos);
     473        4801 :         pos = hostapd_eid_time_zone(hapd, pos);
     474             : 
     475        4801 :         pos = hostapd_eid_interworking(hapd, pos);
     476        4801 :         pos = hostapd_eid_adv_proto(hapd, pos);
     477        4801 :         pos = hostapd_eid_roaming_consortium(hapd, pos);
     478             : 
     479             : #ifdef CONFIG_FST
     480        4801 :         if (hapd->iface->fst_ies) {
     481         264 :                 os_memcpy(pos, wpabuf_head(hapd->iface->fst_ies),
     482             :                           wpabuf_len(hapd->iface->fst_ies));
     483         264 :                 pos += wpabuf_len(hapd->iface->fst_ies);
     484             :         }
     485             : #endif /* CONFIG_FST */
     486             : 
     487             : #ifdef CONFIG_IEEE80211AC
     488        4801 :         if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
     489          34 :                 pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
     490          34 :                 pos = hostapd_eid_vht_operation(hapd, pos);
     491          34 :                 pos = hostapd_eid_txpower_envelope(hapd, pos);
     492          34 :                 pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
     493             :         }
     494        4801 :         if (hapd->conf->vendor_vht)
     495           2 :                 pos = hostapd_eid_vendor_vht(hapd, pos);
     496             : #endif /* CONFIG_IEEE80211AC */
     497             : 
     498             :         /* Wi-Fi Alliance WMM */
     499        4801 :         pos = hostapd_eid_wmm(hapd, pos);
     500             : 
     501             : #ifdef CONFIG_WPS
     502        4801 :         if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
     503        1838 :                 os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
     504             :                           wpabuf_len(hapd->wps_probe_resp_ie));
     505        1838 :                 pos += wpabuf_len(hapd->wps_probe_resp_ie);
     506             :         }
     507             : #endif /* CONFIG_WPS */
     508             : 
     509             : #ifdef CONFIG_P2P
     510        1056 :         if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p &&
     511         501 :             hapd->p2p_probe_resp_ie) {
     512         501 :                 os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
     513             :                           wpabuf_len(hapd->p2p_probe_resp_ie));
     514         501 :                 pos += wpabuf_len(hapd->p2p_probe_resp_ie);
     515             :         }
     516             : #endif /* CONFIG_P2P */
     517             : #ifdef CONFIG_P2P_MANAGER
     518        4246 :         if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
     519             :             P2P_MANAGE)
     520           6 :                 pos = hostapd_eid_p2p_manage(hapd, pos);
     521             : #endif /* CONFIG_P2P_MANAGER */
     522             : 
     523             : #ifdef CONFIG_HS20
     524        4801 :         pos = hostapd_eid_hs20_indication(hapd, pos);
     525        4801 :         pos = hostapd_eid_osen(hapd, pos);
     526             : #endif /* CONFIG_HS20 */
     527             : 
     528        4801 :         pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
     529             : 
     530        4801 :         if (hapd->conf->vendor_elements) {
     531          21 :                 os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
     532             :                           wpabuf_len(hapd->conf->vendor_elements));
     533          21 :                 pos += wpabuf_len(hapd->conf->vendor_elements);
     534             :         }
     535             : 
     536        4801 :         *resp_len = pos - (u8 *) resp;
     537        4801 :         return (u8 *) resp;
     538             : }
     539             : 
     540             : 
     541             : enum ssid_match_result {
     542             :         NO_SSID_MATCH,
     543             :         EXACT_SSID_MATCH,
     544             :         WILDCARD_SSID_MATCH
     545             : };
     546             : 
     547        4946 : static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
     548             :                                          const u8 *ssid, size_t ssid_len,
     549             :                                          const u8 *ssid_list,
     550             :                                          size_t ssid_list_len)
     551             : {
     552             :         const u8 *pos, *end;
     553        4946 :         int wildcard = 0;
     554             : 
     555        4946 :         if (ssid_len == 0)
     556        4232 :                 wildcard = 1;
     557        5552 :         if (ssid_len == hapd->conf->ssid.ssid_len &&
     558         606 :             os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
     559         588 :                 return EXACT_SSID_MATCH;
     560             : 
     561        4358 :         if (ssid_list == NULL)
     562        4358 :                 return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
     563             : 
     564           0 :         pos = ssid_list;
     565           0 :         end = ssid_list + ssid_list_len;
     566           0 :         while (end - pos >= 1) {
     567           0 :                 if (2 + pos[1] > end - pos)
     568           0 :                         break;
     569           0 :                 if (pos[1] == 0)
     570           0 :                         wildcard = 1;
     571           0 :                 if (pos[1] == hapd->conf->ssid.ssid_len &&
     572           0 :                     os_memcmp(pos + 2, hapd->conf->ssid.ssid, pos[1]) == 0)
     573           0 :                         return EXACT_SSID_MATCH;
     574           0 :                 pos += 2 + pos[1];
     575             :         }
     576             : 
     577           0 :         return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
     578             : }
     579             : 
     580             : 
     581          15 : void sta_track_expire(struct hostapd_iface *iface, int force)
     582             : {
     583             :         struct os_reltime now;
     584             :         struct hostapd_sta_info *info;
     585             : 
     586          15 :         if (!iface->num_sta_seen)
     587          15 :                 return;
     588             : 
     589          15 :         os_get_reltime(&now);
     590          42 :         while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
     591             :                                      list))) {
     592          42 :                 if (!force &&
     593          16 :                     !os_reltime_expired(&now, &info->last_seen,
     594          16 :                                         iface->conf->track_sta_max_age))
     595          14 :                         break;
     596          12 :                 force = 0;
     597             : 
     598          84 :                 wpa_printf(MSG_MSGDUMP, "%s: Expire STA tracking entry for "
     599          12 :                            MACSTR, iface->bss[0]->conf->iface,
     600          72 :                            MAC2STR(info->addr));
     601          12 :                 dl_list_del(&info->list);
     602          12 :                 iface->num_sta_seen--;
     603          12 :                 sta_track_del(info);
     604             :         }
     605             : }
     606             : 
     607             : 
     608        7757 : static struct hostapd_sta_info * sta_track_get(struct hostapd_iface *iface,
     609             :                                                const u8 *addr)
     610             : {
     611             :         struct hostapd_sta_info *info;
     612             : 
     613        7812 :         dl_list_for_each(info, &iface->sta_seen, struct hostapd_sta_info, list)
     614         118 :                 if (os_memcmp(addr, info->addr, ETH_ALEN) == 0)
     615          63 :                         return info;
     616             : 
     617        7694 :         return NULL;
     618             : }
     619             : 
     620             : 
     621          52 : void sta_track_add(struct hostapd_iface *iface, const u8 *addr)
     622             : {
     623             :         struct hostapd_sta_info *info;
     624             : 
     625          52 :         info = sta_track_get(iface, addr);
     626          52 :         if (info) {
     627             :                 /* Move the most recent entry to the end of the list */
     628          29 :                 dl_list_del(&info->list);
     629          29 :                 dl_list_add_tail(&iface->sta_seen, &info->list);
     630          29 :                 os_get_reltime(&info->last_seen);
     631          29 :                 return;
     632             :         }
     633             : 
     634             :         /* Add a new entry */
     635          23 :         info = os_zalloc(sizeof(*info));
     636          23 :         if (info == NULL)
     637           0 :                 return;
     638          23 :         os_memcpy(info->addr, addr, ETH_ALEN);
     639          23 :         os_get_reltime(&info->last_seen);
     640             : 
     641          23 :         if (iface->num_sta_seen >= iface->conf->track_sta_max_num) {
     642             :                 /* Expire oldest entry to make room for a new one */
     643          10 :                 sta_track_expire(iface, 1);
     644             :         }
     645             : 
     646         161 :         wpa_printf(MSG_MSGDUMP, "%s: Add STA tracking entry for "
     647         161 :                    MACSTR, iface->bss[0]->conf->iface, MAC2STR(addr));
     648          23 :         dl_list_add_tail(&iface->sta_seen, &info->list);
     649          23 :         iface->num_sta_seen++;
     650             : }
     651             : 
     652             : 
     653             : struct hostapd_data *
     654          10 : sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
     655             :                   const char *ifname)
     656             : {
     657          10 :         struct hapd_interfaces *interfaces = iface->interfaces;
     658             :         size_t i, j;
     659             : 
     660          22 :         for (i = 0; i < interfaces->count; i++) {
     661          18 :                 struct hostapd_data *hapd = NULL;
     662             : 
     663          18 :                 iface = interfaces->iface[i];
     664          26 :                 for (j = 0; j < iface->num_bss; j++) {
     665          18 :                         hapd = iface->bss[j];
     666          18 :                         if (os_strcmp(ifname, hapd->conf->iface) == 0)
     667          10 :                                 break;
     668           8 :                         hapd = NULL;
     669             :                 }
     670             : 
     671          18 :                 if (hapd && sta_track_get(iface, addr))
     672           6 :                         return hapd;
     673             :         }
     674             : 
     675           4 :         return NULL;
     676             : }
     677             : 
     678             : 
     679             : #ifdef CONFIG_TAXONOMY
     680        3800 : void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
     681             :                                    struct wpabuf **probe_ie_taxonomy)
     682             : {
     683             :         struct hostapd_sta_info *info;
     684             : 
     685        3800 :         info = sta_track_get(iface, addr);
     686        3800 :         if (!info)
     687        7593 :                 return;
     688             : 
     689           7 :         wpabuf_free(*probe_ie_taxonomy);
     690           7 :         *probe_ie_taxonomy = info->probe_ie_taxonomy;
     691           7 :         info->probe_ie_taxonomy = NULL;
     692             : }
     693             : #endif /* CONFIG_TAXONOMY */
     694             : 
     695             : 
     696        4979 : void handle_probe_req(struct hostapd_data *hapd,
     697             :                       const struct ieee80211_mgmt *mgmt, size_t len,
     698             :                       int ssi_signal)
     699             : {
     700             :         u8 *resp;
     701             :         struct ieee802_11_elems elems;
     702             :         const u8 *ie;
     703             :         size_t ie_len;
     704             :         size_t i, resp_len;
     705             :         int noack;
     706             :         enum ssid_match_result res;
     707             :         int ret;
     708             :         u16 csa_offs[2];
     709             :         size_t csa_offs_len;
     710             : 
     711        4979 :         if (len < IEEE80211_HDRLEN)
     712         178 :                 return;
     713        4979 :         ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
     714        4979 :         if (hapd->iconf->track_sta_max_num)
     715          29 :                 sta_track_add(hapd->iface, mgmt->sa);
     716        4979 :         ie_len = len - IEEE80211_HDRLEN;
     717             : 
     718        7396 :         for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
     719        4840 :                 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
     720        2420 :                                             mgmt->sa, mgmt->da, mgmt->bssid,
     721             :                                             ie, ie_len, ssi_signal) > 0)
     722           3 :                         return;
     723             : 
     724        4976 :         if (!hapd->iconf->send_probe_response)
     725           0 :                 return;
     726             : 
     727        4976 :         if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
     728           0 :                 wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
     729           0 :                            MAC2STR(mgmt->sa));
     730           0 :                 return;
     731             :         }
     732             : 
     733        4976 :         if ((!elems.ssid || !elems.supp_rates)) {
     734           0 :                 wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
     735             :                            "without SSID or supported rates element",
     736           0 :                            MAC2STR(mgmt->sa));
     737           0 :                 return;
     738             :         }
     739             : 
     740             :         /*
     741             :          * No need to reply if the Probe Request frame was sent on an adjacent
     742             :          * channel. IEEE Std 802.11-2012 describes this as a requirement for an
     743             :          * AP with dot11RadioMeasurementActivated set to true, but strictly
     744             :          * speaking does not allow such ignoring of Probe Request frames if
     745             :          * dot11RadioMeasurementActivated is false. Anyway, this can help reduce
     746             :          * number of unnecessary Probe Response frames for cases where the STA
     747             :          * is less likely to see them (Probe Request frame sent on a
     748             :          * neighboring, but partially overlapping, channel).
     749             :          */
     750        9459 :         if (elems.ds_params &&
     751        8966 :             hapd->iface->current_mode &&
     752        4487 :             (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G ||
     753        4487 :              hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B) &&
     754        4483 :             hapd->iconf->channel != elems.ds_params[0]) {
     755           6 :                 wpa_printf(MSG_DEBUG,
     756             :                            "Ignore Probe Request due to DS Params mismatch: chan=%u != ds.chan=%u",
     757           6 :                            hapd->iconf->channel, elems.ds_params[0]);
     758           3 :                 return;
     759             :         }
     760             : 
     761             : #ifdef CONFIG_P2P
     762         561 :         if (hapd->p2p && hapd->p2p_group && elems.wps_ie) {
     763             :                 struct wpabuf *wps;
     764         509 :                 wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
     765         509 :                 if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
     766           2 :                         wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
     767             :                                    "due to mismatch with Requested Device "
     768             :                                    "Type");
     769           2 :                         wpabuf_free(wps);
     770           2 :                         return;
     771             :                 }
     772         507 :                 wpabuf_free(wps);
     773             :         }
     774             : 
     775         559 :         if (hapd->p2p && hapd->p2p_group && elems.p2p) {
     776             :                 struct wpabuf *p2p;
     777         505 :                 p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
     778         505 :                 if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
     779           3 :                         wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
     780             :                                    "due to mismatch with Device ID");
     781           3 :                         wpabuf_free(p2p);
     782           3 :                         return;
     783             :                 }
     784         502 :                 wpabuf_free(p2p);
     785             :         }
     786             : #endif /* CONFIG_P2P */
     787             : 
     788        4990 :         if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
     789          22 :             elems.ssid_list_len == 0) {
     790         132 :                 wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
     791         132 :                            "broadcast SSID ignored", MAC2STR(mgmt->sa));
     792          22 :                 return;
     793             :         }
     794             : 
     795             : #ifdef CONFIG_P2P
     796        1069 :         if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
     797         667 :             elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
     798         154 :             os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
     799             :                       P2P_WILDCARD_SSID_LEN) == 0) {
     800             :                 /* Process P2P Wildcard SSID like Wildcard SSID */
     801         154 :                 elems.ssid_len = 0;
     802             :         }
     803             : #endif /* CONFIG_P2P */
     804             : 
     805             : #ifdef CONFIG_TAXONOMY
     806             :         {
     807             :                 struct sta_info *sta;
     808             :                 struct hostapd_sta_info *info;
     809             : 
     810        4390 :                 if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
     811         495 :                         taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
     812        3895 :                 } else if ((info = sta_track_get(hapd->iface,
     813        3895 :                                                  mgmt->sa)) != NULL) {
     814          21 :                         taxonomy_hostapd_sta_info_probe_req(hapd, info,
     815             :                                                             ie, ie_len);
     816             :                 }
     817             :         }
     818             : #endif /* CONFIG_TAXONOMY */
     819             : 
     820        4946 :         res = ssid_match(hapd, elems.ssid, elems.ssid_len,
     821        4946 :                          elems.ssid_list, elems.ssid_list_len);
     822        4946 :         if (res == NO_SSID_MATCH) {
     823         126 :                 if (!(mgmt->da[0] & 0x01)) {
     824           0 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     825             :                                    " for foreign SSID '%s' (DA " MACSTR ")%s",
     826           0 :                                    MAC2STR(mgmt->sa),
     827           0 :                                    wpa_ssid_txt(elems.ssid, elems.ssid_len),
     828           0 :                                    MAC2STR(mgmt->da),
     829           0 :                                    elems.ssid_list ? " (SSID list)" : "");
     830             :                 }
     831         126 :                 return;
     832             :         }
     833             : 
     834             : #ifdef CONFIG_INTERWORKING
     835        5339 :         if (hapd->conf->interworking &&
     836         982 :             elems.interworking && elems.interworking_len >= 1) {
     837         463 :                 u8 ant = elems.interworking[0] & 0x0f;
     838         473 :                 if (ant != INTERWORKING_ANT_WILDCARD &&
     839          10 :                     ant != hapd->conf->access_network_type) {
     840          35 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     841             :                                    " for mismatching ANT %u ignored",
     842          30 :                                    MAC2STR(mgmt->sa), ant);
     843           5 :                         return;
     844             :                 }
     845             :         }
     846             : 
     847        5273 :         if (hapd->conf->interworking && elems.interworking &&
     848         911 :             (elems.interworking_len == 7 || elems.interworking_len == 9)) {
     849             :                 const u8 *hessid;
     850           5 :                 if (elems.interworking_len == 7)
     851           5 :                         hessid = elems.interworking + 1;
     852             :                 else
     853           0 :                         hessid = elems.interworking + 1 + 2;
     854          10 :                 if (!is_broadcast_ether_addr(hessid) &&
     855           5 :                     os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
     856          36 :                         wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
     857             :                                    " for mismatching HESSID " MACSTR
     858             :                                    " ignored",
     859          36 :                                    MAC2STR(mgmt->sa), MAC2STR(hessid));
     860           3 :                         return;
     861             :                 }
     862             :         }
     863             : #endif /* CONFIG_INTERWORKING */
     864             : 
     865             : #ifdef CONFIG_P2P
     866        1067 :         if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
     867         512 :             supp_rates_11b_only(&elems)) {
     868             :                 /* Indicates support for 11b rates only */
     869           0 :                 wpa_printf(MSG_EXCESSIVE, "P2P: Ignore Probe Request from "
     870             :                            MACSTR " with only 802.11b rates",
     871           0 :                            MAC2STR(mgmt->sa));
     872           0 :                 return;
     873             :         }
     874             : #endif /* CONFIG_P2P */
     875             : 
     876             :         /* TODO: verify that supp_rates contains at least one matching rate
     877             :          * with AP configuration */
     878             : 
     879        4818 :         if (hapd->conf->no_probe_resp_if_seen_on &&
     880          12 :             is_multicast_ether_addr(mgmt->da) &&
     881          12 :             is_multicast_ether_addr(mgmt->bssid) &&
     882           6 :             sta_track_seen_on(hapd->iface, mgmt->sa,
     883           6 :                               hapd->conf->no_probe_resp_if_seen_on)) {
     884          24 :                 wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
     885             :                            " since STA has been seen on %s",
     886          21 :                            hapd->conf->iface, MAC2STR(mgmt->sa),
     887           3 :                            hapd->conf->no_probe_resp_if_seen_on);
     888           3 :                 return;
     889             :         }
     890             : 
     891        4814 :         if (hapd->conf->no_probe_resp_if_max_sta &&
     892           9 :             is_multicast_ether_addr(mgmt->da) &&
     893           8 :             is_multicast_ether_addr(mgmt->bssid) &&
     894           7 :             hapd->num_sta >= hapd->conf->max_num_sta &&
     895           3 :             !ap_get_sta(hapd, mgmt->sa)) {
     896          14 :                 wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
     897             :                            " since no room for additional STA",
     898          14 :                            hapd->conf->iface, MAC2STR(mgmt->sa));
     899           2 :                 return;
     900             :         }
     901             : 
     902             : #ifdef CONFIG_TESTING_OPTIONS
     903        4816 :         if (hapd->iconf->ignore_probe_probability > 0.0 &&
     904           9 :             drand48() < hapd->iconf->ignore_probe_probability) {
     905          36 :                 wpa_printf(MSG_INFO,
     906             :                            "TESTING: ignoring probe request from " MACSTR,
     907          36 :                            MAC2STR(mgmt->sa));
     908           6 :                 return;
     909             :         }
     910             : #endif /* CONFIG_TESTING_OPTIONS */
     911             : 
     912        4801 :         resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
     913             :                                       &resp_len);
     914        4801 :         if (resp == NULL)
     915           0 :                 return;
     916             : 
     917             :         /*
     918             :          * If this is a broadcast probe request, apply no ack policy to avoid
     919             :          * excessive retries.
     920             :          */
     921        9014 :         noack = !!(res == WILDCARD_SSID_MATCH &&
     922        4213 :                    is_broadcast_ether_addr(mgmt->da));
     923             : 
     924        4801 :         csa_offs_len = 0;
     925        4801 :         if (hapd->csa_in_progress) {
     926           0 :                 if (hapd->cs_c_off_proberesp)
     927           0 :                         csa_offs[csa_offs_len++] =
     928           0 :                                 hapd->cs_c_off_proberesp;
     929             : 
     930           0 :                 if (hapd->cs_c_off_ecsa_proberesp)
     931           0 :                         csa_offs[csa_offs_len++] =
     932           0 :                                 hapd->cs_c_off_ecsa_proberesp;
     933             :         }
     934             : 
     935        4801 :         ret = hostapd_drv_send_mlme_csa(hapd, resp, resp_len, noack,
     936             :                                         csa_offs_len ? csa_offs : NULL,
     937             :                                         csa_offs_len);
     938             : 
     939        4801 :         if (ret < 0)
     940           5 :                 wpa_printf(MSG_INFO, "handle_probe_req: send failed");
     941             : 
     942        4801 :         os_free(resp);
     943             : 
     944       33607 :         wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
     945       28806 :                    "SSID", MAC2STR(mgmt->sa),
     946        4801 :                    elems.ssid_len == 0 ? "broadcast" : "our");
     947             : }
     948             : 
     949             : 
     950        5366 : static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
     951             :                                         size_t *resp_len)
     952             : {
     953             :         /* check probe response offloading caps and print warnings */
     954        5366 :         if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD))
     955        5366 :                 return NULL;
     956             : 
     957             : #ifdef CONFIG_WPS
     958           0 :         if (hapd->conf->wps_state && hapd->wps_probe_resp_ie &&
     959           0 :             (!(hapd->iface->probe_resp_offloads &
     960             :                (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS |
     961             :                 WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2))))
     962           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload WPS "
     963             :                            "Probe Response while not supporting this");
     964             : #endif /* CONFIG_WPS */
     965             : 
     966             : #ifdef CONFIG_P2P
     967           0 :         if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie &&
     968           0 :             !(hapd->iface->probe_resp_offloads &
     969             :               WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P))
     970           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload P2P "
     971             :                            "Probe Response while not supporting this");
     972             : #endif  /* CONFIG_P2P */
     973             : 
     974           0 :         if (hapd->conf->interworking &&
     975           0 :             !(hapd->iface->probe_resp_offloads &
     976             :               WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING))
     977           0 :                 wpa_printf(MSG_WARNING, "Device is trying to offload "
     978             :                            "Interworking Probe Response while not supporting "
     979             :                            "this");
     980             : 
     981             :         /* Generate a Probe Response template for the non-P2P case */
     982           0 :         return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len);
     983             : }
     984             : 
     985             : #endif /* NEED_AP_MLME */
     986             : 
     987             : 
     988          23 : void sta_track_del(struct hostapd_sta_info *info)
     989             : {
     990             : #ifdef CONFIG_TAXONOMY
     991          23 :         wpabuf_free(info->probe_ie_taxonomy);
     992          23 :         info->probe_ie_taxonomy = NULL;
     993             : #endif /* CONFIG_TAXONOMY */
     994          23 :         os_free(info);
     995          23 : }
     996             : 
     997             : 
     998        5368 : int ieee802_11_build_ap_params(struct hostapd_data *hapd,
     999             :                                struct wpa_driver_ap_params *params)
    1000             : {
    1001        5368 :         struct ieee80211_mgmt *head = NULL;
    1002        5368 :         u8 *tail = NULL;
    1003        5368 :         size_t head_len = 0, tail_len = 0;
    1004        5368 :         u8 *resp = NULL;
    1005        5368 :         size_t resp_len = 0;
    1006             : #ifdef NEED_AP_MLME
    1007             :         u16 capab_info;
    1008             :         u8 *pos, *tailpos, *csa_pos;
    1009             : 
    1010             : #define BEACON_HEAD_BUF_SIZE 256
    1011             : #define BEACON_TAIL_BUF_SIZE 512
    1012        5368 :         head = os_zalloc(BEACON_HEAD_BUF_SIZE);
    1013        5368 :         tail_len = BEACON_TAIL_BUF_SIZE;
    1014             : #ifdef CONFIG_WPS
    1015        5368 :         if (hapd->conf->wps_state && hapd->wps_beacon_ie)
    1016        2878 :                 tail_len += wpabuf_len(hapd->wps_beacon_ie);
    1017             : #endif /* CONFIG_WPS */
    1018             : #ifdef CONFIG_P2P
    1019        2160 :         if (hapd->p2p_beacon_ie)
    1020        2106 :                 tail_len += wpabuf_len(hapd->p2p_beacon_ie);
    1021             : #endif /* CONFIG_P2P */
    1022             : #ifdef CONFIG_FST
    1023        5368 :         if (hapd->iface->fst_ies)
    1024         266 :                 tail_len += wpabuf_len(hapd->iface->fst_ies);
    1025             : #endif /* CONFIG_FST */
    1026        5368 :         if (hapd->conf->vendor_elements)
    1027          23 :                 tail_len += wpabuf_len(hapd->conf->vendor_elements);
    1028             : 
    1029             : #ifdef CONFIG_IEEE80211AC
    1030        5368 :         if (hapd->conf->vendor_vht) {
    1031           1 :                 tail_len += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
    1032             :                         2 + sizeof(struct ieee80211_vht_operation);
    1033             :         }
    1034             : #endif /* CONFIG_IEEE80211AC */
    1035             : 
    1036        5368 :         tail_len += hostapd_mbo_ie_len(hapd);
    1037             : 
    1038        5368 :         tailpos = tail = os_malloc(tail_len);
    1039        5368 :         if (head == NULL || tail == NULL) {
    1040           2 :                 wpa_printf(MSG_ERROR, "Failed to set beacon data");
    1041           2 :                 os_free(head);
    1042           2 :                 os_free(tail);
    1043           2 :                 return -1;
    1044             :         }
    1045             : 
    1046        5366 :         head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
    1047             :                                            WLAN_FC_STYPE_BEACON);
    1048        5366 :         head->duration = host_to_le16(0);
    1049        5366 :         os_memset(head->da, 0xff, ETH_ALEN);
    1050             : 
    1051        5366 :         os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
    1052        5366 :         os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
    1053        5366 :         head->u.beacon.beacon_int =
    1054        5366 :                 host_to_le16(hapd->iconf->beacon_int);
    1055             : 
    1056             :         /* hardware or low-level driver will setup seq_ctrl and timestamp */
    1057        5366 :         capab_info = hostapd_own_capab_info(hapd);
    1058        5366 :         head->u.beacon.capab_info = host_to_le16(capab_info);
    1059        5366 :         pos = &head->u.beacon.variable[0];
    1060             : 
    1061             :         /* SSID */
    1062        5366 :         *pos++ = WLAN_EID_SSID;
    1063        5366 :         if (hapd->conf->ignore_broadcast_ssid == 2) {
    1064             :                 /* clear the data, but keep the correct length of the SSID */
    1065           1 :                 *pos++ = hapd->conf->ssid.ssid_len;
    1066           1 :                 os_memset(pos, 0, hapd->conf->ssid.ssid_len);
    1067           1 :                 pos += hapd->conf->ssid.ssid_len;
    1068        5365 :         } else if (hapd->conf->ignore_broadcast_ssid) {
    1069           9 :                 *pos++ = 0; /* empty SSID */
    1070             :         } else {
    1071        5356 :                 *pos++ = hapd->conf->ssid.ssid_len;
    1072        5356 :                 os_memcpy(pos, hapd->conf->ssid.ssid,
    1073             :                           hapd->conf->ssid.ssid_len);
    1074        5356 :                 pos += hapd->conf->ssid.ssid_len;
    1075             :         }
    1076             : 
    1077             :         /* Supported rates */
    1078        5366 :         pos = hostapd_eid_supp_rates(hapd, pos);
    1079             : 
    1080             :         /* DS Params */
    1081        5366 :         pos = hostapd_eid_ds_params(hapd, pos);
    1082             : 
    1083        5366 :         head_len = pos - (u8 *) head;
    1084             : 
    1085        5366 :         tailpos = hostapd_eid_country(hapd, tailpos,
    1086        5366 :                                       tail + BEACON_TAIL_BUF_SIZE - tailpos);
    1087             : 
    1088             :         /* Power Constraint element */
    1089        5366 :         tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
    1090             : 
    1091             :         /* CSA IE */
    1092        5366 :         csa_pos = hostapd_eid_csa(hapd, tailpos);
    1093        5366 :         if (csa_pos != tailpos)
    1094          28 :                 hapd->cs_c_off_beacon = csa_pos - tail - 1;
    1095        5366 :         tailpos = csa_pos;
    1096             : 
    1097             :         /* ERP Information element */
    1098        5366 :         tailpos = hostapd_eid_erp_info(hapd, tailpos);
    1099             : 
    1100             :         /* Extended supported rates */
    1101        5366 :         tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
    1102             : 
    1103             :         /* RSN, MDIE, WPA */
    1104        5366 :         tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
    1105             :                                   tailpos);
    1106             : 
    1107        5366 :         tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
    1108        5366 :                                                tail + BEACON_TAIL_BUF_SIZE -
    1109             :                                                tailpos);
    1110             : 
    1111        5366 :         tailpos = hostapd_eid_bss_load(hapd, tailpos,
    1112        5366 :                                        tail + BEACON_TAIL_BUF_SIZE - tailpos);
    1113             : 
    1114             :         /* eCSA IE */
    1115        5366 :         csa_pos = hostapd_eid_ecsa(hapd, tailpos);
    1116        5366 :         if (csa_pos != tailpos)
    1117          27 :                 hapd->cs_c_off_ecsa_beacon = csa_pos - tail - 1;
    1118        5366 :         tailpos = csa_pos;
    1119             : 
    1120        5366 :         tailpos = hostapd_eid_supported_op_classes(hapd, tailpos);
    1121             : 
    1122             : #ifdef CONFIG_IEEE80211N
    1123             :         /* Secondary Channel Offset element */
    1124             :         /* TODO: The standard doesn't specify a position for this element. */
    1125        5366 :         tailpos = hostapd_eid_secondary_channel(hapd, tailpos);
    1126             : 
    1127        5366 :         tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
    1128        5366 :         tailpos = hostapd_eid_ht_operation(hapd, tailpos);
    1129             : #endif /* CONFIG_IEEE80211N */
    1130             : 
    1131        5366 :         tailpos = hostapd_eid_ext_capab(hapd, tailpos);
    1132             : 
    1133             :         /*
    1134             :          * TODO: Time Advertisement element should only be included in some
    1135             :          * DTIM Beacon frames.
    1136             :          */
    1137        5366 :         tailpos = hostapd_eid_time_adv(hapd, tailpos);
    1138             : 
    1139        5366 :         tailpos = hostapd_eid_interworking(hapd, tailpos);
    1140        5366 :         tailpos = hostapd_eid_adv_proto(hapd, tailpos);
    1141        5366 :         tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
    1142             : 
    1143             : #ifdef CONFIG_FST
    1144        5366 :         if (hapd->iface->fst_ies) {
    1145         266 :                 os_memcpy(tailpos, wpabuf_head(hapd->iface->fst_ies),
    1146             :                           wpabuf_len(hapd->iface->fst_ies));
    1147         266 :                 tailpos += wpabuf_len(hapd->iface->fst_ies);
    1148             :         }
    1149             : #endif /* CONFIG_FST */
    1150             : 
    1151             : #ifdef CONFIG_IEEE80211AC
    1152        5366 :         if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) {
    1153          53 :                 tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
    1154          53 :                 tailpos = hostapd_eid_vht_operation(hapd, tailpos);
    1155          53 :                 tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
    1156          53 :                 tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
    1157             :         }
    1158        5366 :         if (hapd->conf->vendor_vht)
    1159           1 :                 tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
    1160             : #endif /* CONFIG_IEEE80211AC */
    1161             : 
    1162             :         /* Wi-Fi Alliance WMM */
    1163        5366 :         tailpos = hostapd_eid_wmm(hapd, tailpos);
    1164             : 
    1165             : #ifdef CONFIG_WPS
    1166        5366 :         if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
    1167        2878 :                 os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
    1168             :                           wpabuf_len(hapd->wps_beacon_ie));
    1169        2878 :                 tailpos += wpabuf_len(hapd->wps_beacon_ie);
    1170             :         }
    1171             : #endif /* CONFIG_WPS */
    1172             : 
    1173             : #ifdef CONFIG_P2P
    1174        2160 :         if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
    1175        2106 :                 os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
    1176             :                           wpabuf_len(hapd->p2p_beacon_ie));
    1177        2106 :                 tailpos += wpabuf_len(hapd->p2p_beacon_ie);
    1178             :         }
    1179             : #endif /* CONFIG_P2P */
    1180             : #ifdef CONFIG_P2P_MANAGER
    1181        3206 :         if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
    1182             :             P2P_MANAGE)
    1183           5 :                 tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
    1184             : #endif /* CONFIG_P2P_MANAGER */
    1185             : 
    1186             : #ifdef CONFIG_HS20
    1187        5366 :         tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
    1188        5366 :         tailpos = hostapd_eid_osen(hapd, tailpos);
    1189             : #endif /* CONFIG_HS20 */
    1190             : 
    1191        5366 :         tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
    1192             : 
    1193        5366 :         if (hapd->conf->vendor_elements) {
    1194          23 :                 os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
    1195             :                           wpabuf_len(hapd->conf->vendor_elements));
    1196          23 :                 tailpos += wpabuf_len(hapd->conf->vendor_elements);
    1197             :         }
    1198             : 
    1199        5366 :         tail_len = tailpos > tail ? tailpos - tail : 0;
    1200             : 
    1201        5366 :         resp = hostapd_probe_resp_offloads(hapd, &resp_len);
    1202             : #endif /* NEED_AP_MLME */
    1203             : 
    1204        5366 :         os_memset(params, 0, sizeof(*params));
    1205        5366 :         params->head = (u8 *) head;
    1206        5366 :         params->head_len = head_len;
    1207        5366 :         params->tail = tail;
    1208        5366 :         params->tail_len = tail_len;
    1209        5366 :         params->proberesp = resp;
    1210        5366 :         params->proberesp_len = resp_len;
    1211        5366 :         params->dtim_period = hapd->conf->dtim_period;
    1212        5366 :         params->beacon_int = hapd->iconf->beacon_int;
    1213        5366 :         params->basic_rates = hapd->iface->basic_rates;
    1214        5366 :         params->ssid = hapd->conf->ssid.ssid;
    1215        5366 :         params->ssid_len = hapd->conf->ssid.ssid_len;
    1216        5366 :         if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
    1217             :             (WPA_PROTO_WPA | WPA_PROTO_RSN))
    1218         184 :                 params->pairwise_ciphers = hapd->conf->wpa_pairwise |
    1219          92 :                         hapd->conf->rsn_pairwise;
    1220        5274 :         else if (hapd->conf->wpa & WPA_PROTO_RSN)
    1221        3641 :                 params->pairwise_ciphers = hapd->conf->rsn_pairwise;
    1222        1633 :         else if (hapd->conf->wpa & WPA_PROTO_WPA)
    1223          48 :                 params->pairwise_ciphers = hapd->conf->wpa_pairwise;
    1224        5366 :         params->group_cipher = hapd->conf->wpa_group;
    1225        5366 :         params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
    1226        5366 :         params->auth_algs = hapd->conf->auth_algs;
    1227        5366 :         params->wpa_version = hapd->conf->wpa;
    1228       10738 :         params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa ||
    1229        1556 :                 (hapd->conf->ieee802_1x &&
    1230          24 :                  (hapd->conf->default_wep_key_len ||
    1231           9 :                   hapd->conf->individual_wep_key_len));
    1232        5366 :         switch (hapd->conf->ignore_broadcast_ssid) {
    1233             :         case 0:
    1234        5356 :                 params->hide_ssid = NO_SSID_HIDING;
    1235        5356 :                 break;
    1236             :         case 1:
    1237           9 :                 params->hide_ssid = HIDDEN_SSID_ZERO_LEN;
    1238           9 :                 break;
    1239             :         case 2:
    1240           1 :                 params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
    1241           1 :                 break;
    1242             :         }
    1243        5366 :         params->isolate = hapd->conf->isolate;
    1244        5366 :         params->smps_mode = hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_MASK;
    1245             : #ifdef NEED_AP_MLME
    1246        5366 :         params->cts_protect = !!(ieee802_11_erp_info(hapd) &
    1247             :                                 ERP_INFO_USE_PROTECTION);
    1248       10671 :         params->preamble = hapd->iface->num_sta_no_short_preamble == 0 &&
    1249        5305 :                 hapd->iconf->preamble == SHORT_PREAMBLE;
    1250       10720 :         if (hapd->iface->current_mode &&
    1251        5354 :             hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    1252        4726 :                 params->short_slot_time =
    1253        4726 :                         hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1;
    1254             :         else
    1255         640 :                 params->short_slot_time = -1;
    1256        5366 :         if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
    1257         166 :                 params->ht_opmode = -1;
    1258             :         else
    1259        5200 :                 params->ht_opmode = hapd->iface->ht_op_mode;
    1260             : #endif /* NEED_AP_MLME */
    1261        5366 :         params->interworking = hapd->conf->interworking;
    1262        5569 :         if (hapd->conf->interworking &&
    1263         203 :             !is_zero_ether_addr(hapd->conf->hessid))
    1264         111 :                 params->hessid = hapd->conf->hessid;
    1265        5366 :         params->access_network_type = hapd->conf->access_network_type;
    1266        5366 :         params->ap_max_inactivity = hapd->conf->ap_max_inactivity;
    1267             : #ifdef CONFIG_P2P
    1268        2160 :         params->p2p_go_ctwindow = hapd->iconf->p2p_go_ctwindow;
    1269             : #endif /* CONFIG_P2P */
    1270             : #ifdef CONFIG_HS20
    1271        5366 :         params->disable_dgaf = hapd->conf->disable_dgaf;
    1272        5366 :         if (hapd->conf->osen) {
    1273           1 :                 params->privacy = 1;
    1274           1 :                 params->osen = 1;
    1275             :         }
    1276             : #endif /* CONFIG_HS20 */
    1277        5366 :         params->pbss = hapd->conf->pbss;
    1278        5366 :         return 0;
    1279             : }
    1280             : 
    1281             : 
    1282        5366 : void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
    1283             : {
    1284        5366 :         os_free(params->tail);
    1285        5366 :         params->tail = NULL;
    1286        5366 :         os_free(params->head);
    1287        5366 :         params->head = NULL;
    1288        5366 :         os_free(params->proberesp);
    1289        5366 :         params->proberesp = NULL;
    1290        5366 : }
    1291             : 
    1292             : 
    1293        5310 : int ieee802_11_set_beacon(struct hostapd_data *hapd)
    1294             : {
    1295             :         struct wpa_driver_ap_params params;
    1296             :         struct hostapd_freq_params freq;
    1297        5310 :         struct hostapd_iface *iface = hapd->iface;
    1298        5310 :         struct hostapd_config *iconf = iface->conf;
    1299             :         struct wpabuf *beacon, *proberesp, *assocresp;
    1300        5310 :         int res, ret = -1;
    1301             : 
    1302        5310 :         if (hapd->csa_in_progress) {
    1303           0 :                 wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
    1304           0 :                 return -1;
    1305             :         }
    1306             : 
    1307        5310 :         hapd->beacon_set_done = 1;
    1308             : 
    1309        5310 :         if (ieee802_11_build_ap_params(hapd, &params) < 0)
    1310           2 :                 return -1;
    1311             : 
    1312        5308 :         if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
    1313             :             0)
    1314           0 :                 goto fail;
    1315             : 
    1316        5308 :         params.beacon_ies = beacon;
    1317        5308 :         params.proberesp_ies = proberesp;
    1318        5308 :         params.assocresp_ies = assocresp;
    1319        5308 :         params.reenable = hapd->reenable_beacon;
    1320        5308 :         hapd->reenable_beacon = 0;
    1321             : 
    1322       10604 :         if (iface->current_mode &&
    1323       26480 :             hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
    1324        5296 :                                     iconf->channel, iconf->ieee80211n,
    1325             :                                     iconf->ieee80211ac,
    1326             :                                     iconf->secondary_channel,
    1327        5296 :                                     iconf->vht_oper_chwidth,
    1328        5296 :                                     iconf->vht_oper_centr_freq_seg0_idx,
    1329        5296 :                                     iconf->vht_oper_centr_freq_seg1_idx,
    1330        5296 :                                     iface->current_mode->vht_capab) == 0)
    1331        5296 :                 params.freq = &freq;
    1332             : 
    1333        5308 :         res = hostapd_drv_set_ap(hapd, &params);
    1334        5308 :         hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
    1335        5308 :         if (res)
    1336           1 :                 wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
    1337             :         else
    1338        5307 :                 ret = 0;
    1339             : fail:
    1340        5308 :         ieee802_11_free_ap_params(&params);
    1341        5308 :         return ret;
    1342             : }
    1343             : 
    1344             : 
    1345        1083 : int ieee802_11_set_beacons(struct hostapd_iface *iface)
    1346             : {
    1347             :         size_t i;
    1348        1083 :         int ret = 0;
    1349             : 
    1350        2170 :         for (i = 0; i < iface->num_bss; i++) {
    1351        2174 :                 if (iface->bss[i]->started &&
    1352        1087 :                     ieee802_11_set_beacon(iface->bss[i]) < 0)
    1353           0 :                         ret = -1;
    1354             :         }
    1355             : 
    1356        1083 :         return ret;
    1357             : }
    1358             : 
    1359             : 
    1360             : /* only update beacons if started */
    1361          13 : int ieee802_11_update_beacons(struct hostapd_iface *iface)
    1362             : {
    1363             :         size_t i;
    1364          13 :         int ret = 0;
    1365             : 
    1366          26 :         for (i = 0; i < iface->num_bss; i++) {
    1367          26 :                 if (iface->bss[i]->beacon_set_done && iface->bss[i]->started &&
    1368          13 :                     ieee802_11_set_beacon(iface->bss[i]) < 0)
    1369           0 :                         ret = -1;
    1370             :         }
    1371             : 
    1372          13 :         return ret;
    1373             : }
    1374             : 
    1375             : #endif /* CONFIG_NATIVE_WINDOWS */

Generated by: LCOV version 1.10