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