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 1443382998 Lines: 282 418 67.5 %
Date: 2015-09-27 Functions: 41 47 87.2 %

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

Generated by: LCOV version 1.10