LCOV - code coverage report
Current view: top level - src/ap - ap_drv_ops.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 296 415 71.3 %
Date: 2016-10-02 Functions: 46 52 88.5 %

          Line data    Source code
       1             : /*
       2             :  * hostapd - Driver operations
       3             :  * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #include "utils/common.h"
      12             : #include "common/ieee802_11_defs.h"
      13             : #include "common/hw_features_common.h"
      14             : #include "wps/wps.h"
      15             : #include "p2p/p2p.h"
      16             : #include "hostapd.h"
      17             : #include "ieee802_11.h"
      18             : #include "sta_info.h"
      19             : #include "ap_config.h"
      20             : #include "p2p_hostapd.h"
      21             : #include "hs20.h"
      22             : #include "ap_drv_ops.h"
      23             : 
      24             : 
      25       44750 : u32 hostapd_sta_flags_to_drv(u32 flags)
      26             : {
      27       44750 :         int res = 0;
      28       44750 :         if (flags & WLAN_STA_AUTHORIZED)
      29        3963 :                 res |= WPA_STA_AUTHORIZED;
      30       44750 :         if (flags & WLAN_STA_WMM)
      31       36193 :                 res |= WPA_STA_WMM;
      32       44750 :         if (flags & WLAN_STA_SHORT_PREAMBLE)
      33       35554 :                 res |= WPA_STA_SHORT_PREAMBLE;
      34       44750 :         if (flags & WLAN_STA_MFP)
      35         612 :                 res |= WPA_STA_MFP;
      36       44750 :         if (flags & WLAN_STA_AUTH)
      37       39371 :                 res |= WPA_STA_AUTHENTICATED;
      38       44750 :         if (flags & WLAN_STA_ASSOC)
      39       34942 :                 res |= WPA_STA_ASSOCIATED;
      40       44750 :         return res;
      41             : }
      42             : 
      43             : 
      44       52232 : static int add_buf(struct wpabuf **dst, const struct wpabuf *src)
      45             : {
      46       52232 :         if (!src)
      47       36434 :                 return 0;
      48       15798 :         if (wpabuf_resize(dst, wpabuf_len(src)) != 0)
      49           0 :                 return -1;
      50       15798 :         wpabuf_put_buf(*dst, src);
      51       15798 :         return 0;
      52             : }
      53             : 
      54             : 
      55       48369 : static int add_buf_data(struct wpabuf **dst, const u8 *data, size_t len)
      56             : {
      57       48369 :         if (!data || !len)
      58       31782 :                 return 0;
      59       16587 :         if (wpabuf_resize(dst, len) != 0)
      60           0 :                 return -1;
      61       16587 :         wpabuf_put_data(*dst, data, len);
      62       16587 :         return 0;
      63             : }
      64             : 
      65             : 
      66        5366 : int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
      67             :                                struct wpabuf **beacon_ret,
      68             :                                struct wpabuf **proberesp_ret,
      69             :                                struct wpabuf **assocresp_ret)
      70             : {
      71        5366 :         struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
      72             :         u8 buf[200], *pos;
      73             : 
      74        5366 :         *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
      75             : 
      76        5366 :         pos = buf;
      77        5366 :         pos = hostapd_eid_time_adv(hapd, pos);
      78        5366 :         if (add_buf_data(&beacon, buf, pos - buf) < 0)
      79           0 :                 goto fail;
      80        5366 :         pos = hostapd_eid_time_zone(hapd, pos);
      81        5366 :         if (add_buf_data(&proberesp, buf, pos - buf) < 0)
      82           0 :                 goto fail;
      83             : 
      84        5366 :         pos = buf;
      85        5366 :         pos = hostapd_eid_ext_capab(hapd, pos);
      86        5366 :         if (add_buf_data(&assocresp, buf, pos - buf) < 0)
      87           0 :                 goto fail;
      88        5366 :         pos = hostapd_eid_interworking(hapd, pos);
      89        5366 :         pos = hostapd_eid_adv_proto(hapd, pos);
      90        5366 :         pos = hostapd_eid_roaming_consortium(hapd, pos);
      91       10732 :         if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
      92        5366 :             add_buf_data(&proberesp, buf, pos - buf) < 0)
      93             :                 goto fail;
      94             : 
      95             : #ifdef CONFIG_FST
      96       10732 :         if (add_buf(&beacon, hapd->iface->fst_ies) < 0 ||
      97       10732 :             add_buf(&proberesp, hapd->iface->fst_ies) < 0 ||
      98        5366 :             add_buf(&assocresp, hapd->iface->fst_ies) < 0)
      99             :                 goto fail;
     100             : #endif /* CONFIG_FST */
     101             : 
     102       10732 :         if (add_buf(&beacon, hapd->wps_beacon_ie) < 0 ||
     103        5366 :             add_buf(&proberesp, hapd->wps_probe_resp_ie) < 0)
     104             :                 goto fail;
     105             : 
     106             : #ifdef CONFIG_P2P
     107        4320 :         if (add_buf(&beacon, hapd->p2p_beacon_ie) < 0 ||
     108        2160 :             add_buf(&proberesp, hapd->p2p_probe_resp_ie) < 0)
     109             :                 goto fail;
     110             : #endif /* CONFIG_P2P */
     111             : 
     112             : #ifdef CONFIG_P2P_MANAGER
     113        3206 :         if (hapd->conf->p2p & P2P_MANAGE) {
     114           5 :                 if (wpabuf_resize(&beacon, 100) == 0) {
     115             :                         u8 *start, *p;
     116           5 :                         start = wpabuf_put(beacon, 0);
     117           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     118           5 :                         wpabuf_put(beacon, p - start);
     119             :                 }
     120             : 
     121           5 :                 if (wpabuf_resize(&proberesp, 100) == 0) {
     122             :                         u8 *start, *p;
     123           5 :                         start = wpabuf_put(proberesp, 0);
     124           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     125           5 :                         wpabuf_put(proberesp, p - start);
     126             :                 }
     127             :         }
     128             : #endif /* CONFIG_P2P_MANAGER */
     129             : 
     130             : #ifdef CONFIG_WPS
     131        5366 :         if (hapd->conf->wps_state) {
     132        2878 :                 struct wpabuf *a = wps_build_assoc_resp_ie();
     133        2878 :                 add_buf(&assocresp, a);
     134        2878 :                 wpabuf_free(a);
     135             :         }
     136             : #endif /* CONFIG_WPS */
     137             : 
     138             : #ifdef CONFIG_P2P_MANAGER
     139        3206 :         if (hapd->conf->p2p & P2P_MANAGE) {
     140           5 :                 if (wpabuf_resize(&assocresp, 100) == 0) {
     141             :                         u8 *start, *p;
     142           5 :                         start = wpabuf_put(assocresp, 0);
     143           5 :                         p = hostapd_eid_p2p_manage(hapd, start);
     144           5 :                         wpabuf_put(assocresp, p - start);
     145             :                 }
     146             :         }
     147             : #endif /* CONFIG_P2P_MANAGER */
     148             : 
     149             : #ifdef CONFIG_WIFI_DISPLAY
     150        2160 :         if (hapd->p2p_group) {
     151             :                 struct wpabuf *a;
     152        2106 :                 a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
     153        2106 :                 add_buf(&assocresp, a);
     154        2106 :                 wpabuf_free(a);
     155             :         }
     156             : #endif /* CONFIG_WIFI_DISPLAY */
     157             : 
     158             : #ifdef CONFIG_HS20
     159        5366 :         pos = hostapd_eid_hs20_indication(hapd, buf);
     160       10732 :         if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
     161        5366 :             add_buf_data(&proberesp, buf, pos - buf) < 0)
     162             :                 goto fail;
     163             : 
     164        5366 :         pos = hostapd_eid_osen(hapd, buf);
     165       10732 :         if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
     166        5366 :             add_buf_data(&proberesp, buf, pos - buf) < 0)
     167             :                 goto fail;
     168             : #endif /* CONFIG_HS20 */
     169             : 
     170             : #ifdef CONFIG_MBO
     171        5366 :         if (hapd->conf->mbo_enabled) {
     172          25 :                 pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
     173          50 :                 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
     174          50 :                     add_buf_data(&proberesp, buf, pos - buf) < 0 ||
     175          25 :                     add_buf_data(&assocresp, buf, pos - buf) < 0)
     176             :                         goto fail;
     177             :         }
     178             : #endif /* CONFIG_MBO */
     179             : 
     180        5366 :         add_buf(&beacon, hapd->conf->vendor_elements);
     181        5366 :         add_buf(&proberesp, hapd->conf->vendor_elements);
     182        5366 :         add_buf(&assocresp, hapd->conf->assocresp_elements);
     183             : 
     184        5366 :         *beacon_ret = beacon;
     185        5366 :         *proberesp_ret = proberesp;
     186        5366 :         *assocresp_ret = assocresp;
     187             : 
     188        5366 :         return 0;
     189             : 
     190             : fail:
     191           0 :         wpabuf_free(beacon);
     192           0 :         wpabuf_free(proberesp);
     193           0 :         wpabuf_free(assocresp);
     194           0 :         return -1;
     195             : }
     196             : 
     197             : 
     198        5366 : void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
     199             :                                struct wpabuf *beacon,
     200             :                                struct wpabuf *proberesp,
     201             :                                struct wpabuf *assocresp)
     202             : {
     203        5366 :         wpabuf_free(beacon);
     204        5366 :         wpabuf_free(proberesp);
     205        5366 :         wpabuf_free(assocresp);
     206        5366 : }
     207             : 
     208             : 
     209        2657 : int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
     210             : {
     211        2657 :         if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
     212        2657 :                 return 0;
     213             : 
     214           0 :         return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
     215             : }
     216             : 
     217             : 
     218        4798 : int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
     219             : {
     220             :         struct wpabuf *beacon, *proberesp, *assocresp;
     221             :         int ret;
     222             : 
     223        4798 :         if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
     224        4798 :                 return 0;
     225             : 
     226           0 :         if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
     227             :             0)
     228           0 :                 return -1;
     229             : 
     230           0 :         ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
     231             :                                           assocresp);
     232             : 
     233           0 :         hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
     234             : 
     235           0 :         return ret;
     236             : }
     237             : 
     238             : 
     239        7328 : int hostapd_set_authorized(struct hostapd_data *hapd,
     240             :                            struct sta_info *sta, int authorized)
     241             : {
     242        7328 :         if (authorized) {
     243        2167 :                 return hostapd_sta_set_flags(hapd, sta->addr,
     244        2167 :                                              hostapd_sta_flags_to_drv(
     245             :                                                      sta->flags),
     246             :                                              WPA_STA_AUTHORIZED, ~0);
     247             :         }
     248             : 
     249        5161 :         return hostapd_sta_set_flags(hapd, sta->addr,
     250        5161 :                                      hostapd_sta_flags_to_drv(sta->flags),
     251             :                                      0, ~WPA_STA_AUTHORIZED);
     252             : }
     253             : 
     254             : 
     255        9183 : int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
     256             : {
     257             :         int set_flags, total_flags, flags_and, flags_or;
     258        9183 :         total_flags = hostapd_sta_flags_to_drv(sta->flags);
     259        9183 :         set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
     260       16828 :         if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
     261        9410 :              sta->auth_alg == WLAN_AUTH_FT) &&
     262        1765 :             sta->flags & WLAN_STA_AUTHORIZED)
     263         989 :                 set_flags |= WPA_STA_AUTHORIZED;
     264        9183 :         flags_or = total_flags & set_flags;
     265        9183 :         flags_and = total_flags | ~set_flags;
     266        9183 :         return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
     267             :                                      flags_or, flags_and);
     268             : }
     269             : 
     270             : 
     271        3319 : int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
     272             :                               int enabled)
     273             : {
     274             :         struct wpa_bss_params params;
     275        3319 :         os_memset(&params, 0, sizeof(params));
     276        3319 :         params.ifname = ifname;
     277        3319 :         params.enabled = enabled;
     278        3319 :         if (enabled) {
     279        1622 :                 params.wpa = hapd->conf->wpa;
     280        1622 :                 params.ieee802_1x = hapd->conf->ieee802_1x;
     281        1622 :                 params.wpa_group = hapd->conf->wpa_group;
     282        1622 :                 if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
     283             :                     (WPA_PROTO_WPA | WPA_PROTO_RSN))
     284          58 :                         params.wpa_pairwise = hapd->conf->wpa_pairwise |
     285          29 :                                 hapd->conf->rsn_pairwise;
     286        1593 :                 else if (hapd->conf->wpa & WPA_PROTO_RSN)
     287        1561 :                         params.wpa_pairwise = hapd->conf->rsn_pairwise;
     288          32 :                 else if (hapd->conf->wpa & WPA_PROTO_WPA)
     289          16 :                         params.wpa_pairwise = hapd->conf->wpa_pairwise;
     290        1622 :                 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
     291        1622 :                 params.rsn_preauth = hapd->conf->rsn_preauth;
     292             : #ifdef CONFIG_IEEE80211W
     293        1622 :                 params.ieee80211w = hapd->conf->ieee80211w;
     294             : #endif /* CONFIG_IEEE80211W */
     295             :         }
     296        3319 :         return hostapd_set_ieee8021x(hapd, &params);
     297             : }
     298             : 
     299             : 
     300          51 : int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
     301             : {
     302             :         char force_ifname[IFNAMSIZ];
     303             :         u8 if_addr[ETH_ALEN];
     304          51 :         return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
     305             :                               NULL, NULL, force_ifname, if_addr, NULL, 0);
     306             : }
     307             : 
     308             : 
     309          51 : int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
     310             : {
     311          51 :         return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
     312             : }
     313             : 
     314             : 
     315           2 : int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
     316             :                         const u8 *addr, int aid, int val)
     317             : {
     318           2 :         const char *bridge = NULL;
     319             : 
     320           2 :         if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
     321           0 :                 return -1;
     322           2 :         if (hapd->conf->wds_bridge[0])
     323           2 :                 bridge = hapd->conf->wds_bridge;
     324           0 :         else if (hapd->conf->bridge[0])
     325           0 :                 bridge = hapd->conf->bridge;
     326           2 :         return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
     327             :                                          bridge, ifname_wds);
     328             : }
     329             : 
     330             : 
     331         113 : int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
     332             :                          u16 auth_alg)
     333             : {
     334         113 :         if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
     335         113 :                 return 0;
     336           0 :         return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
     337             : }
     338             : 
     339             : 
     340           0 : int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
     341             :                      u16 seq, u16 status, const u8 *ie, size_t len)
     342             : {
     343           0 :         if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
     344           0 :                 return 0;
     345           0 :         return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
     346             :                                       seq, status, ie, len);
     347             : }
     348             : 
     349             : 
     350           0 : int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
     351             :                       int reassoc, u16 status, const u8 *ie, size_t len)
     352             : {
     353           0 :         if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
     354           0 :                 return 0;
     355           0 :         return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
     356             :                                        reassoc, status, ie, len);
     357             : }
     358             : 
     359             : 
     360        9464 : int hostapd_sta_add(struct hostapd_data *hapd,
     361             :                     const u8 *addr, u16 aid, u16 capability,
     362             :                     const u8 *supp_rates, size_t supp_rates_len,
     363             :                     u16 listen_interval,
     364             :                     const struct ieee80211_ht_capabilities *ht_capab,
     365             :                     const struct ieee80211_vht_capabilities *vht_capab,
     366             :                     u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
     367             :                     int set)
     368             : {
     369             :         struct hostapd_sta_add_params params;
     370             : 
     371        9464 :         if (hapd->driver == NULL)
     372           0 :                 return 0;
     373        9464 :         if (hapd->driver->sta_add == NULL)
     374           0 :                 return 0;
     375             : 
     376        9464 :         os_memset(&params, 0, sizeof(params));
     377        9464 :         params.addr = addr;
     378        9464 :         params.aid = aid;
     379        9464 :         params.capability = capability;
     380        9464 :         params.supp_rates = supp_rates;
     381        9464 :         params.supp_rates_len = supp_rates_len;
     382        9464 :         params.listen_interval = listen_interval;
     383        9464 :         params.ht_capabilities = ht_capab;
     384        9464 :         params.vht_capabilities = vht_capab;
     385        9464 :         params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
     386        9464 :         params.vht_opmode = vht_opmode;
     387        9464 :         params.flags = hostapd_sta_flags_to_drv(flags);
     388        9464 :         params.qosinfo = qosinfo;
     389        9464 :         params.support_p2p_ps = supp_p2p_ps;
     390        9464 :         params.set = set;
     391        9464 :         return hapd->driver->sta_add(hapd->drv_priv, &params);
     392             : }
     393             : 
     394             : 
     395           0 : int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
     396             :                       u8 *tspec_ie, size_t tspec_ielen)
     397             : {
     398           0 :         if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
     399           0 :                 return 0;
     400           0 :         return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
     401             :                                        tspec_ielen);
     402             : }
     403             : 
     404             : 
     405        6201 : int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
     406             : {
     407        6201 :         if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
     408        6201 :                 return 0;
     409           0 :         return hapd->driver->set_privacy(hapd->drv_priv, enabled);
     410             : }
     411             : 
     412             : 
     413        3276 : int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
     414             :                              size_t elem_len)
     415             : {
     416        3276 :         if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
     417        3276 :                 return 0;
     418           0 :         return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
     419             : }
     420             : 
     421             : 
     422        2659 : int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
     423             : {
     424        2659 :         if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
     425        2659 :                 return 0;
     426           0 :         return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
     427             : }
     428             : 
     429             : 
     430        2489 : int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
     431             : {
     432        2489 :         if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
     433        2489 :                 return 0;
     434           0 :         return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
     435             : }
     436             : 
     437             : 
     438          95 : int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
     439             :                    const char *ifname, const u8 *addr, void *bss_ctx,
     440             :                    void **drv_priv, char *force_ifname, u8 *if_addr,
     441             :                    const char *bridge, int use_existing)
     442             : {
     443          95 :         if (hapd->driver == NULL || hapd->driver->if_add == NULL)
     444           0 :                 return -1;
     445          95 :         return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
     446             :                                     bss_ctx, drv_priv, force_ifname, if_addr,
     447             :                                     bridge, use_existing, 1);
     448             : }
     449             : 
     450             : 
     451          95 : int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
     452             :                       const char *ifname)
     453             : {
     454         190 :         if (hapd->driver == NULL || hapd->drv_priv == NULL ||
     455          95 :             hapd->driver->if_remove == NULL)
     456           0 :                 return -1;
     457          95 :         return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
     458             : }
     459             : 
     460             : 
     461        3319 : int hostapd_set_ieee8021x(struct hostapd_data *hapd,
     462             :                           struct wpa_bss_params *params)
     463             : {
     464        3319 :         if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
     465        3319 :                 return 0;
     466           0 :         return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
     467             : }
     468             : 
     469             : 
     470        2509 : int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
     471             :                        const u8 *addr, int idx, u8 *seq)
     472             : {
     473        2509 :         if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
     474           0 :                 return 0;
     475        2509 :         return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
     476             :                                         seq);
     477             : }
     478             : 
     479             : 
     480        2466 : int hostapd_flush(struct hostapd_data *hapd)
     481             : {
     482        2466 :         if (hapd->driver == NULL || hapd->driver->flush == NULL)
     483           0 :                 return 0;
     484        2466 :         return hapd->driver->flush(hapd->drv_priv);
     485             : }
     486             : 
     487             : 
     488        2430 : int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
     489             :                      int freq, int channel, int ht_enabled, int vht_enabled,
     490             :                      int sec_channel_offset, int vht_oper_chwidth,
     491             :                      int center_segment0, int center_segment1)
     492             : {
     493             :         struct hostapd_freq_params data;
     494             : 
     495        4860 :         if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
     496             :                                     vht_enabled, sec_channel_offset,
     497             :                                     vht_oper_chwidth,
     498             :                                     center_segment0, center_segment1,
     499        2430 :                                     hapd->iface->current_mode ?
     500        2430 :                                     hapd->iface->current_mode->vht_capab : 0))
     501           2 :                 return -1;
     502             : 
     503        2428 :         if (hapd->driver == NULL)
     504           0 :                 return 0;
     505        2428 :         if (hapd->driver->set_freq == NULL)
     506           0 :                 return 0;
     507        2428 :         return hapd->driver->set_freq(hapd->drv_priv, &data);
     508             : }
     509             : 
     510           1 : int hostapd_set_rts(struct hostapd_data *hapd, int rts)
     511             : {
     512           1 :         if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
     513           0 :                 return 0;
     514           1 :         return hapd->driver->set_rts(hapd->drv_priv, rts);
     515             : }
     516             : 
     517             : 
     518           3 : int hostapd_set_frag(struct hostapd_data *hapd, int frag)
     519             : {
     520           3 :         if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
     521           0 :                 return 0;
     522           3 :         return hapd->driver->set_frag(hapd->drv_priv, frag);
     523             : }
     524             : 
     525             : 
     526       16511 : int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
     527             :                           int total_flags, int flags_or, int flags_and)
     528             : {
     529       16511 :         if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
     530           0 :                 return 0;
     531       16511 :         return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
     532             :                                            flags_or, flags_and);
     533             : }
     534             : 
     535             : 
     536         376 : int hostapd_set_country(struct hostapd_data *hapd, const char *country)
     537             : {
     538         752 :         if (hapd->driver == NULL ||
     539         376 :             hapd->driver->set_country == NULL)
     540           0 :                 return 0;
     541         376 :         return hapd->driver->set_country(hapd->drv_priv, country);
     542             : }
     543             : 
     544             : 
     545        8656 : int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
     546             :                                 int cw_min, int cw_max, int burst_time)
     547             : {
     548        8656 :         if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
     549          48 :                 return 0;
     550        8608 :         return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
     551             :                                                  cw_min, cw_max, burst_time);
     552             : }
     553             : 
     554             : 
     555             : struct hostapd_hw_modes *
     556        2618 : hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
     557             :                             u16 *flags)
     558             : {
     559        5236 :         if (hapd->driver == NULL ||
     560        2618 :             hapd->driver->get_hw_feature_data == NULL)
     561           0 :                 return NULL;
     562        2618 :         return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
     563             :                                                  flags);
     564             : }
     565             : 
     566             : 
     567        2602 : int hostapd_driver_commit(struct hostapd_data *hapd)
     568             : {
     569        2602 :         if (hapd->driver == NULL || hapd->driver->commit == NULL)
     570        2602 :                 return 0;
     571           0 :         return hapd->driver->commit(hapd->drv_priv);
     572             : }
     573             : 
     574             : 
     575       17343 : int hostapd_drv_none(struct hostapd_data *hapd)
     576             : {
     577       17343 :         return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
     578             : }
     579             : 
     580             : 
     581         126 : int hostapd_driver_scan(struct hostapd_data *hapd,
     582             :                         struct wpa_driver_scan_params *params)
     583             : {
     584         126 :         if (hapd->driver && hapd->driver->scan2)
     585         126 :                 return hapd->driver->scan2(hapd->drv_priv, params);
     586           0 :         return -1;
     587             : }
     588             : 
     589             : 
     590          71 : struct wpa_scan_results * hostapd_driver_get_scan_results(
     591             :         struct hostapd_data *hapd)
     592             : {
     593          71 :         if (hapd->driver && hapd->driver->get_scan_results2)
     594          71 :                 return hapd->driver->get_scan_results2(hapd->drv_priv);
     595           0 :         return NULL;
     596             : }
     597             : 
     598             : 
     599           0 : int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
     600             :                            int duration)
     601             : {
     602           0 :         if (hapd->driver && hapd->driver->set_noa)
     603           0 :                 return hapd->driver->set_noa(hapd->drv_priv, count, start,
     604             :                                              duration);
     605           0 :         return -1;
     606             : }
     607             : 
     608             : 
     609       36989 : int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
     610             :                         enum wpa_alg alg, const u8 *addr,
     611             :                         int key_idx, int set_tx,
     612             :                         const u8 *seq, size_t seq_len,
     613             :                         const u8 *key, size_t key_len)
     614             : {
     615       36989 :         if (hapd->driver == NULL || hapd->driver->set_key == NULL)
     616          96 :                 return 0;
     617       36893 :         return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
     618             :                                      key_idx, set_tx, seq, seq_len, key,
     619             :                                      key_len);
     620             : }
     621             : 
     622             : 
     623       10731 : int hostapd_drv_send_mlme(struct hostapd_data *hapd,
     624             :                           const void *msg, size_t len, int noack)
     625             : {
     626       10731 :         if (!hapd->driver || !hapd->driver->send_mlme || !hapd->drv_priv)
     627           4 :                 return 0;
     628       10727 :         return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
     629             :                                        NULL, 0);
     630             : }
     631             : 
     632             : 
     633        4801 : int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
     634             :                               const void *msg, size_t len, int noack,
     635             :                               const u16 *csa_offs, size_t csa_offs_len)
     636             : {
     637        4801 :         if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
     638           0 :                 return 0;
     639        4801 :         return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
     640             :                                        csa_offs, csa_offs_len);
     641             : }
     642             : 
     643             : 
     644        5728 : int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
     645             :                            const u8 *addr, int reason)
     646             : {
     647        5728 :         if (!hapd->driver || !hapd->driver->sta_deauth || !hapd->drv_priv)
     648           1 :                 return 0;
     649        5727 :         return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
     650             :                                         reason);
     651             : }
     652             : 
     653             : 
     654          10 : int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
     655             :                              const u8 *addr, int reason)
     656             : {
     657          10 :         if (!hapd->driver || !hapd->driver->sta_disassoc || !hapd->drv_priv)
     658           1 :                 return 0;
     659           9 :         return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
     660             :                                           reason);
     661             : }
     662             : 
     663             : 
     664          34 : int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
     665             :                          const u8 *peer, u8 *buf, u16 *buf_len)
     666             : {
     667          34 :         if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
     668          34 :                 return -1;
     669           0 :         return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
     670             :                                       buf_len);
     671             : }
     672             : 
     673             : 
     674         399 : int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
     675             :                             unsigned int wait, const u8 *dst, const u8 *data,
     676             :                             size_t len)
     677             : {
     678             :         const u8 *bssid;
     679         399 :         const u8 wildcard_bssid[ETH_ALEN] = {
     680             :                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     681             :         };
     682             : 
     683         399 :         if (!hapd->driver || !hapd->driver->send_action || !hapd->drv_priv)
     684           2 :                 return 0;
     685         397 :         bssid = hapd->own_addr;
     686         397 :         if (!is_multicast_ether_addr(dst) &&
     687         397 :             len > 0 && data[0] == WLAN_ACTION_PUBLIC) {
     688             :                 struct sta_info *sta;
     689             : 
     690             :                 /*
     691             :                  * Public Action frames to a STA that is not a member of the BSS
     692             :                  * shall use wildcard BSSID value.
     693             :                  */
     694           2 :                 sta = ap_get_sta(hapd, dst);
     695           2 :                 if (!sta || !(sta->flags & WLAN_STA_ASSOC))
     696           2 :                         bssid = wildcard_bssid;
     697             :         }
     698         794 :         return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
     699         397 :                                          hapd->own_addr, bssid, data, len, 0);
     700             : }
     701             : 
     702             : 
     703         504 : int hostapd_drv_send_action_addr3_ap(struct hostapd_data *hapd,
     704             :                                      unsigned int freq,
     705             :                                      unsigned int wait, const u8 *dst,
     706             :                                      const u8 *data, size_t len)
     707             : {
     708         504 :         if (hapd->driver == NULL || hapd->driver->send_action == NULL)
     709           0 :                 return 0;
     710        1008 :         return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
     711         504 :                                          hapd->own_addr, hapd->own_addr, data,
     712             :                                          len, 0);
     713             : }
     714             : 
     715             : 
     716          15 : int hostapd_start_dfs_cac(struct hostapd_iface *iface,
     717             :                           enum hostapd_hw_mode mode, int freq,
     718             :                           int channel, int ht_enabled, int vht_enabled,
     719             :                           int sec_channel_offset, int vht_oper_chwidth,
     720             :                           int center_segment0, int center_segment1)
     721             : {
     722          15 :         struct hostapd_data *hapd = iface->bss[0];
     723             :         struct hostapd_freq_params data;
     724             :         int res;
     725             : 
     726          15 :         if (!hapd->driver || !hapd->driver->start_dfs_cac)
     727           0 :                 return 0;
     728             : 
     729          15 :         if (!iface->conf->ieee80211h) {
     730           0 :                 wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
     731             :                            "is not enabled");
     732           0 :                 return -1;
     733             :         }
     734             : 
     735          15 :         if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
     736             :                                     vht_enabled, sec_channel_offset,
     737             :                                     vht_oper_chwidth, center_segment0,
     738             :                                     center_segment1,
     739          15 :                                     iface->current_mode->vht_capab)) {
     740           1 :                 wpa_printf(MSG_ERROR, "Can't set freq params");
     741           1 :                 return -1;
     742             :         }
     743             : 
     744          14 :         res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
     745          14 :         if (!res) {
     746          13 :                 iface->cac_started = 1;
     747          13 :                 os_get_reltime(&iface->dfs_cac_start);
     748             :         }
     749             : 
     750          14 :         return res;
     751             : }
     752             : 
     753             : 
     754           4 : int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
     755             :                             const u8 *qos_map_set, u8 qos_map_set_len)
     756             : {
     757           4 :         if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
     758           1 :                 return 0;
     759           3 :         return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
     760             :                                          qos_map_set_len);
     761             : }
     762             : 
     763             : 
     764           0 : static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
     765             :                                              struct hostapd_hw_modes *mode,
     766             :                                              int acs_ch_list_all,
     767             :                                              int **freq_list)
     768             : {
     769             :         int i;
     770             : 
     771           0 :         for (i = 0; i < mode->num_channels; i++) {
     772           0 :                 struct hostapd_channel_data *chan = &mode->channels[i];
     773             : 
     774           0 :                 if ((acs_ch_list_all ||
     775           0 :                      freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
     776           0 :                                               chan->chan)) &&
     777           0 :                     !(chan->flag & HOSTAPD_CHAN_DISABLED))
     778           0 :                         int_array_add_unique(freq_list, chan->freq);
     779             :         }
     780           0 : }
     781             : 
     782             : 
     783        2004 : void hostapd_get_ext_capa(struct hostapd_iface *iface)
     784             : {
     785        2004 :         struct hostapd_data *hapd = iface->bss[0];
     786             : 
     787        2004 :         if (!hapd->driver || !hapd->driver->get_ext_capab)
     788        2004 :                 return;
     789             : 
     790        2004 :         hapd->driver->get_ext_capab(hapd->drv_priv, WPA_IF_AP_BSS,
     791             :                                     &iface->extended_capa,
     792             :                                     &iface->extended_capa_mask,
     793             :                                     &iface->extended_capa_len);
     794             : }
     795             : 
     796             : 
     797           0 : int hostapd_drv_do_acs(struct hostapd_data *hapd)
     798             : {
     799             :         struct drv_acs_params params;
     800           0 :         int ret, i, acs_ch_list_all = 0;
     801           0 :         u8 *channels = NULL;
     802           0 :         unsigned int num_channels = 0;
     803             :         struct hostapd_hw_modes *mode;
     804           0 :         int *freq_list = NULL;
     805             : 
     806           0 :         if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
     807           0 :                 return 0;
     808             : 
     809           0 :         os_memset(&params, 0, sizeof(params));
     810           0 :         params.hw_mode = hapd->iface->conf->hw_mode;
     811             : 
     812             :         /*
     813             :          * If no chanlist config parameter is provided, include all enabled
     814             :          * channels of the selected hw_mode.
     815             :          */
     816           0 :         if (!hapd->iface->conf->acs_ch_list.num)
     817           0 :                 acs_ch_list_all = 1;
     818             : 
     819           0 :         mode = hapd->iface->current_mode;
     820           0 :         if (mode) {
     821           0 :                 channels = os_malloc(mode->num_channels);
     822           0 :                 if (channels == NULL)
     823           0 :                         return -1;
     824             : 
     825           0 :                 for (i = 0; i < mode->num_channels; i++) {
     826           0 :                         struct hostapd_channel_data *chan = &mode->channels[i];
     827           0 :                         if (!acs_ch_list_all &&
     828           0 :                             !freq_range_list_includes(
     829           0 :                                     &hapd->iface->conf->acs_ch_list,
     830           0 :                                     chan->chan))
     831           0 :                                 continue;
     832           0 :                         if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
     833           0 :                                 channels[num_channels++] = chan->chan;
     834           0 :                                 int_array_add_unique(&freq_list, chan->freq);
     835             :                         }
     836             :                 }
     837             :         } else {
     838           0 :                 for (i = 0; i < hapd->iface->num_hw_features; i++) {
     839           0 :                         mode = &hapd->iface->hw_features[i];
     840           0 :                         hostapd_get_hw_mode_any_channels(hapd, mode,
     841             :                                                          acs_ch_list_all,
     842             :                                                          &freq_list);
     843             :                 }
     844             :         }
     845             : 
     846           0 :         params.ch_list = channels;
     847           0 :         params.ch_list_len = num_channels;
     848           0 :         params.freq_list = freq_list;
     849             : 
     850           0 :         params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
     851           0 :         params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
     852             :                                  HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
     853           0 :         params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
     854           0 :         params.ch_width = 20;
     855           0 :         if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
     856           0 :                 params.ch_width = 40;
     857             : 
     858             :         /* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
     859             :          */
     860           0 :         if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) {
     861           0 :                 if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
     862           0 :                         params.ch_width = 80;
     863           0 :                 else if (hapd->iface->conf->vht_oper_chwidth ==
     864           0 :                          VHT_CHANWIDTH_160MHZ ||
     865           0 :                          hapd->iface->conf->vht_oper_chwidth ==
     866             :                          VHT_CHANWIDTH_80P80MHZ)
     867           0 :                         params.ch_width = 160;
     868             :         }
     869             : 
     870           0 :         ret = hapd->driver->do_acs(hapd->drv_priv, &params);
     871           0 :         os_free(channels);
     872             : 
     873           0 :         return ret;
     874             : }

Generated by: LCOV version 1.10