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 27 static 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 42 static 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 59 static 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 68 static 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 79 static 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 95 static 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 108 static 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 118 static 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 126 static 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 143 static 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 162 static 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 173 static 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 183 static 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 237 static 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 250 static 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 258 static 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 265 static 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 274 static 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 284 static 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 292 static 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 302 static 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 312 static 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 337 static 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 345 static 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 354 void 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 382 int 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 390 int 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 399 int 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 407 int 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 415 int 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 426 int 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 435 int 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 444 int 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 454 int 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 462 int 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 479 int 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 487 int 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 495 int 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 505 int 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 515 int 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 524 int 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 532 int 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 540 int 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 548 int 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 558 int 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 567 struct hostapd_hw_modes * 568 hostapd_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 579 int 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 587 int 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 600 int hostapd_drv_none(struct hostapd_data *hapd) 601 { 602 return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0; 603 } 604 605 606 int 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 615 struct 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