1e28a4053SRui Paulo /* 2e28a4053SRui Paulo * hostapd - Driver operations 3e28a4053SRui Paulo * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> 4e28a4053SRui Paulo * 5*f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6*f05cddf9SRui Paulo * See README for more details. 7e28a4053SRui Paulo */ 8e28a4053SRui Paulo 9e28a4053SRui Paulo #include "utils/includes.h" 10e28a4053SRui Paulo 11e28a4053SRui Paulo #include "utils/common.h" 12e28a4053SRui Paulo #include "drivers/driver.h" 13e28a4053SRui Paulo #include "common/ieee802_11_defs.h" 14*f05cddf9SRui Paulo #include "wps/wps.h" 15*f05cddf9SRui Paulo #include "p2p/p2p.h" 16e28a4053SRui Paulo #include "hostapd.h" 17e28a4053SRui Paulo #include "ieee802_11.h" 18e28a4053SRui Paulo #include "sta_info.h" 19e28a4053SRui Paulo #include "ap_config.h" 20*f05cddf9SRui Paulo #include "p2p_hostapd.h" 21*f05cddf9SRui Paulo #include "hs20.h" 22e28a4053SRui Paulo #include "ap_drv_ops.h" 23e28a4053SRui Paulo 24e28a4053SRui Paulo 25*f05cddf9SRui Paulo u32 hostapd_sta_flags_to_drv(u32 flags) 26e28a4053SRui Paulo { 27e28a4053SRui Paulo int res = 0; 28e28a4053SRui Paulo if (flags & WLAN_STA_AUTHORIZED) 29e28a4053SRui Paulo res |= WPA_STA_AUTHORIZED; 30e28a4053SRui Paulo if (flags & WLAN_STA_WMM) 31e28a4053SRui Paulo res |= WPA_STA_WMM; 32e28a4053SRui Paulo if (flags & WLAN_STA_SHORT_PREAMBLE) 33e28a4053SRui Paulo res |= WPA_STA_SHORT_PREAMBLE; 34e28a4053SRui Paulo if (flags & WLAN_STA_MFP) 35e28a4053SRui Paulo res |= WPA_STA_MFP; 36e28a4053SRui Paulo return res; 37e28a4053SRui Paulo } 38e28a4053SRui Paulo 39e28a4053SRui Paulo 40*f05cddf9SRui Paulo int hostapd_build_ap_extra_ies(struct hostapd_data *hapd, 41*f05cddf9SRui Paulo struct wpabuf **beacon_ret, 42*f05cddf9SRui Paulo struct wpabuf **proberesp_ret, 43*f05cddf9SRui Paulo struct wpabuf **assocresp_ret) 44e28a4053SRui Paulo { 45*f05cddf9SRui Paulo struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL; 46*f05cddf9SRui Paulo u8 buf[200], *pos; 47*f05cddf9SRui Paulo 48*f05cddf9SRui Paulo *beacon_ret = *proberesp_ret = *assocresp_ret = NULL; 49*f05cddf9SRui Paulo 50*f05cddf9SRui Paulo pos = buf; 51*f05cddf9SRui Paulo pos = hostapd_eid_time_adv(hapd, pos); 52*f05cddf9SRui Paulo if (pos != buf) { 53*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, pos - buf) != 0) 54*f05cddf9SRui Paulo goto fail; 55*f05cddf9SRui Paulo wpabuf_put_data(beacon, buf, pos - buf); 56*f05cddf9SRui Paulo } 57*f05cddf9SRui Paulo pos = hostapd_eid_time_zone(hapd, pos); 58*f05cddf9SRui Paulo if (pos != buf) { 59*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, pos - buf) != 0) 60*f05cddf9SRui Paulo goto fail; 61*f05cddf9SRui Paulo wpabuf_put_data(proberesp, buf, pos - buf); 62*f05cddf9SRui Paulo } 63*f05cddf9SRui Paulo 64*f05cddf9SRui Paulo pos = buf; 65*f05cddf9SRui Paulo pos = hostapd_eid_ext_capab(hapd, pos); 66*f05cddf9SRui Paulo if (pos != buf) { 67*f05cddf9SRui Paulo if (wpabuf_resize(&assocresp, pos - buf) != 0) 68*f05cddf9SRui Paulo goto fail; 69*f05cddf9SRui Paulo wpabuf_put_data(assocresp, buf, pos - buf); 70*f05cddf9SRui Paulo } 71*f05cddf9SRui Paulo pos = hostapd_eid_interworking(hapd, pos); 72*f05cddf9SRui Paulo pos = hostapd_eid_adv_proto(hapd, pos); 73*f05cddf9SRui Paulo pos = hostapd_eid_roaming_consortium(hapd, pos); 74*f05cddf9SRui Paulo if (pos != buf) { 75*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, pos - buf) != 0) 76*f05cddf9SRui Paulo goto fail; 77*f05cddf9SRui Paulo wpabuf_put_data(beacon, buf, pos - buf); 78*f05cddf9SRui Paulo 79*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, pos - buf) != 0) 80*f05cddf9SRui Paulo goto fail; 81*f05cddf9SRui Paulo wpabuf_put_data(proberesp, buf, pos - buf); 82*f05cddf9SRui Paulo } 83*f05cddf9SRui Paulo 84*f05cddf9SRui Paulo if (hapd->wps_beacon_ie) { 85*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) < 86*f05cddf9SRui Paulo 0) 87*f05cddf9SRui Paulo goto fail; 88*f05cddf9SRui Paulo wpabuf_put_buf(beacon, hapd->wps_beacon_ie); 89*f05cddf9SRui Paulo } 90*f05cddf9SRui Paulo 91*f05cddf9SRui Paulo if (hapd->wps_probe_resp_ie) { 92*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, 93*f05cddf9SRui Paulo wpabuf_len(hapd->wps_probe_resp_ie)) < 0) 94*f05cddf9SRui Paulo goto fail; 95*f05cddf9SRui Paulo wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie); 96*f05cddf9SRui Paulo } 97*f05cddf9SRui Paulo 98*f05cddf9SRui Paulo #ifdef CONFIG_P2P 99*f05cddf9SRui Paulo if (hapd->p2p_beacon_ie) { 100*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) < 101*f05cddf9SRui Paulo 0) 102*f05cddf9SRui Paulo goto fail; 103*f05cddf9SRui Paulo wpabuf_put_buf(beacon, hapd->p2p_beacon_ie); 104*f05cddf9SRui Paulo } 105*f05cddf9SRui Paulo 106*f05cddf9SRui Paulo if (hapd->p2p_probe_resp_ie) { 107*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, 108*f05cddf9SRui Paulo wpabuf_len(hapd->p2p_probe_resp_ie)) < 0) 109*f05cddf9SRui Paulo goto fail; 110*f05cddf9SRui Paulo wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie); 111*f05cddf9SRui Paulo } 112*f05cddf9SRui Paulo #endif /* CONFIG_P2P */ 113*f05cddf9SRui Paulo 114*f05cddf9SRui Paulo #ifdef CONFIG_P2P_MANAGER 115*f05cddf9SRui Paulo if (hapd->conf->p2p & P2P_MANAGE) { 116*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, 100) == 0) { 117*f05cddf9SRui Paulo u8 *start, *p; 118*f05cddf9SRui Paulo start = wpabuf_put(beacon, 0); 119*f05cddf9SRui Paulo p = hostapd_eid_p2p_manage(hapd, start); 120*f05cddf9SRui Paulo wpabuf_put(beacon, p - start); 121*f05cddf9SRui Paulo } 122*f05cddf9SRui Paulo 123*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, 100) == 0) { 124*f05cddf9SRui Paulo u8 *start, *p; 125*f05cddf9SRui Paulo start = wpabuf_put(proberesp, 0); 126*f05cddf9SRui Paulo p = hostapd_eid_p2p_manage(hapd, start); 127*f05cddf9SRui Paulo wpabuf_put(proberesp, p - start); 128*f05cddf9SRui Paulo } 129*f05cddf9SRui Paulo } 130*f05cddf9SRui Paulo #endif /* CONFIG_P2P_MANAGER */ 131*f05cddf9SRui Paulo 132*f05cddf9SRui Paulo #ifdef CONFIG_WPS2 133*f05cddf9SRui Paulo if (hapd->conf->wps_state) { 134*f05cddf9SRui Paulo struct wpabuf *a = wps_build_assoc_resp_ie(); 135*f05cddf9SRui Paulo if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0) 136*f05cddf9SRui Paulo wpabuf_put_buf(assocresp, a); 137*f05cddf9SRui Paulo wpabuf_free(a); 138*f05cddf9SRui Paulo } 139*f05cddf9SRui Paulo #endif /* CONFIG_WPS2 */ 140*f05cddf9SRui Paulo 141*f05cddf9SRui Paulo #ifdef CONFIG_P2P_MANAGER 142*f05cddf9SRui Paulo if (hapd->conf->p2p & P2P_MANAGE) { 143*f05cddf9SRui Paulo if (wpabuf_resize(&assocresp, 100) == 0) { 144*f05cddf9SRui Paulo u8 *start, *p; 145*f05cddf9SRui Paulo start = wpabuf_put(assocresp, 0); 146*f05cddf9SRui Paulo p = hostapd_eid_p2p_manage(hapd, start); 147*f05cddf9SRui Paulo wpabuf_put(assocresp, p - start); 148*f05cddf9SRui Paulo } 149*f05cddf9SRui Paulo } 150*f05cddf9SRui Paulo #endif /* CONFIG_P2P_MANAGER */ 151*f05cddf9SRui Paulo 152*f05cddf9SRui Paulo #ifdef CONFIG_WIFI_DISPLAY 153*f05cddf9SRui Paulo if (hapd->p2p_group) { 154*f05cddf9SRui Paulo struct wpabuf *a; 155*f05cddf9SRui Paulo a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS); 156*f05cddf9SRui Paulo if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0) 157*f05cddf9SRui Paulo wpabuf_put_buf(assocresp, a); 158*f05cddf9SRui Paulo wpabuf_free(a); 159*f05cddf9SRui Paulo } 160*f05cddf9SRui Paulo #endif /* CONFIG_WIFI_DISPLAY */ 161*f05cddf9SRui Paulo 162*f05cddf9SRui Paulo #ifdef CONFIG_HS20 163*f05cddf9SRui Paulo pos = buf; 164*f05cddf9SRui Paulo pos = hostapd_eid_hs20_indication(hapd, pos); 165*f05cddf9SRui Paulo if (pos != buf) { 166*f05cddf9SRui Paulo if (wpabuf_resize(&beacon, pos - buf) != 0) 167*f05cddf9SRui Paulo goto fail; 168*f05cddf9SRui Paulo wpabuf_put_data(beacon, buf, pos - buf); 169*f05cddf9SRui Paulo 170*f05cddf9SRui Paulo if (wpabuf_resize(&proberesp, pos - buf) != 0) 171*f05cddf9SRui Paulo goto fail; 172*f05cddf9SRui Paulo wpabuf_put_data(proberesp, buf, pos - buf); 173*f05cddf9SRui Paulo } 174*f05cddf9SRui Paulo #endif /* CONFIG_HS20 */ 175*f05cddf9SRui Paulo 176*f05cddf9SRui Paulo *beacon_ret = beacon; 177*f05cddf9SRui Paulo *proberesp_ret = proberesp; 178*f05cddf9SRui Paulo *assocresp_ret = assocresp; 179*f05cddf9SRui Paulo 180*f05cddf9SRui Paulo return 0; 181*f05cddf9SRui Paulo 182*f05cddf9SRui Paulo fail: 183*f05cddf9SRui Paulo wpabuf_free(beacon); 184*f05cddf9SRui Paulo wpabuf_free(proberesp); 185*f05cddf9SRui Paulo wpabuf_free(assocresp); 186*f05cddf9SRui Paulo return -1; 187*f05cddf9SRui Paulo } 188*f05cddf9SRui Paulo 189*f05cddf9SRui Paulo 190*f05cddf9SRui Paulo void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, 191*f05cddf9SRui Paulo struct wpabuf *beacon, 192*f05cddf9SRui Paulo struct wpabuf *proberesp, 193*f05cddf9SRui Paulo struct wpabuf *assocresp) 194*f05cddf9SRui Paulo { 195*f05cddf9SRui Paulo wpabuf_free(beacon); 196*f05cddf9SRui Paulo wpabuf_free(proberesp); 197*f05cddf9SRui Paulo wpabuf_free(assocresp); 198*f05cddf9SRui Paulo } 199*f05cddf9SRui Paulo 200*f05cddf9SRui Paulo 201*f05cddf9SRui Paulo int hostapd_set_ap_wps_ie(struct hostapd_data *hapd) 202*f05cddf9SRui Paulo { 203*f05cddf9SRui Paulo struct wpabuf *beacon, *proberesp, *assocresp; 204e28a4053SRui Paulo int ret; 205e28a4053SRui Paulo 206e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL) 207e28a4053SRui Paulo return 0; 208e28a4053SRui Paulo 209*f05cddf9SRui Paulo if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) < 210*f05cddf9SRui Paulo 0) 211*f05cddf9SRui Paulo return -1; 212e28a4053SRui Paulo 213*f05cddf9SRui Paulo ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp, 214*f05cddf9SRui Paulo assocresp); 215*f05cddf9SRui Paulo 216*f05cddf9SRui Paulo hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp); 217e28a4053SRui Paulo 218e28a4053SRui Paulo return ret; 219e28a4053SRui Paulo } 220e28a4053SRui Paulo 221e28a4053SRui Paulo 222*f05cddf9SRui Paulo int hostapd_set_authorized(struct hostapd_data *hapd, 223e28a4053SRui Paulo struct sta_info *sta, int authorized) 224e28a4053SRui Paulo { 225e28a4053SRui Paulo if (authorized) { 226e28a4053SRui Paulo return hostapd_sta_set_flags(hapd, sta->addr, 227e28a4053SRui Paulo hostapd_sta_flags_to_drv( 228e28a4053SRui Paulo sta->flags), 229e28a4053SRui Paulo WPA_STA_AUTHORIZED, ~0); 230e28a4053SRui Paulo } 231e28a4053SRui Paulo 232e28a4053SRui Paulo return hostapd_sta_set_flags(hapd, sta->addr, 233e28a4053SRui Paulo hostapd_sta_flags_to_drv(sta->flags), 234e28a4053SRui Paulo 0, ~WPA_STA_AUTHORIZED); 235e28a4053SRui Paulo } 236e28a4053SRui Paulo 237e28a4053SRui Paulo 238*f05cddf9SRui Paulo int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta) 239e28a4053SRui Paulo { 240e28a4053SRui Paulo int set_flags, total_flags, flags_and, flags_or; 241e28a4053SRui Paulo total_flags = hostapd_sta_flags_to_drv(sta->flags); 242e28a4053SRui Paulo set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP; 243e28a4053SRui Paulo if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 244e28a4053SRui Paulo sta->auth_alg == WLAN_AUTH_FT) && 245e28a4053SRui Paulo sta->flags & WLAN_STA_AUTHORIZED) 246e28a4053SRui Paulo set_flags |= WPA_STA_AUTHORIZED; 247e28a4053SRui Paulo flags_or = total_flags & set_flags; 248e28a4053SRui Paulo flags_and = total_flags | ~set_flags; 249e28a4053SRui Paulo return hostapd_sta_set_flags(hapd, sta->addr, total_flags, 250e28a4053SRui Paulo flags_or, flags_and); 251e28a4053SRui Paulo } 252e28a4053SRui Paulo 253e28a4053SRui Paulo 254*f05cddf9SRui Paulo int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname, 255*f05cddf9SRui Paulo int enabled) 256e28a4053SRui Paulo { 257e28a4053SRui Paulo struct wpa_bss_params params; 258e28a4053SRui Paulo os_memset(¶ms, 0, sizeof(params)); 259e28a4053SRui Paulo params.ifname = ifname; 260e28a4053SRui Paulo params.enabled = enabled; 261e28a4053SRui Paulo if (enabled) { 262e28a4053SRui Paulo params.wpa = hapd->conf->wpa; 263e28a4053SRui Paulo params.ieee802_1x = hapd->conf->ieee802_1x; 264e28a4053SRui Paulo params.wpa_group = hapd->conf->wpa_group; 265e28a4053SRui Paulo params.wpa_pairwise = hapd->conf->wpa_pairwise; 266e28a4053SRui Paulo params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt; 267e28a4053SRui Paulo params.rsn_preauth = hapd->conf->rsn_preauth; 268*f05cddf9SRui Paulo #ifdef CONFIG_IEEE80211W 269*f05cddf9SRui Paulo params.ieee80211w = hapd->conf->ieee80211w; 270*f05cddf9SRui Paulo #endif /* CONFIG_IEEE80211W */ 271e28a4053SRui Paulo } 272e28a4053SRui Paulo return hostapd_set_ieee8021x(hapd, ¶ms); 273e28a4053SRui Paulo } 274e28a4053SRui Paulo 275e28a4053SRui Paulo 276*f05cddf9SRui Paulo int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname) 277e28a4053SRui Paulo { 278e28a4053SRui Paulo char force_ifname[IFNAMSIZ]; 279e28a4053SRui Paulo u8 if_addr[ETH_ALEN]; 280*f05cddf9SRui Paulo return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr, 281*f05cddf9SRui Paulo NULL, NULL, force_ifname, if_addr, NULL); 282e28a4053SRui Paulo } 283e28a4053SRui Paulo 284*f05cddf9SRui Paulo 285*f05cddf9SRui Paulo int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname) 286e28a4053SRui Paulo { 287e28a4053SRui Paulo return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname); 288e28a4053SRui Paulo } 289e28a4053SRui Paulo 290e28a4053SRui Paulo 291*f05cddf9SRui Paulo int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, int aid, 292*f05cddf9SRui Paulo int val) 293e28a4053SRui Paulo { 294*f05cddf9SRui Paulo const char *bridge = NULL; 295*f05cddf9SRui Paulo 296e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL) 297e28a4053SRui Paulo return 0; 298*f05cddf9SRui Paulo if (hapd->conf->wds_bridge[0]) 299*f05cddf9SRui Paulo bridge = hapd->conf->wds_bridge; 300*f05cddf9SRui Paulo else if (hapd->conf->bridge[0]) 301*f05cddf9SRui Paulo bridge = hapd->conf->bridge; 302*f05cddf9SRui Paulo return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val, 303*f05cddf9SRui Paulo bridge); 304e28a4053SRui Paulo } 305e28a4053SRui Paulo 306e28a4053SRui Paulo 307*f05cddf9SRui Paulo int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr, 308*f05cddf9SRui Paulo u16 auth_alg) 309e28a4053SRui Paulo { 310*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL) 311e28a4053SRui Paulo return 0; 312*f05cddf9SRui Paulo return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg); 313e28a4053SRui Paulo } 314e28a4053SRui Paulo 315e28a4053SRui Paulo 316*f05cddf9SRui Paulo int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr, 317*f05cddf9SRui Paulo u16 seq, u16 status, const u8 *ie, size_t len) 318e28a4053SRui Paulo { 319*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->sta_auth == NULL) 320e28a4053SRui Paulo return 0; 321*f05cddf9SRui Paulo return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr, 322*f05cddf9SRui Paulo seq, status, ie, len); 323e28a4053SRui Paulo } 324e28a4053SRui Paulo 325e28a4053SRui Paulo 326*f05cddf9SRui Paulo int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr, 327*f05cddf9SRui Paulo int reassoc, u16 status, const u8 *ie, size_t len) 328e28a4053SRui Paulo { 329*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL) 330e28a4053SRui Paulo return 0; 331*f05cddf9SRui Paulo return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr, 332*f05cddf9SRui Paulo reassoc, status, ie, len); 333e28a4053SRui Paulo } 334e28a4053SRui Paulo 335e28a4053SRui Paulo 336*f05cddf9SRui Paulo int hostapd_sta_add(struct hostapd_data *hapd, 337e28a4053SRui Paulo const u8 *addr, u16 aid, u16 capability, 338e28a4053SRui Paulo const u8 *supp_rates, size_t supp_rates_len, 339e28a4053SRui Paulo u16 listen_interval, 340*f05cddf9SRui Paulo const struct ieee80211_ht_capabilities *ht_capab, 341*f05cddf9SRui Paulo u32 flags, u8 qosinfo) 342e28a4053SRui Paulo { 343e28a4053SRui Paulo struct hostapd_sta_add_params params; 344e28a4053SRui Paulo 345e28a4053SRui Paulo if (hapd->driver == NULL) 346e28a4053SRui Paulo return 0; 347e28a4053SRui Paulo if (hapd->driver->sta_add == NULL) 348e28a4053SRui Paulo return 0; 349e28a4053SRui Paulo 350e28a4053SRui Paulo os_memset(¶ms, 0, sizeof(params)); 351e28a4053SRui Paulo params.addr = addr; 352e28a4053SRui Paulo params.aid = aid; 353e28a4053SRui Paulo params.capability = capability; 354e28a4053SRui Paulo params.supp_rates = supp_rates; 355e28a4053SRui Paulo params.supp_rates_len = supp_rates_len; 356e28a4053SRui Paulo params.listen_interval = listen_interval; 357e28a4053SRui Paulo params.ht_capabilities = ht_capab; 358*f05cddf9SRui Paulo params.flags = hostapd_sta_flags_to_drv(flags); 359*f05cddf9SRui Paulo params.qosinfo = qosinfo; 360e28a4053SRui Paulo return hapd->driver->sta_add(hapd->drv_priv, ¶ms); 361e28a4053SRui Paulo } 362e28a4053SRui Paulo 363e28a4053SRui Paulo 364*f05cddf9SRui Paulo int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr, 365*f05cddf9SRui Paulo u8 *tspec_ie, size_t tspec_ielen) 366e28a4053SRui Paulo { 367*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->add_tspec == NULL) 368e28a4053SRui Paulo return 0; 369*f05cddf9SRui Paulo return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie, 370*f05cddf9SRui Paulo tspec_ielen); 371e28a4053SRui Paulo } 372e28a4053SRui Paulo 373e28a4053SRui Paulo 374e28a4053SRui Paulo int hostapd_set_privacy(struct hostapd_data *hapd, int enabled) 375e28a4053SRui Paulo { 376e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_privacy == NULL) 377e28a4053SRui Paulo return 0; 378e28a4053SRui Paulo return hapd->driver->set_privacy(hapd->drv_priv, enabled); 379e28a4053SRui Paulo } 380e28a4053SRui Paulo 381e28a4053SRui Paulo 382e28a4053SRui Paulo int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem, 383e28a4053SRui Paulo size_t elem_len) 384e28a4053SRui Paulo { 385e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL) 386e28a4053SRui Paulo return 0; 387e28a4053SRui Paulo return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len); 388e28a4053SRui Paulo } 389e28a4053SRui Paulo 390e28a4053SRui Paulo 391e28a4053SRui Paulo int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len) 392e28a4053SRui Paulo { 393e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL) 394e28a4053SRui Paulo return 0; 395e28a4053SRui Paulo return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len); 396e28a4053SRui Paulo } 397e28a4053SRui Paulo 398e28a4053SRui Paulo 399e28a4053SRui Paulo int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len) 400e28a4053SRui Paulo { 401e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL) 402e28a4053SRui Paulo return 0; 403e28a4053SRui Paulo return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len); 404e28a4053SRui Paulo } 405e28a4053SRui Paulo 406e28a4053SRui Paulo 407e28a4053SRui Paulo int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type, 408e28a4053SRui Paulo const char *ifname, const u8 *addr, void *bss_ctx, 409*f05cddf9SRui Paulo void **drv_priv, char *force_ifname, u8 *if_addr, 410*f05cddf9SRui Paulo const char *bridge) 411e28a4053SRui Paulo { 412e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->if_add == NULL) 413e28a4053SRui Paulo return -1; 414e28a4053SRui Paulo return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr, 415*f05cddf9SRui Paulo bss_ctx, drv_priv, force_ifname, if_addr, 416*f05cddf9SRui Paulo bridge); 417e28a4053SRui Paulo } 418e28a4053SRui Paulo 419e28a4053SRui Paulo 420e28a4053SRui Paulo int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, 421e28a4053SRui Paulo const char *ifname) 422e28a4053SRui Paulo { 423e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->if_remove == NULL) 424e28a4053SRui Paulo return -1; 425e28a4053SRui Paulo return hapd->driver->if_remove(hapd->drv_priv, type, ifname); 426e28a4053SRui Paulo } 427e28a4053SRui Paulo 428e28a4053SRui Paulo 429e28a4053SRui Paulo int hostapd_set_ieee8021x(struct hostapd_data *hapd, 430e28a4053SRui Paulo struct wpa_bss_params *params) 431e28a4053SRui Paulo { 432e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL) 433e28a4053SRui Paulo return 0; 434e28a4053SRui Paulo return hapd->driver->set_ieee8021x(hapd->drv_priv, params); 435e28a4053SRui Paulo } 436e28a4053SRui Paulo 437e28a4053SRui Paulo 438e28a4053SRui Paulo int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd, 439e28a4053SRui Paulo const u8 *addr, int idx, u8 *seq) 440e28a4053SRui Paulo { 441e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL) 442e28a4053SRui Paulo return 0; 443e28a4053SRui Paulo return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx, 444e28a4053SRui Paulo seq); 445e28a4053SRui Paulo } 446e28a4053SRui Paulo 447e28a4053SRui Paulo 448e28a4053SRui Paulo int hostapd_flush(struct hostapd_data *hapd) 449e28a4053SRui Paulo { 450e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->flush == NULL) 451e28a4053SRui Paulo return 0; 452e28a4053SRui Paulo return hapd->driver->flush(hapd->drv_priv); 453e28a4053SRui Paulo } 454e28a4053SRui Paulo 455e28a4053SRui Paulo 456e28a4053SRui Paulo int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq, 457e28a4053SRui Paulo int channel, int ht_enabled, int sec_channel_offset) 458e28a4053SRui Paulo { 459e28a4053SRui Paulo struct hostapd_freq_params data; 460e28a4053SRui Paulo if (hapd->driver == NULL) 461e28a4053SRui Paulo return 0; 462e28a4053SRui Paulo if (hapd->driver->set_freq == NULL) 463e28a4053SRui Paulo return 0; 464e28a4053SRui Paulo os_memset(&data, 0, sizeof(data)); 465e28a4053SRui Paulo data.mode = mode; 466e28a4053SRui Paulo data.freq = freq; 467e28a4053SRui Paulo data.channel = channel; 468e28a4053SRui Paulo data.ht_enabled = ht_enabled; 469e28a4053SRui Paulo data.sec_channel_offset = sec_channel_offset; 470e28a4053SRui Paulo return hapd->driver->set_freq(hapd->drv_priv, &data); 471e28a4053SRui Paulo } 472e28a4053SRui Paulo 473e28a4053SRui Paulo int hostapd_set_rts(struct hostapd_data *hapd, int rts) 474e28a4053SRui Paulo { 475e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_rts == NULL) 476e28a4053SRui Paulo return 0; 477e28a4053SRui Paulo return hapd->driver->set_rts(hapd->drv_priv, rts); 478e28a4053SRui Paulo } 479e28a4053SRui Paulo 480e28a4053SRui Paulo 481e28a4053SRui Paulo int hostapd_set_frag(struct hostapd_data *hapd, int frag) 482e28a4053SRui Paulo { 483e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_frag == NULL) 484e28a4053SRui Paulo return 0; 485e28a4053SRui Paulo return hapd->driver->set_frag(hapd->drv_priv, frag); 486e28a4053SRui Paulo } 487e28a4053SRui Paulo 488e28a4053SRui Paulo 489e28a4053SRui Paulo int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, 490e28a4053SRui Paulo int total_flags, int flags_or, int flags_and) 491e28a4053SRui Paulo { 492e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL) 493e28a4053SRui Paulo return 0; 494e28a4053SRui Paulo return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags, 495e28a4053SRui Paulo flags_or, flags_and); 496e28a4053SRui Paulo } 497e28a4053SRui Paulo 498e28a4053SRui Paulo 499e28a4053SRui Paulo int hostapd_set_country(struct hostapd_data *hapd, const char *country) 500e28a4053SRui Paulo { 501e28a4053SRui Paulo if (hapd->driver == NULL || 502e28a4053SRui Paulo hapd->driver->set_country == NULL) 503e28a4053SRui Paulo return 0; 504e28a4053SRui Paulo return hapd->driver->set_country(hapd->drv_priv, country); 505e28a4053SRui Paulo } 506e28a4053SRui Paulo 507e28a4053SRui Paulo 508e28a4053SRui Paulo int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs, 509e28a4053SRui Paulo int cw_min, int cw_max, int burst_time) 510e28a4053SRui Paulo { 511e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL) 512e28a4053SRui Paulo return 0; 513e28a4053SRui Paulo return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs, 514e28a4053SRui Paulo cw_min, cw_max, burst_time); 515e28a4053SRui Paulo } 516e28a4053SRui Paulo 517e28a4053SRui Paulo 518e28a4053SRui Paulo struct hostapd_hw_modes * 519e28a4053SRui Paulo hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes, 520e28a4053SRui Paulo u16 *flags) 521e28a4053SRui Paulo { 522e28a4053SRui Paulo if (hapd->driver == NULL || 523e28a4053SRui Paulo hapd->driver->get_hw_feature_data == NULL) 524e28a4053SRui Paulo return NULL; 525e28a4053SRui Paulo return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes, 526e28a4053SRui Paulo flags); 527e28a4053SRui Paulo } 528e28a4053SRui Paulo 529e28a4053SRui Paulo 530e28a4053SRui Paulo int hostapd_driver_commit(struct hostapd_data *hapd) 531e28a4053SRui Paulo { 532e28a4053SRui Paulo if (hapd->driver == NULL || hapd->driver->commit == NULL) 533e28a4053SRui Paulo return 0; 534e28a4053SRui Paulo return hapd->driver->commit(hapd->drv_priv); 535e28a4053SRui Paulo } 536e28a4053SRui Paulo 537e28a4053SRui Paulo 538e28a4053SRui Paulo int hostapd_drv_none(struct hostapd_data *hapd) 539e28a4053SRui Paulo { 540e28a4053SRui Paulo return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0; 541e28a4053SRui Paulo } 542e28a4053SRui Paulo 543e28a4053SRui Paulo 544e28a4053SRui Paulo int hostapd_driver_scan(struct hostapd_data *hapd, 545e28a4053SRui Paulo struct wpa_driver_scan_params *params) 546e28a4053SRui Paulo { 547e28a4053SRui Paulo if (hapd->driver && hapd->driver->scan2) 548e28a4053SRui Paulo return hapd->driver->scan2(hapd->drv_priv, params); 549e28a4053SRui Paulo return -1; 550e28a4053SRui Paulo } 551e28a4053SRui Paulo 552e28a4053SRui Paulo 553e28a4053SRui Paulo struct wpa_scan_results * hostapd_driver_get_scan_results( 554e28a4053SRui Paulo struct hostapd_data *hapd) 555e28a4053SRui Paulo { 556e28a4053SRui Paulo if (hapd->driver && hapd->driver->get_scan_results2) 557e28a4053SRui Paulo return hapd->driver->get_scan_results2(hapd->drv_priv); 558e28a4053SRui Paulo return NULL; 559e28a4053SRui Paulo } 560*f05cddf9SRui Paulo 561*f05cddf9SRui Paulo 562*f05cddf9SRui Paulo int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start, 563*f05cddf9SRui Paulo int duration) 564*f05cddf9SRui Paulo { 565*f05cddf9SRui Paulo if (hapd->driver && hapd->driver->set_noa) 566*f05cddf9SRui Paulo return hapd->driver->set_noa(hapd->drv_priv, count, start, 567*f05cddf9SRui Paulo duration); 568*f05cddf9SRui Paulo return -1; 569*f05cddf9SRui Paulo } 570*f05cddf9SRui Paulo 571*f05cddf9SRui Paulo 572*f05cddf9SRui Paulo int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd, 573*f05cddf9SRui Paulo enum wpa_alg alg, const u8 *addr, 574*f05cddf9SRui Paulo int key_idx, int set_tx, 575*f05cddf9SRui Paulo const u8 *seq, size_t seq_len, 576*f05cddf9SRui Paulo const u8 *key, size_t key_len) 577*f05cddf9SRui Paulo { 578*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->set_key == NULL) 579*f05cddf9SRui Paulo return 0; 580*f05cddf9SRui Paulo return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr, 581*f05cddf9SRui Paulo key_idx, set_tx, seq, seq_len, key, 582*f05cddf9SRui Paulo key_len); 583*f05cddf9SRui Paulo } 584*f05cddf9SRui Paulo 585*f05cddf9SRui Paulo 586*f05cddf9SRui Paulo int hostapd_drv_send_mlme(struct hostapd_data *hapd, 587*f05cddf9SRui Paulo const void *msg, size_t len, int noack) 588*f05cddf9SRui Paulo { 589*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->send_mlme == NULL) 590*f05cddf9SRui Paulo return 0; 591*f05cddf9SRui Paulo return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack); 592*f05cddf9SRui Paulo } 593*f05cddf9SRui Paulo 594*f05cddf9SRui Paulo 595*f05cddf9SRui Paulo int hostapd_drv_sta_deauth(struct hostapd_data *hapd, 596*f05cddf9SRui Paulo const u8 *addr, int reason) 597*f05cddf9SRui Paulo { 598*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL) 599*f05cddf9SRui Paulo return 0; 600*f05cddf9SRui Paulo return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr, 601*f05cddf9SRui Paulo reason); 602*f05cddf9SRui Paulo } 603*f05cddf9SRui Paulo 604*f05cddf9SRui Paulo 605*f05cddf9SRui Paulo int hostapd_drv_sta_disassoc(struct hostapd_data *hapd, 606*f05cddf9SRui Paulo const u8 *addr, int reason) 607*f05cddf9SRui Paulo { 608*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL) 609*f05cddf9SRui Paulo return 0; 610*f05cddf9SRui Paulo return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr, 611*f05cddf9SRui Paulo reason); 612*f05cddf9SRui Paulo } 613*f05cddf9SRui Paulo 614*f05cddf9SRui Paulo 615*f05cddf9SRui Paulo int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper, 616*f05cddf9SRui Paulo const u8 *peer, u8 *buf, u16 *buf_len) 617*f05cddf9SRui Paulo { 618*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL) 619*f05cddf9SRui Paulo return 0; 620*f05cddf9SRui Paulo return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf, 621*f05cddf9SRui Paulo buf_len); 622*f05cddf9SRui Paulo } 623*f05cddf9SRui Paulo 624*f05cddf9SRui Paulo 625*f05cddf9SRui Paulo int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq, 626*f05cddf9SRui Paulo unsigned int wait, const u8 *dst, const u8 *data, 627*f05cddf9SRui Paulo size_t len) 628*f05cddf9SRui Paulo { 629*f05cddf9SRui Paulo if (hapd->driver == NULL || hapd->driver->send_action == NULL) 630*f05cddf9SRui Paulo return 0; 631*f05cddf9SRui Paulo return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst, 632*f05cddf9SRui Paulo hapd->own_addr, hapd->own_addr, data, 633*f05cddf9SRui Paulo len, 0); 634*f05cddf9SRui Paulo } 635