1/* 2 * Host AP - driver interaction with BSD net80211 layer 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> 4 * Copyright (c) 2004, 2Wire, Inc 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Alternatively, this software may be distributed under the terms of BSD 11 * license. 12 * 13 * See README and COPYING for more details. 14 * 15 * $FreeBSD$ 16 */ 17 18#include "includes.h" 19#include <sys/ioctl.h> 20 21#include "common.h" 22#include "driver.h" 23#include "eloop.h" 24#include "common/ieee802_11_defs.h" 25#include "common/wpa_common.h" 26 27#include <sys/socket.h> 28#include <net/if.h> 29#include <net/route.h> 30#include <netinet/in.h> 31 32#include <net80211/ieee80211_ioctl.h> 33#include <net80211/ieee80211_freebsd.h> 34 35#include "l2_packet/l2_packet.h" 36 37struct bsd_driver_data { 38 struct hostapd_data *hapd; /* back pointer */ 39 40 int sock; /* open socket for 802.11 ioctls */ 41 struct l2_packet_data *sock_xmit;/* raw packet xmit socket */ 42 int route; /* routing socket for events */ 43 char ifname[IFNAMSIZ+1]; /* interface name */ 44 unsigned int ifindex; /* interface index */ 45 void *ctx; 46 struct wpa_driver_capa capa; /* driver capability */ 47 int is_ap; /* Access point mode */ 48 int prev_roaming; /* roaming state to restore on deinit */ 49 int prev_privacy; /* privacy state to restore on deinit */ 50 int prev_wpa; /* wpa state to restore on deinit */ 51}; 52 53static int 54bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len) 55{ 56 struct bsd_driver_data *drv = priv; 57 struct ieee80211req ireq; 58 59 os_memset(&ireq, 0, sizeof(ireq)); 60 os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name)); 61 ireq.i_type = op; 62 ireq.i_val = val; 63 ireq.i_data = (void *) arg; 64 ireq.i_len = arg_len; 65 66 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { 67 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, val=%u, " 68 "arg_len=%u]: %s", op, val, arg_len, 69 strerror(errno)); 70 return -1; 71 } 72 return 0; 73} 74 75static int 76bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg, 77 int arg_len) 78{ 79 struct bsd_driver_data *drv = priv; 80 81 os_memset(ireq, 0, sizeof(*ireq)); 82 os_strlcpy(ireq->i_name, drv->ifname, sizeof(ireq->i_name)); 83 ireq->i_type = op; 84 ireq->i_len = arg_len; 85 ireq->i_data = arg; 86 87 if (ioctl(drv->sock, SIOCG80211, ireq) < 0) { 88 wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, " 89 "arg_len=%u]: %s", op, arg_len, strerror(errno)); 90 return -1; 91 } 92 return 0; 93} 94 95static int 96get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len) 97{ 98 struct ieee80211req ireq; 99 100 if (bsd_get80211(drv, &ireq, op, arg, arg_len) < 0) 101 return -1; 102 return ireq.i_len; 103} 104 105static int 106set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len) 107{ 108 return bsd_set80211(drv, op, 0, arg, arg_len); 109} 110 111static int 112set80211param(struct bsd_driver_data *drv, int op, int arg) 113{ 114 return bsd_set80211(drv, op, arg, NULL, 0); 115} 116 117static int 118bsd_get_ssid(void *priv, u8 *ssid, int len) 119{ 120 struct bsd_driver_data *drv = priv; 121 122 return get80211var(drv, IEEE80211_IOC_SSID, ssid, IEEE80211_NWID_LEN); 123} 124 125static int 126bsd_set_ssid(void *priv, const u8 *ssid, int ssid_len) 127{ 128 struct bsd_driver_data *drv = priv; 129 130 return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); 131} 132 133static int 134bsd_del_key(void *priv, const u8 *addr, int key_idx) 135{ 136 struct ieee80211req_del_key wk; 137 138 os_memset(&wk, 0, sizeof(wk)); 139 if (addr == NULL) { 140 wpa_printf(MSG_DEBUG, "%s: key_idx=%d", __func__, key_idx); 141 wk.idk_keyix = key_idx; 142 } else { 143 wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, 144 MAC2STR(addr)); 145 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 146 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */ 147 } 148 149 return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); 150} 151 152static int 153bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr) 154{ 155 struct ieee80211req_mlme mlme; 156 157 os_memset(&mlme, 0, sizeof(mlme)); 158 mlme.im_op = op; 159 mlme.im_reason = reason; 160 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 161 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); 162} 163 164static int 165bsd_ctrl_iface(void *priv, int enable) 166{ 167 struct bsd_driver_data *drv = priv; 168 struct ifreq ifr; 169 170 if (drv->sock < 0) 171 return -1; 172 173 os_memset(&ifr, 0, sizeof(ifr)); 174 os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); 175 176 if (ioctl(drv->sock, SIOCGIFFLAGS, &ifr) < 0) { 177 perror("ioctl[SIOCGIFFLAGS]"); 178 return -1; 179 } 180 181 if (enable) { 182 if ((ifr.ifr_flags & IFF_UP) == IFF_UP) 183 return 0; 184 ifr.ifr_flags |= IFF_UP; 185 } else { 186 if ((ifr.ifr_flags & IFF_UP) == 0) 187 return 0; 188 ifr.ifr_flags &= ~IFF_UP; 189 } 190 191 if (ioctl(drv->sock, SIOCSIFFLAGS, &ifr) < 0) { 192 perror("ioctl[SIOCSIFFLAGS]"); 193 return -1; 194 } 195 196 return 0; 197} 198 199static int 200bsd_commit(void *priv) 201{ 202 return bsd_ctrl_iface(priv, 1); 203} 204 205static int 206bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, 207 const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, 208 size_t seq_len, const u8 *key, size_t key_len) 209{ 210 struct ieee80211req_key wk; 211 212 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " 213 "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx, 214 set_tx, seq_len, key_len); 215 216 if (alg == WPA_ALG_NONE) { 217 return bsd_del_key(priv, addr, key_idx); 218 } 219 220 os_memset(&wk, 0, sizeof(wk)); 221 switch (alg) { 222 case WPA_ALG_WEP: 223 wk.ik_type = IEEE80211_CIPHER_WEP; 224 break; 225 case WPA_ALG_TKIP: 226 wk.ik_type = IEEE80211_CIPHER_TKIP; 227 break; 228 case WPA_ALG_CCMP: 229 wk.ik_type = IEEE80211_CIPHER_AES_CCM; 230 break; 231 default: 232 wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg); 233 return -1; 234 } 235 236 wk.ik_flags = IEEE80211_KEY_RECV; 237 if (set_tx) 238 wk.ik_flags |= IEEE80211_KEY_XMIT; 239 240 if (addr == NULL) { 241 os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 242 wk.ik_keyix = key_idx; 243 } else { 244 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 245 /* 246 * Deduce whether group/global or unicast key by checking 247 * the address (yech). Note also that we can only mark global 248 * keys default; doing this for a unicast key is an error. 249 */ 250 if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", 251 IEEE80211_ADDR_LEN) == 0) { 252 wk.ik_flags |= IEEE80211_KEY_GROUP; 253 wk.ik_keyix = key_idx; 254 } else { 255 wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE : 256 key_idx; 257 } 258 } 259 if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) 260 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 261 wk.ik_keylen = key_len; 262 os_memcpy(&wk.ik_keyrsc, seq, seq_len); 263 os_memcpy(wk.ik_keydata, key, key_len); 264 265 return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); 266} 267 268static int 269bsd_configure_wpa(void *priv, struct wpa_bss_params *params) 270{ 271 wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, params->wpa); 272 if (set80211param(priv, IEEE80211_IOC_WPA, params->wpa)) { 273 printf("Unable to set WPA to %u\n", params->wpa); 274 return -1; 275 } 276 return 0; 277} 278 279static int 280bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) 281{ 282 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 283 284 if (!params->enabled) { 285 /* XXX restore state */ 286 return set80211param(priv, IEEE80211_IOC_AUTHMODE, 287 IEEE80211_AUTH_AUTO); 288 } 289 if (!params->wpa && !params->ieee802_1x) { 290 wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled", 291 __func__); 292 return -1; 293 } 294 if (params->wpa && bsd_configure_wpa(priv, params) != 0) { 295 wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state", 296 __func__); 297 return -1; 298 } 299 if (set80211param(priv, IEEE80211_IOC_AUTHMODE, 300 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 301 wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X", 302 __func__); 303 return -1; 304 } 305 return 0; 306} 307 308static int 309bsd_set_sta_authorized(void *priv, const u8 *addr, 310 int total_flags, int flags_or, int flags_and) 311{ 312 int authorized = -1; 313 314 /* For now, only support setting Authorized flag */ 315 if (flags_or & WPA_STA_AUTHORIZED) 316 authorized = 1; 317 if (!(flags_and & WPA_STA_AUTHORIZED)) 318 authorized = 0; 319 320 if (authorized < 0) 321 return 0; 322 323 return bsd_send_mlme_param(priv, authorized ? 324 IEEE80211_MLME_AUTHORIZE : 325 IEEE80211_MLME_UNAUTHORIZE, 0, addr); 326} 327 328static void 329bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN]) 330{ 331 struct ieee80211req_wpaie ie; 332 int ielen = 0; 333 u8 *iebuf = NULL; 334 335 /* 336 * Fetch and validate any negotiated WPA/RSN parameters. 337 */ 338 memset(&ie, 0, sizeof(ie)); 339 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 340 if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { 341 printf("Failed to get WPA/RSN information element.\n"); 342 goto no_ie; 343 } 344 iebuf = ie.wpa_ie; 345 ielen = ie.wpa_ie[1]; 346 if (ielen == 0) 347 iebuf = NULL; 348 else 349 ielen += 2; 350 351no_ie: 352 drv_event_assoc(ctx, addr, iebuf, ielen); 353} 354 355static int 356bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 357 int encrypt, const u8 *own_addr) 358{ 359 struct bsd_driver_data *drv = priv; 360 361 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", data, data_len); 362 363 return l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, data, 364 data_len); 365} 366 367static int 368bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 369{ 370 wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %lu)", __func__, 371 (unsigned long)ie_len); 372 return bsd_set80211(priv, IEEE80211_IOC_APPIE, IEEE80211_APPIE_WPA, 373 ie, ie_len); 374} 375 376/* 377 * Avoid conflicts with hostapd definitions by undefining couple of defines 378 * from net80211 header files. 379 */ 380#undef RSN_VERSION 381#undef WPA_VERSION 382#undef WPA_OUI_TYPE 383 384static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 385 int reason_code); 386 387static const char * 388ether_sprintf(const u8 *addr) 389{ 390 static char buf[sizeof(MACSTR)]; 391 392 if (addr != NULL) 393 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 394 else 395 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 396 return buf; 397} 398 399static int 400bsd_set_privacy(void *priv, int enabled) 401{ 402 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 403 404 return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled); 405} 406 407static int 408bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 409 u8 *seq) 410{ 411 struct ieee80211req_key wk; 412 413 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 414 __func__, ether_sprintf(addr), idx); 415 416 memset(&wk, 0, sizeof(wk)); 417 if (addr == NULL) 418 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 419 else 420 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 421 wk.ik_keyix = idx; 422 423 if (get80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) { 424 printf("Failed to get encryption.\n"); 425 return -1; 426 } 427 428#ifdef WORDS_BIGENDIAN 429 { 430 /* 431 * wk.ik_keytsc is in host byte order (big endian), need to 432 * swap it to match with the byte order used in WPA. 433 */ 434 int i; 435 u8 tmp[WPA_KEY_RSC_LEN]; 436 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 437 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 438 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 439 } 440 } 441#else /* WORDS_BIGENDIAN */ 442 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 443#endif /* WORDS_BIGENDIAN */ 444 return 0; 445} 446 447 448static int 449bsd_flush(void *priv) 450{ 451 u8 allsta[IEEE80211_ADDR_LEN]; 452 453 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 454 return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE); 455} 456 457 458static int 459bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 460 const u8 *addr) 461{ 462 struct ieee80211req_sta_stats stats; 463 464 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 465 if (get80211var(priv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) 466 > 0) { 467 /* XXX? do packets counts include non-data frames? */ 468 data->rx_packets = stats.is_stats.ns_rx_data; 469 data->rx_bytes = stats.is_stats.ns_rx_bytes; 470 data->tx_packets = stats.is_stats.ns_tx_data; 471 data->tx_bytes = stats.is_stats.ns_tx_bytes; 472 } 473 return 0; 474} 475 476static int 477bsd_sta_clear_stats(void *priv, const u8 *addr) 478{ 479 struct ieee80211req_sta_stats stats; 480 481 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 482 483 /* zero station statistics */ 484 memset(&stats, 0, sizeof(stats)); 485 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 486 return set80211var(priv, IEEE80211_IOC_STA_STATS, &stats, 487 sizeof(stats)); 488} 489 490static int 491bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code) 492{ 493 return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code, 494 addr); 495} 496 497static int 498bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 499 int reason_code) 500{ 501 return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code, 502 addr); 503} 504 505static void 506bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) 507{ 508 struct bsd_driver_data *drv = ctx; 509 char buf[2048]; 510 struct if_announcemsghdr *ifan; 511 struct rt_msghdr *rtm; 512 struct ieee80211_michael_event *mic; 513 struct ieee80211_join_event *join; 514 struct ieee80211_leave_event *leave; 515#ifdef CONFIG_DRIVER_RADIUS_ACL 516 struct ieee80211_auth_event *auth; 517#endif 518 int n; 519 union wpa_event_data data; 520 521 n = read(sock, buf, sizeof(buf)); 522 if (n < 0) { 523 if (errno != EINTR && errno != EAGAIN) 524 perror("read(PF_ROUTE)"); 525 return; 526 } 527 528 rtm = (struct rt_msghdr *) buf; 529 if (rtm->rtm_version != RTM_VERSION) { 530 wpa_printf(MSG_DEBUG, "Routing message version %d not " 531 "understood\n", rtm->rtm_version); 532 return; 533 } 534 ifan = (struct if_announcemsghdr *) rtm; 535 if (ifan->ifan_index != drv->ifindex) { 536 wpa_printf(MSG_DEBUG, "Discard routing message to if#%d " 537 "(not for us %d)\n", 538 ifan->ifan_index, drv->ifindex); 539 return; 540 } 541 switch (rtm->rtm_type) { 542 case RTM_IEEE80211: 543 switch (ifan->ifan_what) { 544 case RTM_IEEE80211_ASSOC: 545 case RTM_IEEE80211_REASSOC: 546 case RTM_IEEE80211_DISASSOC: 547 case RTM_IEEE80211_SCAN: 548 break; 549 case RTM_IEEE80211_LEAVE: 550 leave = (struct ieee80211_leave_event *) &ifan[1]; 551 drv_event_disassoc(drv->hapd, leave->iev_addr); 552 break; 553 case RTM_IEEE80211_JOIN: 554#ifdef RTM_IEEE80211_REJOIN 555 case RTM_IEEE80211_REJOIN: 556#endif 557 join = (struct ieee80211_join_event *) &ifan[1]; 558 bsd_new_sta(drv, drv->hapd, join->iev_addr); 559 break; 560 case RTM_IEEE80211_REPLAY: 561 /* ignore */ 562 break; 563 case RTM_IEEE80211_MICHAEL: 564 mic = (struct ieee80211_michael_event *) &ifan[1]; 565 wpa_printf(MSG_DEBUG, 566 "Michael MIC failure wireless event: " 567 "keyix=%u src_addr=" MACSTR, mic->iev_keyix, 568 MAC2STR(mic->iev_src)); 569 os_memset(&data, 0, sizeof(data)); 570 data.michael_mic_failure.unicast = 1; 571 data.michael_mic_failure.src = mic->iev_src; 572 wpa_supplicant_event(drv->hapd, 573 EVENT_MICHAEL_MIC_FAILURE, &data); 574 break; 575#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET 576 case RTM_IEEE80211_AUTH: 577 auth = (struct ieee80211_auth_event *) &ifan[1]; 578 wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR, 579 MAC2STR(auth->iev_addr)); 580 n = hostapd_allowed_address(drv->hapd, auth->iev_addr, 581 NULL, 0, NULL, NULL, NULL); 582 switch (n) { 583 case HOSTAPD_ACL_ACCEPT: 584 case HOSTAPD_ACL_REJECT: 585 hostapd_set_radius_acl_auth(drv->hapd, 586 auth->iev_addr, n, 0); 587 wpa_printf(MSG_DEBUG, 588 "802.11 AUTH, STA = " MACSTR " hostapd says: %s", 589 MAC2STR(auth->iev_addr), 590 (n == HOSTAPD_ACL_ACCEPT ? 591 "ACCEPT" : "REJECT" )); 592 break; 593 case HOSTAPD_ACL_PENDING: 594 wpa_printf(MSG_DEBUG, 595 "802.11 AUTH, STA = " MACSTR " pending", 596 MAC2STR(auth->iev_addr)); 597 break; 598 } 599 break; 600#endif /* CONFIG_DRIVER_RADIUS_ACL */ 601 } 602 break; 603 } 604} 605 606static void 607handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 608{ 609 struct bsd_driver_data *drv = ctx; 610 drv_event_eapol_rx(drv->hapd, src_addr, buf, len); 611} 612 613static int 614bsd_set_countermeasures(void *priv, int enabled) 615{ 616 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 617 return set80211param(priv, IEEE80211_IOC_COUNTERMEASURES, enabled); 618} 619 620#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET 621static int 622bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted, 623 u32 session_timeout) 624{ 625 struct bsd_driver_data *drv = priv; 626 struct hostapd_data *hapd = drv->hapd; 627 struct ieee80211req_mlme mlme; 628 629 switch (accepted) { 630 case HOSTAPD_ACL_ACCEPT_TIMEOUT: 631 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 632 " has been accepted by RADIUS ACL with timeout " 633 "of %d.\n", hapd->conf->iface, MAC2STR(mac), 634 session_timeout); 635 mlme.im_reason = IEEE80211_STATUS_SUCCESS; 636 break; 637 case HOSTAPD_ACL_ACCEPT: 638 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 639 " has been accepted by RADIUS ACL.\n", 640 hapd->conf->iface, MAC2STR(mac)); 641 mlme.im_reason = IEEE80211_STATUS_SUCCESS; 642 break; 643 case HOSTAPD_ACL_REJECT: 644 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 645 " has been rejected by RADIUS ACL.\n", 646 hapd->conf->iface, MAC2STR(mac)); 647 mlme.im_reason = IEEE80211_STATUS_UNSPECIFIED; 648 break; 649 default: 650 wpa_printf(MSG_ERROR, "[%s] STA " MACSTR 651 " has unknown status (%d) by RADIUS ACL. " 652 "Nothing to do...\n", hapd->conf->iface, 653 MAC2STR(mac), accepted); 654 return 0; 655 } 656 memset(&mlme, 0, sizeof(mlme)); 657 mlme.im_op = IEEE80211_MLME_AUTH; 658 memcpy(mlme.im_macaddr, mac, IEEE80211_ADDR_LEN); 659 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); 660} 661 662static int 663bsd_set_radius_acl_expire(void *priv, const u8 *mac) 664{ 665 struct bsd_driver_data *drv = priv; 666 struct hostapd_data *hapd = drv->hapd; 667 668 /* 669 * The expiry of the MAC address from RADIUS ACL cache doesn't mean 670 * that we should kick off the client. Our current approach doesn't 671 * require adding/removing entries from an allow/deny list; so this 672 * function is likely unecessary 673 */ 674 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR " radius acl cache " 675 "expired; nothing to do...", hapd->conf->iface, 676 MAC2STR(mac)); 677 return 0; 678} 679#endif /* CONFIG_DRIVER_RADIUS_ACL */ 680 681static void * 682bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) 683{ 684 struct bsd_driver_data *drv; 685 686 drv = os_zalloc(sizeof(struct bsd_driver_data)); 687 if (drv == NULL) { 688 printf("Could not allocate memory for bsd driver data\n"); 689 goto bad; 690 } 691 692 drv->hapd = hapd; 693 drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 694 if (drv->sock < 0) { 695 perror("socket[PF_INET,SOCK_DGRAM]"); 696 goto bad; 697 } 698 os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); 699 /* 700 * NB: We require the interface name be mappable to an index. 701 * This implies we do not support having wpa_supplicant 702 * wait for an interface to appear. This seems ok; that 703 * doesn't belong here; it's really the job of devd. 704 * XXXSCW: devd is FreeBSD-specific. 705 */ 706 drv->ifindex = if_nametoindex(drv->ifname); 707 if (drv->ifindex == 0) { 708 printf("%s: interface %s does not exist", __func__, 709 drv->ifname); 710 goto bad; 711 } 712 713 drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, 714 handle_read, drv, 0); 715 if (drv->sock_xmit == NULL) 716 goto bad; 717 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 718 goto bad; 719 720 /* mark down during setup */ 721 if (bsd_ctrl_iface(drv, 0) < 0) 722 goto bad; 723 724 drv->route = socket(PF_ROUTE, SOCK_RAW, 0); 725 if (drv->route < 0) { 726 perror("socket(PF_ROUTE,SOCK_RAW)"); 727 goto bad; 728 } 729 eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, 730 NULL); 731 732 return drv; 733bad: 734 if (drv == NULL) 735 return NULL; 736 if (drv->sock_xmit != NULL) 737 l2_packet_deinit(drv->sock_xmit); 738 if (drv->sock >= 0) 739 close(drv->sock); 740 os_free(drv); 741 return NULL; 742} 743 744 745static void 746bsd_deinit(void *priv) 747{ 748 struct bsd_driver_data *drv = priv; 749 750 if (drv->route >= 0) { 751 eloop_unregister_read_sock(drv->route); 752 close(drv->route); 753 } 754 bsd_ctrl_iface(drv, 0); 755 if (drv->sock >= 0) 756 close(drv->sock); 757 if (drv->sock_xmit != NULL) 758 l2_packet_deinit(drv->sock_xmit); 759 os_free(drv); 760} 761 762const struct wpa_driver_ops wpa_driver_bsd_ops = { 763 .name = "bsd", 764 .desc = "BSD 802.11 support", 765 .hapd_init = bsd_init, 766 .hapd_deinit = bsd_deinit, 767 .set_privacy = bsd_set_privacy, 768 .get_seqnum = bsd_get_seqnum, 769 .flush = bsd_flush, 770 .read_sta_data = bsd_read_sta_driver_data, 771 .sta_clear_stats = bsd_sta_clear_stats, 772 .sta_disassoc = bsd_sta_disassoc, 773 .sta_deauth = bsd_sta_deauth, 774 .set_key = bsd_set_key, 775 .set_ieee8021x = bsd_set_ieee8021x, 776 .hapd_set_ssid = bsd_set_ssid, 777 .hapd_get_ssid = bsd_get_ssid, 778 .hapd_send_eapol = bsd_send_eapol, 779 .sta_set_flags = bsd_set_sta_authorized, 780 .set_generic_elem = bsd_set_opt_ie, 781 .set_countermeasures = bsd_set_countermeasures, 782 .commit = bsd_commit, 783#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET 784 .set_radius_acl_auth = bsd_set_radius_acl_auth, 785 .set_radius_acl_expire = bsd_set_radius_acl_expire, 786#endif 787}; 788