1/* 2 * hostapd - Driver operations 3 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include "utils/includes.h" 16 17#include "utils/common.h" 18#include "drivers/driver.h" 19#include "common/ieee802_11_defs.h" 20#include "hostapd.h" 21#include "ieee802_11.h" 22#include "sta_info.h" 23#include "ap_config.h" 24#include "ap_drv_ops.h" 25 26 27static int hostapd_sta_flags_to_drv(int flags) 28{ 29 int res = 0; 30 if (flags & WLAN_STA_AUTHORIZED) 31 res |= WPA_STA_AUTHORIZED; 32 if (flags & WLAN_STA_WMM) 33 res |= WPA_STA_WMM; 34 if (flags & WLAN_STA_SHORT_PREAMBLE) 35 res |= WPA_STA_SHORT_PREAMBLE; 36 if (flags & WLAN_STA_MFP) 37 res |= WPA_STA_MFP; 38 return res; 39} 40 41 42static int hostapd_set_ap_wps_ie(struct hostapd_data *hapd) 43{ 44 struct wpabuf *beacon, *proberesp; 45 int ret; 46 47 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL) 48 return 0; 49 50 beacon = hapd->wps_beacon_ie; 51 proberesp = hapd->wps_probe_resp_ie; 52 53 ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp); 54 55 return ret; 56} 57 58 59static int hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg, 60 size_t len) 61{ 62 if (hapd->driver == NULL || hapd->driver->send_mlme == NULL) 63 return 0; 64 return hapd->driver->send_mlme(hapd->drv_priv, msg, len); 65} 66 67 68static int hostapd_send_eapol(struct hostapd_data *hapd, const u8 *addr, 69 const u8 *data, size_t data_len, int encrypt) 70{ 71 if (hapd->driver == NULL || hapd->driver->hapd_send_eapol == NULL) 72 return 0; 73 return hapd->driver->hapd_send_eapol(hapd->drv_priv, addr, data, 74 data_len, encrypt, 75 hapd->own_addr); 76} 77 78 79static int hostapd_set_authorized(struct hostapd_data *hapd, 80 struct sta_info *sta, int authorized) 81{ 82 if (authorized) { 83 return hostapd_sta_set_flags(hapd, sta->addr, 84 hostapd_sta_flags_to_drv( 85 sta->flags), 86 WPA_STA_AUTHORIZED, ~0); 87 } 88 89 return hostapd_sta_set_flags(hapd, sta->addr, 90 hostapd_sta_flags_to_drv(sta->flags), 91 0, ~WPA_STA_AUTHORIZED); 92} 93 94 95static int hostapd_set_key(const char *ifname, struct hostapd_data *hapd, 96 enum wpa_alg alg, const u8 *addr, int key_idx, 97 int set_tx, const u8 *seq, size_t seq_len, 98 const u8 *key, size_t key_len) 99{ 100 if (hapd->driver == NULL || hapd->driver->set_key == NULL) 101 return 0; 102 return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr, 103 key_idx, set_tx, seq, seq_len, key, 104 key_len); 105} 106 107 108static int hostapd_read_sta_data(struct hostapd_data *hapd, 109 struct hostap_sta_driver_data *data, 110 const u8 *addr) 111{ 112 if (hapd->driver == NULL || hapd->driver->read_sta_data == NULL) 113 return -1; 114 return hapd->driver->read_sta_data(hapd->drv_priv, data, addr); 115} 116 117 118static int hostapd_sta_clear_stats(struct hostapd_data *hapd, const u8 *addr) 119{ 120 if (hapd->driver == NULL || hapd->driver->sta_clear_stats == NULL) 121 return 0; 122 return hapd->driver->sta_clear_stats(hapd->drv_priv, addr); 123} 124 125 126static int hostapd_set_sta_flags(struct hostapd_data *hapd, 127 struct sta_info *sta) 128{ 129 int set_flags, total_flags, flags_and, flags_or; 130 total_flags = hostapd_sta_flags_to_drv(sta->flags); 131 set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP; 132 if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) || 133 sta->auth_alg == WLAN_AUTH_FT) && 134 sta->flags & WLAN_STA_AUTHORIZED) 135 set_flags |= WPA_STA_AUTHORIZED; 136 flags_or = total_flags & set_flags; 137 flags_and = total_flags | ~set_flags; 138 return hostapd_sta_set_flags(hapd, sta->addr, total_flags, 139 flags_or, flags_and); 140} 141 142 143static int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, 144 const char *ifname, int enabled) 145{ 146 struct wpa_bss_params params; 147 os_memset(¶ms, 0, sizeof(params)); 148 params.ifname = ifname; 149 params.enabled = enabled; 150 if (enabled) { 151 params.wpa = hapd->conf->wpa; 152 params.ieee802_1x = hapd->conf->ieee802_1x; 153 params.wpa_group = hapd->conf->wpa_group; 154 params.wpa_pairwise = hapd->conf->wpa_pairwise; 155 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt; 156 params.rsn_preauth = hapd->conf->rsn_preauth; 157 } 158 return hostapd_set_ieee8021x(hapd, ¶ms); 159} 160 161 162static int hostapd_set_radius_acl_auth(struct hostapd_data *hapd, 163 const u8 *mac, int accepted, 164 u32 session_timeout) 165{ 166 if (hapd->driver == NULL || hapd->driver->set_radius_acl_auth == NULL) 167 return 0; 168 return hapd->driver->set_radius_acl_auth(hapd->drv_priv, mac, accepted, 169 session_timeout); 170} 171 172 173static int hostapd_set_radius_acl_expire(struct hostapd_data *hapd, 174 const u8 *mac) 175{ 176 if (hapd->driver == NULL || 177 hapd->driver->set_radius_acl_expire == NULL) 178 return 0; 179 return hapd->driver->set_radius_acl_expire(hapd->drv_priv, mac); 180} 181 182 183static int hostapd_set_bss_params(struct hostapd_data *hapd, 184 int use_protection) 185{ 186 int ret = 0; 187 int preamble; 188#ifdef CONFIG_IEEE80211N 189 u8 buf[60], *ht_capab, *ht_oper, *pos; 190 191 pos = buf; 192 ht_capab = pos; 193 pos = hostapd_eid_ht_capabilities(hapd, pos); 194 ht_oper = pos; 195 pos = hostapd_eid_ht_operation(hapd, pos); 196 if (pos > ht_oper && ht_oper > ht_capab && 197 hostapd_set_ht_params(hapd, ht_capab + 2, ht_capab[1], 198 ht_oper + 2, ht_oper[1])) { 199 wpa_printf(MSG_ERROR, "Could not set HT capabilities " 200 "for kernel driver"); 201 ret = -1; 202 } 203 204#endif /* CONFIG_IEEE80211N */ 205 206 if (hostapd_set_cts_protect(hapd, use_protection)) { 207 wpa_printf(MSG_ERROR, "Failed to set CTS protect in kernel " 208 "driver"); 209 ret = -1; 210 } 211 212 if (hapd->iface->current_mode && 213 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 214 hostapd_set_short_slot_time(hapd, 215 hapd->iface->num_sta_no_short_slot_time 216 > 0 ? 0 : 1)) { 217 wpa_printf(MSG_ERROR, "Failed to set Short Slot Time option " 218 "in kernel driver"); 219 ret = -1; 220 } 221 222 if (hapd->iface->num_sta_no_short_preamble == 0 && 223 hapd->iconf->preamble == SHORT_PREAMBLE) 224 preamble = SHORT_PREAMBLE; 225 else 226 preamble = LONG_PREAMBLE; 227 if (hostapd_set_preamble(hapd, preamble)) { 228 wpa_printf(MSG_ERROR, "Could not set preamble for kernel " 229 "driver"); 230 ret = -1; 231 } 232 233 return ret; 234} 235 236 237static int hostapd_set_beacon(struct hostapd_data *hapd, 238 const u8 *head, size_t head_len, 239 const u8 *tail, size_t tail_len, int dtim_period, 240 int beacon_int) 241{ 242 if (hapd->driver == NULL || hapd->driver->set_beacon == NULL) 243 return 0; 244 return hapd->driver->set_beacon(hapd->drv_priv, 245 head, head_len, tail, tail_len, 246 dtim_period, beacon_int); 247} 248 249 250static int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname) 251{ 252 char force_ifname[IFNAMSIZ]; 253 u8 if_addr[ETH_ALEN]; 254 return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL, NULL, 255 force_ifname, if_addr); 256} 257 258static int hostapd_vlan_if_remove(struct hostapd_data *hapd, 259 const char *ifname) 260{ 261 return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname); 262} 263 264 265static int hostapd_set_wds_sta(struct hostapd_data *hapd, const u8 *addr, 266 int aid, int val) 267{ 268 if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL) 269 return 0; 270 return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val); 271} 272 273 274static int hostapd_set_sta_vlan(const char *ifname, struct hostapd_data *hapd, 275 const u8 *addr, int vlan_id) 276{ 277 if (hapd->driver == NULL || hapd->driver->set_sta_vlan == NULL) 278 return 0; 279 return hapd->driver->set_sta_vlan(hapd->drv_priv, addr, ifname, 280 vlan_id); 281} 282 283 284static int hostapd_get_inact_sec(struct hostapd_data *hapd, const u8 *addr) 285{ 286 if (hapd->driver == NULL || hapd->driver->get_inact_sec == NULL) 287 return 0; 288 return hapd->driver->get_inact_sec(hapd->drv_priv, addr); 289} 290 291 292static int hostapd_sta_deauth(struct hostapd_data *hapd, const u8 *addr, 293 int reason) 294{ 295 if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL) 296 return 0; 297 return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr, 298 reason); 299} 300 301 302static int hostapd_sta_disassoc(struct hostapd_data *hapd, const u8 *addr, 303 int reason) 304{ 305 if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL) 306 return 0; 307 return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr, 308 reason); 309} 310 311 312static int hostapd_sta_add(struct hostapd_data *hapd, 313 const u8 *addr, u16 aid, u16 capability, 314 const u8 *supp_rates, size_t supp_rates_len, 315 u16 listen_interval, 316 const struct ieee80211_ht_capabilities *ht_capab) 317{ 318 struct hostapd_sta_add_params params; 319 320 if (hapd->driver == NULL) 321 return 0; 322 if (hapd->driver->sta_add == NULL) 323 return 0; 324 325 os_memset(¶ms, 0, sizeof(params)); 326 params.addr = addr; 327 params.aid = aid; 328 params.capability = capability; 329 params.supp_rates = supp_rates; 330 params.supp_rates_len = supp_rates_len; 331 params.listen_interval = listen_interval; 332 params.ht_capabilities = ht_capab; 333 return hapd->driver->sta_add(hapd->drv_priv, ¶ms); 334} 335 336 337static int hostapd_sta_remove(struct hostapd_data *hapd, const u8 *addr) 338{ 339 if (hapd->driver == NULL || hapd->driver->sta_remove == NULL) 340 return 0; 341 return hapd->driver->sta_remove(hapd->drv_priv, addr); 342} 343 344 345static int hostapd_set_countermeasures(struct hostapd_data *hapd, int enabled) 346{ 347 if (hapd->driver == NULL || 348 hapd->driver->hapd_set_countermeasures == NULL) 349 return 0; 350 return hapd->driver->hapd_set_countermeasures(hapd->drv_priv, enabled); 351} 352 353 354void hostapd_set_driver_ops(struct hostapd_driver_ops *ops) 355{ 356 ops->set_ap_wps_ie = hostapd_set_ap_wps_ie; 357 ops->send_mgmt_frame = hostapd_send_mgmt_frame; 358 ops->send_eapol = hostapd_send_eapol; 359 ops->set_authorized = hostapd_set_authorized; 360 ops->set_key = hostapd_set_key; 361 ops->read_sta_data = hostapd_read_sta_data; 362 ops->sta_clear_stats = hostapd_sta_clear_stats; 363 ops->set_sta_flags = hostapd_set_sta_flags; 364 ops->set_drv_ieee8021x = hostapd_set_drv_ieee8021x; 365 ops->set_radius_acl_auth = hostapd_set_radius_acl_auth; 366 ops->set_radius_acl_expire = hostapd_set_radius_acl_expire; 367 ops->set_bss_params = hostapd_set_bss_params; 368 ops->set_beacon = hostapd_set_beacon; 369 ops->vlan_if_add = hostapd_vlan_if_add; 370 ops->vlan_if_remove = hostapd_vlan_if_remove; 371 ops->set_wds_sta = hostapd_set_wds_sta; 372 ops->set_sta_vlan = hostapd_set_sta_vlan; 373 ops->get_inact_sec = hostapd_get_inact_sec; 374 ops->sta_deauth = hostapd_sta_deauth; 375 ops->sta_disassoc = hostapd_sta_disassoc; 376 ops->sta_add = hostapd_sta_add; 377 ops->sta_remove = hostapd_sta_remove; 378 ops->set_countermeasures = hostapd_set_countermeasures; 379} 380 381 382int hostapd_set_privacy(struct hostapd_data *hapd, int enabled) 383{ 384 if (hapd->driver == NULL || hapd->driver->set_privacy == NULL) 385 return 0; 386 return hapd->driver->set_privacy(hapd->drv_priv, enabled); 387} 388 389 390int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem, 391 size_t elem_len) 392{ 393 if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL) 394 return 0; 395 return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len); 396} 397 398 399int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len) 400{ 401 if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL) 402 return 0; 403 return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len); 404} 405 406 407int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len) 408{ 409 if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL) 410 return 0; 411 return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len); 412} 413 414 415int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type, 416 const char *ifname, const u8 *addr, void *bss_ctx, 417 void **drv_priv, char *force_ifname, u8 *if_addr) 418{ 419 if (hapd->driver == NULL || hapd->driver->if_add == NULL) 420 return -1; 421 return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr, 422 bss_ctx, drv_priv, force_ifname, if_addr); 423} 424 425 426int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, 427 const char *ifname) 428{ 429 if (hapd->driver == NULL || hapd->driver->if_remove == NULL) 430 return -1; 431 return hapd->driver->if_remove(hapd->drv_priv, type, ifname); 432} 433 434 435int hostapd_set_ieee8021x(struct hostapd_data *hapd, 436 struct wpa_bss_params *params) 437{ 438 if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL) 439 return 0; 440 return hapd->driver->set_ieee8021x(hapd->drv_priv, params); 441} 442 443 444int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd, 445 const u8 *addr, int idx, u8 *seq) 446{ 447 if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL) 448 return 0; 449 return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx, 450 seq); 451} 452 453 454int hostapd_flush(struct hostapd_data *hapd) 455{ 456 if (hapd->driver == NULL || hapd->driver->flush == NULL) 457 return 0; 458 return hapd->driver->flush(hapd->drv_priv); 459} 460 461 462int hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq, 463 int channel, int ht_enabled, int sec_channel_offset) 464{ 465 struct hostapd_freq_params data; 466 if (hapd->driver == NULL) 467 return 0; 468 if (hapd->driver->set_freq == NULL) 469 return 0; 470 os_memset(&data, 0, sizeof(data)); 471 data.mode = mode; 472 data.freq = freq; 473 data.channel = channel; 474 data.ht_enabled = ht_enabled; 475 data.sec_channel_offset = sec_channel_offset; 476 return hapd->driver->set_freq(hapd->drv_priv, &data); 477} 478 479int hostapd_set_rts(struct hostapd_data *hapd, int rts) 480{ 481 if (hapd->driver == NULL || hapd->driver->set_rts == NULL) 482 return 0; 483 return hapd->driver->set_rts(hapd->drv_priv, rts); 484} 485 486 487int hostapd_set_frag(struct hostapd_data *hapd, int frag) 488{ 489 if (hapd->driver == NULL || hapd->driver->set_frag == NULL) 490 return 0; 491 return hapd->driver->set_frag(hapd->drv_priv, frag); 492} 493 494 495int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr, 496 int total_flags, int flags_or, int flags_and) 497{ 498 if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL) 499 return 0; 500 return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags, 501 flags_or, flags_and); 502} 503 504 505int hostapd_set_rate_sets(struct hostapd_data *hapd, int *supp_rates, 506 int *basic_rates, int mode) 507{ 508 if (hapd->driver == NULL || hapd->driver->set_rate_sets == NULL) 509 return 0; 510 return hapd->driver->set_rate_sets(hapd->drv_priv, supp_rates, 511 basic_rates, mode); 512} 513 514 515int hostapd_set_country(struct hostapd_data *hapd, const char *country) 516{ 517 if (hapd->driver == NULL || 518 hapd->driver->set_country == NULL) 519 return 0; 520 return hapd->driver->set_country(hapd->drv_priv, country); 521} 522 523 524int hostapd_set_cts_protect(struct hostapd_data *hapd, int value) 525{ 526 if (hapd->driver == NULL || hapd->driver->set_cts_protect == NULL) 527 return 0; 528 return hapd->driver->set_cts_protect(hapd->drv_priv, value); 529} 530 531 532int hostapd_set_preamble(struct hostapd_data *hapd, int value) 533{ 534 if (hapd->driver == NULL || hapd->driver->set_preamble == NULL) 535 return 0; 536 return hapd->driver->set_preamble(hapd->drv_priv, value); 537} 538 539 540int hostapd_set_short_slot_time(struct hostapd_data *hapd, int value) 541{ 542 if (hapd->driver == NULL || hapd->driver->set_short_slot_time == NULL) 543 return 0; 544 return hapd->driver->set_short_slot_time(hapd->drv_priv, value); 545} 546 547 548int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs, 549 int cw_min, int cw_max, int burst_time) 550{ 551 if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL) 552 return 0; 553 return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs, 554 cw_min, cw_max, burst_time); 555} 556 557 558int hostapd_valid_bss_mask(struct hostapd_data *hapd, const u8 *addr, 559 const u8 *mask) 560{ 561 if (hapd->driver == NULL || hapd->driver->valid_bss_mask == NULL) 562 return 1; 563 return hapd->driver->valid_bss_mask(hapd->drv_priv, addr, mask); 564} 565 566 567struct hostapd_hw_modes * 568hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes, 569 u16 *flags) 570{ 571 if (hapd->driver == NULL || 572 hapd->driver->get_hw_feature_data == NULL) 573 return NULL; 574 return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes, 575 flags); 576} 577 578 579int hostapd_driver_commit(struct hostapd_data *hapd) 580{ 581 if (hapd->driver == NULL || hapd->driver->commit == NULL) 582 return 0; 583 return hapd->driver->commit(hapd->drv_priv); 584} 585 586 587int hostapd_set_ht_params(struct hostapd_data *hapd, 588 const u8 *ht_capab, size_t ht_capab_len, 589 const u8 *ht_oper, size_t ht_oper_len) 590{ 591 if (hapd->driver == NULL || hapd->driver->set_ht_params == NULL || 592 ht_capab == NULL || ht_oper == NULL) 593 return 0; 594 return hapd->driver->set_ht_params(hapd->drv_priv, 595 ht_capab, ht_capab_len, 596 ht_oper, ht_oper_len); 597} 598 599 600int hostapd_drv_none(struct hostapd_data *hapd) 601{ 602 return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0; 603} 604 605 606int hostapd_driver_scan(struct hostapd_data *hapd, 607 struct wpa_driver_scan_params *params) 608{ 609 if (hapd->driver && hapd->driver->scan2) 610 return hapd->driver->scan2(hapd->drv_priv, params); 611 return -1; 612} 613 614 615struct wpa_scan_results * hostapd_driver_get_scan_results( 616 struct hostapd_data *hapd) 617{ 618 if (hapd->driver && hapd->driver->get_scan_results2) 619 return hapd->driver->get_scan_results2(hapd->drv_priv); 620 return NULL; 621} 622