1/* 2 * WPA Supplicant - driver interaction with BSD net80211 layer 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> 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 * $FreeBSD$ 15 */ 16 17#include <stdlib.h> 18#include <stdio.h> 19#include <unistd.h> 20#include <string.h> 21#include <sys/ioctl.h> 22#include <errno.h> 23 24#include "common.h" 25#include "driver.h" 26#include "eloop.h" 27#include "l2_packet.h" 28#include "ieee802_11_defs.h" 29 30#include <sys/socket.h> 31#include <net/if.h> 32#include <net/if_media.h> 33#include <net/ethernet.h> 34 35#include <net80211/ieee80211_ioctl.h> 36 37struct wpa_driver_bsd_data { 38 int sock; /* open socket for 802.11 ioctls */ 39 int route; /* routing socket for events */ 40 char ifname[IFNAMSIZ+1]; /* interface name */ 41 unsigned int ifindex; /* interface index */ 42 void *ctx; 43 int prev_roaming; /* roaming state to restore on deinit */ 44 int prev_privacy; /* privacy state to restore on deinit */ 45 int prev_wpa; /* wpa state to restore on deinit */ 46 int prev_scanvalid; /* scan valid to restore on deinit */ 47 uint8_t lastssid[IEEE80211_NWID_LEN]; 48 int lastssid_len; 49 uint32_t drivercaps; /* general driver capabilities */ 50 uint32_t cryptocaps; /* hardware crypto support */ 51 enum ieee80211_opmode opmode; /* operation mode */ 52}; 53 54static enum ieee80211_opmode 55get80211opmode(struct wpa_driver_bsd_data *drv) 56{ 57 struct ifmediareq ifmr; 58 59 (void) memset(&ifmr, 0, sizeof(ifmr)); 60 (void) strncpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name)); 61 62 if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) { 63 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { 64 if (ifmr.ifm_current & IFM_FLAG0) 65 return IEEE80211_M_AHDEMO; 66 else 67 return IEEE80211_M_IBSS; 68 } 69 if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 70 return IEEE80211_M_HOSTAP; 71 if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 72 return IEEE80211_M_MONITOR; 73 if (ifmr.ifm_current & IFM_IEEE80211_MBSS) 74 return IEEE80211_M_MBSS; 75 } 76 return IEEE80211_M_STA; 77} 78 79static int 80set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len) 81{ 82 struct ieee80211req ireq; 83 84 memset(&ireq, 0, sizeof(ireq)); 85 strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); 86 ireq.i_type = op; 87 ireq.i_len = arg_len; 88 ireq.i_data = (void *) arg; 89 90 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { 91 fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n", 92 op, arg_len, strerror(errno)); 93 return -1; 94 } 95 return 0; 96} 97 98static int 99get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len) 100{ 101 struct ieee80211req ireq; 102 103 memset(&ireq, 0, sizeof(ireq)); 104 strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); 105 ireq.i_type = op; 106 ireq.i_len = arg_len; 107 ireq.i_data = arg; 108 109 if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { 110 fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n", 111 op, arg_len, strerror(errno)); 112 return -1; 113 } 114 return ireq.i_len; 115} 116 117static int 118set80211param(struct wpa_driver_bsd_data *drv, int op, int arg) 119{ 120 struct ieee80211req ireq; 121 122 memset(&ireq, 0, sizeof(ireq)); 123 strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); 124 ireq.i_type = op; 125 ireq.i_val = arg; 126 127 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { 128 fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n", 129 op, arg, strerror(errno)); 130 return -1; 131 } 132 return 0; 133} 134 135static int 136get80211param(struct wpa_driver_bsd_data *drv, int op) 137{ 138 struct ieee80211req ireq; 139 140 memset(&ireq, 0, sizeof(ireq)); 141 strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); 142 ireq.i_type = op; 143 144 if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { 145 fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n", 146 op, strerror(errno)); 147 return -1; 148 } 149 return ireq.i_val; 150} 151 152static int 153getifflags(struct wpa_driver_bsd_data *drv, int *flags) 154{ 155 struct ifreq ifr; 156 157 memset(&ifr, 0, sizeof(ifr)); 158 strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); 159 if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 160 perror("SIOCGIFFLAGS"); 161 return errno; 162 } 163 *flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); 164 return 0; 165} 166 167static int 168setifflags(struct wpa_driver_bsd_data *drv, int flags) 169{ 170 struct ifreq ifr; 171 172 memset(&ifr, 0, sizeof(ifr)); 173 strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); 174 ifr.ifr_flags = flags & 0xffff; 175 ifr.ifr_flagshigh = flags >> 16; 176 if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { 177 perror("SIOCSIFFLAGS"); 178 return errno; 179 } 180 return 0; 181} 182 183static int 184wpa_driver_bsd_get_bssid(void *priv, u8 *bssid) 185{ 186 struct wpa_driver_bsd_data *drv = priv; 187 188 return get80211var(drv, IEEE80211_IOC_BSSID, 189 bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0; 190} 191 192#if 0 193static int 194wpa_driver_bsd_set_bssid(void *priv, const char *bssid) 195{ 196 struct wpa_driver_bsd_data *drv = priv; 197 198 return set80211var(drv, IEEE80211_IOC_BSSID, 199 bssid, IEEE80211_ADDR_LEN); 200} 201#endif 202 203static int 204wpa_driver_bsd_get_ssid(void *priv, u8 *ssid) 205{ 206 struct wpa_driver_bsd_data *drv = priv; 207 208 return get80211var(drv, IEEE80211_IOC_SSID, 209 ssid, IEEE80211_NWID_LEN); 210} 211 212static int 213wpa_driver_bsd_set_ssid(void *priv, const char *ssid, 214 size_t ssid_len) 215{ 216 struct wpa_driver_bsd_data *drv = priv; 217 218 return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); 219} 220 221static int 222wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, 223 const u8 *wpa_ie, size_t wpa_ie_len) 224{ 225 struct ieee80211req ireq; 226 227 memset(&ireq, 0, sizeof(ireq)); 228 strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); 229 ireq.i_type = IEEE80211_IOC_APPIE; 230 ireq.i_val = IEEE80211_APPIE_WPA; 231 ireq.i_len = wpa_ie_len; 232 ireq.i_data = (void *) wpa_ie; 233 if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { 234 fprintf(stderr, 235 "ioctl[IEEE80211_IOC_APPIE:IEEE80211_APPIE_WPA]: %s\n", 236 strerror(errno)); 237 return -1; 238 } 239 return 0; 240} 241 242static int 243wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) 244{ 245 struct wpa_driver_bsd_data *drv = priv; 246 int ret = 0; 247 248 wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", 249 __FUNCTION__, wpa, privacy); 250 251 if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) 252 ret = -1; 253 if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) 254 ret = -1; 255 if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0) 256 ret = -1; 257 258 return ret; 259} 260 261static int 262wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, 263 const unsigned char *addr) 264{ 265 struct ieee80211req_del_key wk; 266 267 memset(&wk, 0, sizeof(wk)); 268 if (addr != NULL && 269 bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) { 270 struct ether_addr ea; 271 272 memcpy(&ea, addr, IEEE80211_ADDR_LEN); 273 wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d", 274 __func__, ether_ntoa(&ea), key_idx); 275 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 276 wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE; 277 } else { 278 wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx); 279 wk.idk_keyix = key_idx; 280 } 281 return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); 282} 283 284static int 285wpa_driver_bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, 286 const unsigned char *addr, int key_idx, int set_tx, 287 const u8 *seq, size_t seq_len, 288 const u8 *key, size_t key_len) 289{ 290 struct wpa_driver_bsd_data *drv = priv; 291 struct ieee80211req_key wk; 292 struct ether_addr ea; 293 char *alg_name; 294 u_int8_t cipher; 295 296 if (alg == WPA_ALG_NONE) 297 return wpa_driver_bsd_del_key(drv, key_idx, addr); 298 299 switch (alg) { 300 case WPA_ALG_WEP: 301 alg_name = "WEP"; 302 cipher = IEEE80211_CIPHER_WEP; 303 break; 304 case WPA_ALG_TKIP: 305 alg_name = "TKIP"; 306 cipher = IEEE80211_CIPHER_TKIP; 307 break; 308 case WPA_ALG_CCMP: 309 alg_name = "CCMP"; 310 cipher = IEEE80211_CIPHER_AES_CCM; 311 break; 312 default: 313 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", 314 __func__, alg); 315 return -1; 316 } 317 318 memcpy(&ea, addr, IEEE80211_ADDR_LEN); 319 wpa_printf(MSG_DEBUG, 320 "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", 321 __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, 322 seq_len, key_len); 323 324 if (seq_len > sizeof(u_int64_t)) { 325 wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", 326 __func__, seq_len); 327 return -2; 328 } 329 if (key_len > sizeof(wk.ik_keydata)) { 330 wpa_printf(MSG_DEBUG, "%s: key length %zu too big", 331 __func__, key_len); 332 return -3; 333 } 334 335 memset(&wk, 0, sizeof(wk)); 336 wk.ik_type = cipher; 337 wk.ik_flags = IEEE80211_KEY_RECV; 338 if (set_tx) 339 wk.ik_flags |= IEEE80211_KEY_XMIT; 340 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 341 /* 342 * Deduce whether group/global or unicast key by checking 343 * the address (yech). Note also that we can only mark global 344 * keys default; doing this for a unicast key is an error. 345 */ 346 if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) { 347 wk.ik_flags |= IEEE80211_KEY_GROUP; 348 wk.ik_keyix = key_idx; 349 } else { 350 wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx); 351 } 352 if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) 353 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 354 /* 355 * Ignore replay failures in IBSS and AHDEMO mode. 356 */ 357 if (drv->opmode == IEEE80211_M_IBSS || 358 drv->opmode == IEEE80211_M_AHDEMO) 359 wk.ik_flags |= IEEE80211_KEY_NOREPLAY; 360 wk.ik_keylen = key_len; 361 memcpy(&wk.ik_keyrsc, seq, seq_len); 362 wk.ik_keyrsc = le64toh(wk.ik_keyrsc); 363 memcpy(wk.ik_keydata, key, key_len); 364 365 return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); 366} 367 368static int 369wpa_driver_bsd_set_countermeasures(void *priv, int enabled) 370{ 371 struct wpa_driver_bsd_data *drv = priv; 372 373 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 374 return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); 375} 376 377 378static int 379wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled) 380{ 381 struct wpa_driver_bsd_data *drv = priv; 382 383 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 384 return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled); 385} 386 387static int 388wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) 389{ 390 struct wpa_driver_bsd_data *drv = priv; 391 int authmode; 392 393 if ((auth_alg & WPA_AUTH_ALG_OPEN) && 394 (auth_alg & WPA_AUTH_ALG_SHARED)) 395 authmode = IEEE80211_AUTH_AUTO; 396 else if (auth_alg & WPA_AUTH_ALG_SHARED) 397 authmode = IEEE80211_AUTH_SHARED; 398 else 399 authmode = IEEE80211_AUTH_OPEN; 400 401 wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u", 402 __func__, auth_alg, authmode); 403 404 return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); 405} 406 407static int 408wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) 409{ 410 struct wpa_driver_bsd_data *drv = priv; 411 struct ieee80211req_mlme mlme; 412 413 drv->lastssid_len = 0; 414 415 wpa_printf(MSG_DEBUG, "%s", __func__); 416 memset(&mlme, 0, sizeof(mlme)); 417 mlme.im_op = IEEE80211_MLME_DEAUTH; 418 mlme.im_reason = reason_code; 419 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 420 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); 421} 422 423static int 424wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) 425{ 426 struct wpa_driver_bsd_data *drv = priv; 427 struct ieee80211req_mlme mlme; 428 429 drv->lastssid_len = 0; 430 431 wpa_printf(MSG_DEBUG, "%s", __func__); 432 memset(&mlme, 0, sizeof(mlme)); 433 mlme.im_op = IEEE80211_MLME_DISASSOC; 434 mlme.im_reason = reason_code; 435 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 436 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); 437} 438 439static int 440wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) 441{ 442 struct wpa_driver_bsd_data *drv = priv; 443 struct ieee80211req_mlme mlme; 444 int flags, privacy; 445 446 wpa_printf(MSG_DEBUG, 447 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" 448 , __func__ 449 , params->ssid_len, params->ssid 450 , params->wpa_ie_len 451 , params->pairwise_suite 452 , params->group_suite 453 , params->key_mgmt_suite 454 ); 455 456 /* NB: interface must be marked UP to associate */ 457 if (getifflags(drv, &flags) != 0) { 458 wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); 459 return -1; 460 } 461 if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { 462 wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", 463 __func__); 464 return -1; 465 } 466 467 if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted) 468 < 0) 469 return -1; 470 if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) 471 return -1; 472 /* XXX error handling is wrong but unclear what to do... */ 473 if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) 474 return -1; 475 476 privacy = !(params->pairwise_suite == CIPHER_NONE && 477 params->group_suite == CIPHER_NONE && 478 params->key_mgmt_suite == KEY_MGMT_NONE && 479 params->wpa_ie_len == 0); 480 wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy); 481 482 if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) 483 return -1; 484 485 if (params->wpa_ie_len && 486 set80211param(drv, IEEE80211_IOC_WPA, 487 params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) 488 return -1; 489 490 memset(&mlme, 0, sizeof(mlme)); 491 mlme.im_op = IEEE80211_MLME_ASSOC; 492 if (params->ssid != NULL) 493 memcpy(mlme.im_ssid, params->ssid, params->ssid_len); 494 mlme.im_ssid_len = params->ssid_len; 495 if (params->bssid != NULL) 496 memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); 497 if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) 498 return -1; 499 memcpy(drv->lastssid, params->ssid, params->ssid_len); 500 drv->lastssid_len = params->ssid_len; 501 return 0; 502} 503 504static int 505wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) 506{ 507 struct wpa_driver_bsd_data *drv = priv; 508 struct ieee80211_scan_req sr; 509 int i; 510 int flags; 511 512 /* XXX not true but easiest to perpetuate the myth */ 513 /* NB: interface must be marked UP to do a scan */ 514 if (getifflags(drv, &flags) != 0) { 515 wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); 516 return -1; 517 } 518 if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { 519 wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", 520 __func__); 521 return -1; 522 } 523 524 memset(&sr, 0, sizeof(sr)); 525 sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE 526 | IEEE80211_IOC_SCAN_ONCE 527 | IEEE80211_IOC_SCAN_NOJOIN 528 ; 529 sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; 530 if (params->num_ssids > 0) { 531 sr.sr_nssid = params->num_ssids; 532#if 0 533 /* Boundary check is done by upper layer */ 534 if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID) 535 sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID; 536#endif 537 /* NB: check scan cache first */ 538 sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; 539} 540 for (i = 0; i < sr.sr_nssid; i++) { 541 sr.sr_ssid[i].len = params->ssids[i].ssid_len; 542 os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid, 543 sr.sr_ssid[i].len); 544 } 545 /* NB: net80211 delivers a scan complete event so no need to poll */ 546 return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); 547} 548 549#include <net/route.h> 550#include <net80211/ieee80211_freebsd.h> 551 552static void 553wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) 554{ 555 struct wpa_driver_bsd_data *drv = sock_ctx; 556 char buf[2048]; 557 struct if_announcemsghdr *ifan; 558 struct if_msghdr *ifm; 559 struct rt_msghdr *rtm; 560 union wpa_event_data event; 561 struct ieee80211_michael_event *mic; 562 int n; 563 564 n = read(sock, buf, sizeof(buf)); 565 if (n < 0) { 566 if (errno != EINTR && errno != EAGAIN) 567 perror("read(PF_ROUTE)"); 568 return; 569 } 570 571 rtm = (struct rt_msghdr *) buf; 572 if (rtm->rtm_version != RTM_VERSION) { 573 wpa_printf(MSG_DEBUG, "Routing message version %d not " 574 "understood\n", rtm->rtm_version); 575 return; 576 } 577 memset(&event, 0, sizeof(event)); 578 switch (rtm->rtm_type) { 579 case RTM_IFANNOUNCE: 580 ifan = (struct if_announcemsghdr *) rtm; 581 if (ifan->ifan_index != drv->ifindex) 582 break; 583 strlcpy(event.interface_status.ifname, drv->ifname, 584 sizeof(event.interface_status.ifname)); 585 switch (ifan->ifan_what) { 586 case IFAN_DEPARTURE: 587 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 588 default: 589 return; 590 } 591 wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s", 592 event.interface_status.ifname, 593 ifan->ifan_what == IFAN_DEPARTURE ? 594 "removed" : "added"); 595 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 596 break; 597 case RTM_IEEE80211: 598 ifan = (struct if_announcemsghdr *) rtm; 599 if (ifan->ifan_index != drv->ifindex) 600 break; 601 switch (ifan->ifan_what) { 602 case RTM_IEEE80211_ASSOC: 603 case RTM_IEEE80211_REASSOC: 604 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); 605 break; 606 case RTM_IEEE80211_DISASSOC: 607 wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); 608 break; 609 case RTM_IEEE80211_SCAN: 610 wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); 611 break; 612 case RTM_IEEE80211_REPLAY: 613 /* ignore */ 614 break; 615 case RTM_IEEE80211_MICHAEL: 616 mic = (struct ieee80211_michael_event *) &ifan[1]; 617 wpa_printf(MSG_DEBUG, 618 "Michael MIC failure wireless event: " 619 "keyix=%u src_addr=" MACSTR, mic->iev_keyix, 620 MAC2STR(mic->iev_src)); 621 622 memset(&event, 0, sizeof(event)); 623 event.michael_mic_failure.unicast = 624 !IEEE80211_IS_MULTICAST(mic->iev_dst); 625 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, 626 &event); 627 break; 628 } 629 break; 630 case RTM_IFINFO: 631 ifm = (struct if_msghdr *) rtm; 632 if (ifm->ifm_index != drv->ifindex) 633 break; 634 if ((rtm->rtm_flags & RTF_UP) == 0) { 635 strlcpy(event.interface_status.ifname, drv->ifname, 636 sizeof(event.interface_status.ifname)); 637 event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 638 wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN", 639 event.interface_status.ifname); 640 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); 641 } 642 break; 643 } 644} 645 646static int 647getmaxrate(const uint8_t rates[15], uint8_t nrates) 648{ 649 int i, maxrate = -1; 650 651 for (i = 0; i < nrates; i++) { 652 int rate = rates[i] & IEEE80211_RATE_VAL; 653 if (rate > maxrate) 654 rate = maxrate; 655 } 656 return maxrate; 657} 658 659/* unalligned little endian access */ 660#define LE_READ_4(p) \ 661 ((u_int32_t) \ 662 ((((const u_int8_t *)(p))[0] ) | \ 663 (((const u_int8_t *)(p))[1] << 8) | \ 664 (((const u_int8_t *)(p))[2] << 16) | \ 665 (((const u_int8_t *)(p))[3] << 24))) 666 667static int __inline 668iswpaoui(const u_int8_t *frm) 669{ 670 return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); 671} 672 673 674static void 675wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res, 676 struct ieee80211req_scan_result *sr) 677{ 678 struct wpa_scan_res *result, **tmp; 679 size_t extra_len; 680 u8 *pos; 681 682 extra_len = 2 + sr->isr_ssid_len; 683 extra_len += 2 + sr->isr_nrates; 684 extra_len += 3; /* ERP IE */ 685 extra_len += sr->isr_ie_len; 686 687 result = os_zalloc(sizeof(*result) + extra_len); 688 if (result == NULL) 689 return; 690 os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN); 691 result->freq = sr->isr_freq; 692 result->beacon_int = sr->isr_intval; 693 result->caps = sr->isr_capinfo; 694 result->qual = sr->isr_rssi; 695 result->noise = sr->isr_noise; 696 /* 697 * the rssi value reported by the kernel is in 0.5dB steps relative to 698 * the reported noise floor. see ieee80211_node.h for details. 699 */ 700 result->level = sr->isr_rssi / 2 + sr->isr_noise; 701 702 pos = (u8 *)(result + 1); 703 704 *pos++ = WLAN_EID_SSID; 705 *pos++ = sr->isr_ssid_len; 706 os_memcpy(pos, sr + 1, sr->isr_ssid_len); 707 pos += sr->isr_ssid_len; 708 709 /* 710 * Deal all rates as supported rate. 711 * Because net80211 doesn't report extended supported rate or not. 712 */ 713 *pos++ = WLAN_EID_SUPP_RATES; 714 *pos++ = sr->isr_nrates; 715 os_memcpy(pos, sr->isr_rates, sr->isr_nrates); 716 pos += sr->isr_nrates; 717 718 *pos++ = WLAN_EID_ERP_INFO; 719 *pos++ = 1; 720 *pos++ = sr->isr_erp; 721 722 os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len); 723 pos += sr->isr_ie_len; 724 725 result->ie_len = pos - (u8 *)(result + 1); 726 727 tmp = os_realloc(res->res, 728 (res->num + 1) * sizeof(struct wpa_scan_res *)); 729 if (tmp == NULL) { 730 os_free(result); 731 return; 732 } 733 tmp[res->num++] = result; 734 res->res = tmp; 735} 736 737static struct wpa_scan_results * 738wpa_driver_bsd_get_scan_results2(void *priv) 739{ 740 struct ieee80211req_scan_result *sr; 741 struct wpa_scan_results *res; 742 int len, rest; 743 uint8_t buf[24*1024], *pos; 744 745 len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024); 746 if (len < 0) 747 return NULL; 748 749 res = os_zalloc(sizeof(*res)); 750 if (res == NULL) 751 return NULL; 752 753 pos = buf; 754 rest = len; 755 while (rest >= sizeof(struct ieee80211req_scan_result)) { 756 sr = (struct ieee80211req_scan_result *)pos; 757 wpa_driver_bsd_add_scan_entry(res, sr); 758 pos += sr->isr_len; 759 rest -= sr->isr_len; 760 } 761 762 wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)", 763 len, (unsigned long)res->num); 764 765 return (res); 766} 767 768 769#define GETPARAM(drv, param, v) \ 770 (((v) = get80211param(drv, param)) != -1) 771#define IEEE80211_C_BGSCAN 0x20000000 772 773/* 774 * Set the scan cache valid threshold to 1.5 x bg scan interval 775 * to force all scan requests to consult the cache unless they 776 * explicitly bypass it. 777 */ 778static int 779setscanvalid(struct wpa_driver_bsd_data *drv) 780{ 781 int bgscan, scanvalid; 782 783 if (!GETPARAM(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid) || 784 !GETPARAM(drv, IEEE80211_IOC_BGSCAN_INTERVAL, bgscan)) 785 return -1; 786 scanvalid = 3*bgscan/2; 787 return (drv->prev_scanvalid < scanvalid) ? 788 set80211param(drv, IEEE80211_IOC_SCANVALID, scanvalid) : 0; 789} 790 791static void * 792wpa_driver_bsd_init(void *ctx, const char *ifname) 793{ 794 struct wpa_driver_bsd_data *drv; 795 struct ieee80211_devcaps_req devcaps; 796 int flags; 797 798 drv = malloc(sizeof(*drv)); 799 if (drv == NULL) 800 return NULL; 801 memset(drv, 0, sizeof(*drv)); 802 /* 803 * NB: We require the interface name be mappable to an index. 804 * This implies we do not support having wpa_supplicant 805 * wait for an interface to appear. This seems ok; that 806 * doesn't belong here; it's really the job of devd. 807 */ 808 drv->ifindex = if_nametoindex(ifname); 809 if (drv->ifindex == 0) { 810 wpa_printf(MSG_DEBUG, "%s: interface %s does not exist", 811 __func__, ifname); 812 goto fail1; 813 } 814 drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 815 if (drv->sock < 0) 816 goto fail1; 817 drv->ctx = ctx; 818 strncpy(drv->ifname, ifname, sizeof(drv->ifname)); 819 820 /* 821 * Mark the interface as down to ensure wpa_supplicant has exclusive 822 * access to the net80211 state machine, do this before opening the 823 * route socket to avoid a false event that the interface disappeared. 824 */ 825 if (getifflags(drv, &flags) == 0) 826 (void) setifflags(drv, flags &~ IFF_UP); 827 828 drv->route = socket(PF_ROUTE, SOCK_RAW, 0); 829 if (drv->route < 0) 830 goto fail; 831 eloop_register_read_sock(drv->route, 832 wpa_driver_bsd_event_receive, ctx, drv); 833 834 if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) { 835 wpa_printf(MSG_DEBUG, 836 "%s: failed to get device capabilities: %s", 837 __func__, strerror(errno)); 838 goto fail; 839 } 840 drv->drivercaps = devcaps.dc_drivercaps; 841 drv->cryptocaps = devcaps.dc_cryptocaps; 842 843 if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { 844 wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", 845 __func__, strerror(errno)); 846 goto fail; 847 } 848 if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { 849 wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", 850 __func__, strerror(errno)); 851 goto fail; 852 } 853 if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { 854 wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", 855 __func__, strerror(errno)); 856 goto fail; 857 } 858 if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { 859 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " 860 "roaming: %s", __func__, strerror(errno)); 861 goto fail; 862 } 863 if (drv->drivercaps & IEEE80211_C_BGSCAN) { 864 /* 865 * Driver does background scanning; force the scan valid 866 * setting to 1.5 x bg scan interval so the scan cache is 867 * always consulted before we force a foreground scan. 868 */ 869 if (setscanvalid(drv) < 0) { 870 wpa_printf(MSG_DEBUG, 871 "%s: warning, failed to set scanvalid, scanning " 872 "may be suboptimal: %s", __func__, strerror(errno)); 873 } 874 } 875 if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { 876 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", 877 __func__, strerror(errno)); 878 goto fail; 879 } 880 drv->opmode = get80211opmode(drv); 881 882 return drv; 883fail: 884 close(drv->sock); 885fail1: 886 free(drv); 887 return NULL; 888} 889#undef GETPARAM 890 891static void 892wpa_driver_bsd_deinit(void *priv) 893{ 894 struct wpa_driver_bsd_data *drv = priv; 895 int flags; 896 897 /* NB: mark interface down */ 898 if (getifflags(drv, &flags) == 0) 899 (void) setifflags(drv, flags &~ IFF_UP); 900 901 wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); 902 if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) { 903 /* NB: don't whinge if device ejected or equivalent */ 904 if (errno != ENXIO) 905 wpa_printf(MSG_DEBUG, "%s: failed to restore roaming " 906 "state", __func__); 907 } 908 if (drv->drivercaps & IEEE80211_C_BGSCAN) { 909 /* XXX check return value */ 910 (void) set80211param(drv, IEEE80211_IOC_SCANVALID, 911 drv->prev_scanvalid); 912 } 913 914 (void) close(drv->route); /* ioctl socket */ 915 (void) close(drv->sock); /* event socket */ 916 free(drv); 917} 918 919 920struct wpa_driver_ops wpa_driver_bsd_ops = { 921 .name = "bsd", 922 .desc = "BSD 802.11 support (Atheros, etc.)", 923 .init = wpa_driver_bsd_init, 924 .deinit = wpa_driver_bsd_deinit, 925 .get_bssid = wpa_driver_bsd_get_bssid, 926 .get_ssid = wpa_driver_bsd_get_ssid, 927 .set_key = wpa_driver_bsd_set_key, 928 .set_countermeasures = wpa_driver_bsd_set_countermeasures, 929 .scan2 = wpa_driver_bsd_scan, 930 .get_scan_results2 = wpa_driver_bsd_get_scan_results2, 931 .deauthenticate = wpa_driver_bsd_deauthenticate, 932 .disassociate = wpa_driver_bsd_disassociate, 933 .associate = wpa_driver_bsd_associate, 934}; 935