1/* 2 * Driver interaction with generic Linux Wireless Extensions 3 * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 * 8 * This file implements a driver interface for the Linux Wireless Extensions. 9 * When used with WE-18 or newer, this interface can be used as-is with number 10 * of drivers. In addition to this, some of the common functions in this file 11 * can be used by other driver interface implementations that use generic WE 12 * ioctls, but require private ioctls for some of the functionality. 13 */ 14 15#include "includes.h" 16#include <sys/ioctl.h> 17#include <sys/types.h> 18#include <sys/stat.h> 19#include <fcntl.h> 20#include <net/if_arp.h> 21 22#include "linux_wext.h" 23#include "common.h" 24#include "eloop.h" 25#include "common/ieee802_11_defs.h" 26#include "common/wpa_common.h" 27#include "priv_netlink.h" 28#include "netlink.h" 29#include "linux_ioctl.h" 30#include "rfkill.h" 31#include "driver.h" 32#include "driver_wext.h" 33 34static int wpa_driver_wext_flush_pmkid(void *priv); 35static int wpa_driver_wext_get_range(void *priv); 36static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv); 37static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv); 38static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg); 39 40 41int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv, 42 int idx, u32 value) 43{ 44 struct iwreq iwr; 45 int ret = 0; 46 47 os_memset(&iwr, 0, sizeof(iwr)); 48 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 49 iwr.u.param.flags = idx & IW_AUTH_INDEX; 50 iwr.u.param.value = value; 51 52 if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) { 53 if (errno != EOPNOTSUPP) { 54 wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d " 55 "value 0x%x) failed: %s)", 56 idx, value, strerror(errno)); 57 } 58 ret = errno == EOPNOTSUPP ? -2 : -1; 59 } 60 61 return ret; 62} 63 64 65/** 66 * wpa_driver_wext_get_bssid - Get BSSID, SIOCGIWAP 67 * @priv: Pointer to private wext data from wpa_driver_wext_init() 68 * @bssid: Buffer for BSSID 69 * Returns: 0 on success, -1 on failure 70 */ 71int wpa_driver_wext_get_bssid(void *priv, u8 *bssid) 72{ 73 struct wpa_driver_wext_data *drv = priv; 74 struct iwreq iwr; 75 int ret = 0; 76 77 os_memset(&iwr, 0, sizeof(iwr)); 78 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 79 80 if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) { 81 perror("ioctl[SIOCGIWAP]"); 82 ret = -1; 83 } 84 os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN); 85 86 return ret; 87} 88 89 90/** 91 * wpa_driver_wext_set_bssid - Set BSSID, SIOCSIWAP 92 * @priv: Pointer to private wext data from wpa_driver_wext_init() 93 * @bssid: BSSID 94 * Returns: 0 on success, -1 on failure 95 */ 96int wpa_driver_wext_set_bssid(void *priv, const u8 *bssid) 97{ 98 struct wpa_driver_wext_data *drv = priv; 99 struct iwreq iwr; 100 int ret = 0; 101 102 os_memset(&iwr, 0, sizeof(iwr)); 103 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 104 iwr.u.ap_addr.sa_family = ARPHRD_ETHER; 105 if (bssid) 106 os_memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN); 107 else 108 os_memset(iwr.u.ap_addr.sa_data, 0, ETH_ALEN); 109 110 if (ioctl(drv->ioctl_sock, SIOCSIWAP, &iwr) < 0) { 111 perror("ioctl[SIOCSIWAP]"); 112 ret = -1; 113 } 114 115 return ret; 116} 117 118 119/** 120 * wpa_driver_wext_get_ssid - Get SSID, SIOCGIWESSID 121 * @priv: Pointer to private wext data from wpa_driver_wext_init() 122 * @ssid: Buffer for the SSID; must be at least 32 bytes long 123 * Returns: SSID length on success, -1 on failure 124 */ 125int wpa_driver_wext_get_ssid(void *priv, u8 *ssid) 126{ 127 struct wpa_driver_wext_data *drv = priv; 128 struct iwreq iwr; 129 int ret = 0; 130 131 os_memset(&iwr, 0, sizeof(iwr)); 132 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 133 iwr.u.essid.pointer = (caddr_t) ssid; 134 iwr.u.essid.length = 32; 135 136 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 137 perror("ioctl[SIOCGIWESSID]"); 138 ret = -1; 139 } else { 140 ret = iwr.u.essid.length; 141 if (ret > 32) 142 ret = 32; 143 /* Some drivers include nul termination in the SSID, so let's 144 * remove it here before further processing. WE-21 changes this 145 * to explicitly require the length _not_ to include nul 146 * termination. */ 147 if (ret > 0 && ssid[ret - 1] == '\0' && 148 drv->we_version_compiled < 21) 149 ret--; 150 } 151 152 return ret; 153} 154 155 156/** 157 * wpa_driver_wext_set_ssid - Set SSID, SIOCSIWESSID 158 * @priv: Pointer to private wext data from wpa_driver_wext_init() 159 * @ssid: SSID 160 * @ssid_len: Length of SSID (0..32) 161 * Returns: 0 on success, -1 on failure 162 */ 163int wpa_driver_wext_set_ssid(void *priv, const u8 *ssid, size_t ssid_len) 164{ 165 struct wpa_driver_wext_data *drv = priv; 166 struct iwreq iwr; 167 int ret = 0; 168 char buf[33]; 169 170 if (ssid_len > 32) 171 return -1; 172 173 os_memset(&iwr, 0, sizeof(iwr)); 174 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 175 /* flags: 1 = ESSID is active, 0 = not (promiscuous) */ 176 iwr.u.essid.flags = (ssid_len != 0); 177 os_memset(buf, 0, sizeof(buf)); 178 os_memcpy(buf, ssid, ssid_len); 179 iwr.u.essid.pointer = (caddr_t) buf; 180 if (drv->we_version_compiled < 21) { 181 /* For historic reasons, set SSID length to include one extra 182 * character, C string nul termination, even though SSID is 183 * really an octet string that should not be presented as a C 184 * string. Some Linux drivers decrement the length by one and 185 * can thus end up missing the last octet of the SSID if the 186 * length is not incremented here. WE-21 changes this to 187 * explicitly require the length _not_ to include nul 188 * termination. */ 189 if (ssid_len) 190 ssid_len++; 191 } 192 iwr.u.essid.length = ssid_len; 193 194 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 195 perror("ioctl[SIOCSIWESSID]"); 196 ret = -1; 197 } 198 199 return ret; 200} 201 202 203/** 204 * wpa_driver_wext_set_freq - Set frequency/channel, SIOCSIWFREQ 205 * @priv: Pointer to private wext data from wpa_driver_wext_init() 206 * @freq: Frequency in MHz 207 * Returns: 0 on success, -1 on failure 208 */ 209int wpa_driver_wext_set_freq(void *priv, int freq) 210{ 211 struct wpa_driver_wext_data *drv = priv; 212 struct iwreq iwr; 213 int ret = 0; 214 215 os_memset(&iwr, 0, sizeof(iwr)); 216 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 217 iwr.u.freq.m = freq * 100000; 218 iwr.u.freq.e = 1; 219 220 if (ioctl(drv->ioctl_sock, SIOCSIWFREQ, &iwr) < 0) { 221 perror("ioctl[SIOCSIWFREQ]"); 222 ret = -1; 223 } 224 225 return ret; 226} 227 228 229static void 230wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) 231{ 232 union wpa_event_data data; 233 234 wpa_printf(MSG_MSGDUMP, "WEXT: Custom wireless event: '%s'", 235 custom); 236 237 os_memset(&data, 0, sizeof(data)); 238 /* Host AP driver */ 239 if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 240 data.michael_mic_failure.unicast = 241 os_strstr(custom, " unicast ") != NULL; 242 /* TODO: parse parameters(?) */ 243 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 244 } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) { 245 char *spos; 246 int bytes; 247 u8 *req_ies = NULL, *resp_ies = NULL; 248 249 spos = custom + 17; 250 251 bytes = strspn(spos, "0123456789abcdefABCDEF"); 252 if (!bytes || (bytes & 1)) 253 return; 254 bytes /= 2; 255 256 req_ies = os_malloc(bytes); 257 if (req_ies == NULL || 258 hexstr2bin(spos, req_ies, bytes) < 0) 259 goto done; 260 data.assoc_info.req_ies = req_ies; 261 data.assoc_info.req_ies_len = bytes; 262 263 spos += bytes * 2; 264 265 data.assoc_info.resp_ies = NULL; 266 data.assoc_info.resp_ies_len = 0; 267 268 if (os_strncmp(spos, " RespIEs=", 9) == 0) { 269 spos += 9; 270 271 bytes = strspn(spos, "0123456789abcdefABCDEF"); 272 if (!bytes || (bytes & 1)) 273 goto done; 274 bytes /= 2; 275 276 resp_ies = os_malloc(bytes); 277 if (resp_ies == NULL || 278 hexstr2bin(spos, resp_ies, bytes) < 0) 279 goto done; 280 data.assoc_info.resp_ies = resp_ies; 281 data.assoc_info.resp_ies_len = bytes; 282 } 283 284 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); 285 286 done: 287 os_free(resp_ies); 288 os_free(req_ies); 289#ifdef CONFIG_PEERKEY 290 } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) { 291 if (hwaddr_aton(custom + 17, data.stkstart.peer)) { 292 wpa_printf(MSG_DEBUG, "WEXT: unrecognized " 293 "STKSTART.request '%s'", custom + 17); 294 return; 295 } 296 wpa_supplicant_event(ctx, EVENT_STKSTART, &data); 297#endif /* CONFIG_PEERKEY */ 298 } 299} 300 301 302static int wpa_driver_wext_event_wireless_michaelmicfailure( 303 void *ctx, const char *ev, size_t len) 304{ 305 const struct iw_michaelmicfailure *mic; 306 union wpa_event_data data; 307 308 if (len < sizeof(*mic)) 309 return -1; 310 311 mic = (const struct iw_michaelmicfailure *) ev; 312 313 wpa_printf(MSG_DEBUG, "Michael MIC failure wireless event: " 314 "flags=0x%x src_addr=" MACSTR, mic->flags, 315 MAC2STR(mic->src_addr.sa_data)); 316 317 os_memset(&data, 0, sizeof(data)); 318 data.michael_mic_failure.unicast = !(mic->flags & IW_MICFAILURE_GROUP); 319 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 320 321 return 0; 322} 323 324 325static int wpa_driver_wext_event_wireless_pmkidcand( 326 struct wpa_driver_wext_data *drv, const char *ev, size_t len) 327{ 328 const struct iw_pmkid_cand *cand; 329 union wpa_event_data data; 330 const u8 *addr; 331 332 if (len < sizeof(*cand)) 333 return -1; 334 335 cand = (const struct iw_pmkid_cand *) ev; 336 addr = (const u8 *) cand->bssid.sa_data; 337 338 wpa_printf(MSG_DEBUG, "PMKID candidate wireless event: " 339 "flags=0x%x index=%d bssid=" MACSTR, cand->flags, 340 cand->index, MAC2STR(addr)); 341 342 os_memset(&data, 0, sizeof(data)); 343 os_memcpy(data.pmkid_candidate.bssid, addr, ETH_ALEN); 344 data.pmkid_candidate.index = cand->index; 345 data.pmkid_candidate.preauth = cand->flags & IW_PMKID_CAND_PREAUTH; 346 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data); 347 348 return 0; 349} 350 351 352static int wpa_driver_wext_event_wireless_assocreqie( 353 struct wpa_driver_wext_data *drv, const char *ev, int len) 354{ 355 if (len < 0) 356 return -1; 357 358 wpa_hexdump(MSG_DEBUG, "AssocReq IE wireless event", (const u8 *) ev, 359 len); 360 os_free(drv->assoc_req_ies); 361 drv->assoc_req_ies = os_malloc(len); 362 if (drv->assoc_req_ies == NULL) { 363 drv->assoc_req_ies_len = 0; 364 return -1; 365 } 366 os_memcpy(drv->assoc_req_ies, ev, len); 367 drv->assoc_req_ies_len = len; 368 369 return 0; 370} 371 372 373static int wpa_driver_wext_event_wireless_assocrespie( 374 struct wpa_driver_wext_data *drv, const char *ev, int len) 375{ 376 if (len < 0) 377 return -1; 378 379 wpa_hexdump(MSG_DEBUG, "AssocResp IE wireless event", (const u8 *) ev, 380 len); 381 os_free(drv->assoc_resp_ies); 382 drv->assoc_resp_ies = os_malloc(len); 383 if (drv->assoc_resp_ies == NULL) { 384 drv->assoc_resp_ies_len = 0; 385 return -1; 386 } 387 os_memcpy(drv->assoc_resp_ies, ev, len); 388 drv->assoc_resp_ies_len = len; 389 390 return 0; 391} 392 393 394static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv) 395{ 396 union wpa_event_data data; 397 398 if (drv->assoc_req_ies == NULL && drv->assoc_resp_ies == NULL) 399 return; 400 401 os_memset(&data, 0, sizeof(data)); 402 if (drv->assoc_req_ies) { 403 data.assoc_info.req_ies = drv->assoc_req_ies; 404 data.assoc_info.req_ies_len = drv->assoc_req_ies_len; 405 } 406 if (drv->assoc_resp_ies) { 407 data.assoc_info.resp_ies = drv->assoc_resp_ies; 408 data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len; 409 } 410 411 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); 412 413 os_free(drv->assoc_req_ies); 414 drv->assoc_req_ies = NULL; 415 os_free(drv->assoc_resp_ies); 416 drv->assoc_resp_ies = NULL; 417} 418 419 420static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv, 421 char *data, int len) 422{ 423 struct iw_event iwe_buf, *iwe = &iwe_buf; 424 char *pos, *end, *custom, *buf; 425 426 pos = data; 427 end = data + len; 428 429 while (pos + IW_EV_LCP_LEN <= end) { 430 /* Event data may be unaligned, so make a local, aligned copy 431 * before processing. */ 432 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 433 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d", 434 iwe->cmd, iwe->len); 435 if (iwe->len <= IW_EV_LCP_LEN) 436 return; 437 438 custom = pos + IW_EV_POINT_LEN; 439 if (drv->we_version_compiled > 18 && 440 (iwe->cmd == IWEVMICHAELMICFAILURE || 441 iwe->cmd == IWEVCUSTOM || 442 iwe->cmd == IWEVASSOCREQIE || 443 iwe->cmd == IWEVASSOCRESPIE || 444 iwe->cmd == IWEVPMKIDCAND)) { 445 /* WE-19 removed the pointer from struct iw_point */ 446 char *dpos = (char *) &iwe_buf.u.data.length; 447 int dlen = dpos - (char *) &iwe_buf; 448 os_memcpy(dpos, pos + IW_EV_LCP_LEN, 449 sizeof(struct iw_event) - dlen); 450 } else { 451 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 452 custom += IW_EV_POINT_OFF; 453 } 454 455 switch (iwe->cmd) { 456 case SIOCGIWAP: 457 wpa_printf(MSG_DEBUG, "Wireless event: new AP: " 458 MACSTR, 459 MAC2STR((u8 *) iwe->u.ap_addr.sa_data)); 460 if (is_zero_ether_addr( 461 (const u8 *) iwe->u.ap_addr.sa_data) || 462 os_memcmp(iwe->u.ap_addr.sa_data, 463 "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 464 0) { 465 os_free(drv->assoc_req_ies); 466 drv->assoc_req_ies = NULL; 467 os_free(drv->assoc_resp_ies); 468 drv->assoc_resp_ies = NULL; 469 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, 470 NULL); 471 472 } else { 473 wpa_driver_wext_event_assoc_ies(drv); 474 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, 475 NULL); 476 } 477 break; 478 case IWEVMICHAELMICFAILURE: 479 if (custom + iwe->u.data.length > end) { 480 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 481 "IWEVMICHAELMICFAILURE length"); 482 return; 483 } 484 wpa_driver_wext_event_wireless_michaelmicfailure( 485 drv->ctx, custom, iwe->u.data.length); 486 break; 487 case IWEVCUSTOM: 488 if (custom + iwe->u.data.length > end) { 489 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 490 "IWEVCUSTOM length"); 491 return; 492 } 493 buf = dup_binstr(custom, iwe->u.data.length); 494 if (buf == NULL) 495 return; 496 wpa_driver_wext_event_wireless_custom(drv->ctx, buf); 497 os_free(buf); 498 break; 499 case SIOCGIWSCAN: 500 drv->scan_complete_events = 1; 501 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, 502 drv, drv->ctx); 503 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, 504 NULL); 505 break; 506 case IWEVASSOCREQIE: 507 if (custom + iwe->u.data.length > end) { 508 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 509 "IWEVASSOCREQIE length"); 510 return; 511 } 512 wpa_driver_wext_event_wireless_assocreqie( 513 drv, custom, iwe->u.data.length); 514 break; 515 case IWEVASSOCRESPIE: 516 if (custom + iwe->u.data.length > end) { 517 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 518 "IWEVASSOCRESPIE length"); 519 return; 520 } 521 wpa_driver_wext_event_wireless_assocrespie( 522 drv, custom, iwe->u.data.length); 523 break; 524 case IWEVPMKIDCAND: 525 if (custom + iwe->u.data.length > end) { 526 wpa_printf(MSG_DEBUG, "WEXT: Invalid " 527 "IWEVPMKIDCAND length"); 528 return; 529 } 530 wpa_driver_wext_event_wireless_pmkidcand( 531 drv, custom, iwe->u.data.length); 532 break; 533 } 534 535 pos += iwe->len; 536 } 537} 538 539 540static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv, 541 char *buf, size_t len, int del) 542{ 543 union wpa_event_data event; 544 545 os_memset(&event, 0, sizeof(event)); 546 if (len > sizeof(event.interface_status.ifname)) 547 len = sizeof(event.interface_status.ifname) - 1; 548 os_memcpy(event.interface_status.ifname, buf, len); 549 event.interface_status.ievent = del ? EVENT_INTERFACE_REMOVED : 550 EVENT_INTERFACE_ADDED; 551 552 wpa_printf(MSG_DEBUG, "RTM_%sLINK, IFLA_IFNAME: Interface '%s' %s", 553 del ? "DEL" : "NEW", 554 event.interface_status.ifname, 555 del ? "removed" : "added"); 556 557 if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) { 558 if (del) { 559 if (drv->if_removed) { 560 wpa_printf(MSG_DEBUG, "WEXT: if_removed " 561 "already set - ignore event"); 562 return; 563 } 564 drv->if_removed = 1; 565 } else { 566 if (if_nametoindex(drv->ifname) == 0) { 567 wpa_printf(MSG_DEBUG, "WEXT: Interface %s " 568 "does not exist - ignore " 569 "RTM_NEWLINK", 570 drv->ifname); 571 return; 572 } 573 if (!drv->if_removed) { 574 wpa_printf(MSG_DEBUG, "WEXT: if_removed " 575 "already cleared - ignore event"); 576 return; 577 } 578 drv->if_removed = 0; 579 } 580 } 581 582 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 583} 584 585 586static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv, 587 u8 *buf, size_t len) 588{ 589 int attrlen, rta_len; 590 struct rtattr *attr; 591 592 attrlen = len; 593 attr = (struct rtattr *) buf; 594 595 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 596 while (RTA_OK(attr, attrlen)) { 597 if (attr->rta_type == IFLA_IFNAME) { 598 if (os_strcmp(((char *) attr) + rta_len, drv->ifname) 599 == 0) 600 return 1; 601 else 602 break; 603 } 604 attr = RTA_NEXT(attr, attrlen); 605 } 606 607 return 0; 608} 609 610 611static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv, 612 int ifindex, u8 *buf, size_t len) 613{ 614 if (drv->ifindex == ifindex || drv->ifindex2 == ifindex) 615 return 1; 616 617 if (drv->if_removed && wpa_driver_wext_own_ifname(drv, buf, len)) { 618 drv->ifindex = if_nametoindex(drv->ifname); 619 wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed " 620 "interface"); 621 wpa_driver_wext_finish_drv_init(drv); 622 return 1; 623 } 624 625 return 0; 626} 627 628 629static void wpa_driver_wext_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, 630 u8 *buf, size_t len) 631{ 632 struct wpa_driver_wext_data *drv = ctx; 633 int attrlen, rta_len; 634 struct rtattr *attr; 635 char namebuf[IFNAMSIZ]; 636 637 if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, buf, len)) { 638 wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d", 639 ifi->ifi_index); 640 return; 641 } 642 643 wpa_printf(MSG_DEBUG, "RTM_NEWLINK: operstate=%d ifi_flags=0x%x " 644 "(%s%s%s%s)", 645 drv->operstate, ifi->ifi_flags, 646 (ifi->ifi_flags & IFF_UP) ? "[UP]" : "", 647 (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "", 648 (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "", 649 (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : ""); 650 651 if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) { 652 wpa_printf(MSG_DEBUG, "WEXT: Interface down"); 653 drv->if_disabled = 1; 654 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL); 655 } 656 657 if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) { 658 if (if_indextoname(ifi->ifi_index, namebuf) && 659 linux_iface_up(drv->ioctl_sock, drv->ifname) == 0) { 660 wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up " 661 "event since interface %s is down", 662 namebuf); 663 } else if (if_nametoindex(drv->ifname) == 0) { 664 wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up " 665 "event since interface %s does not exist", 666 drv->ifname); 667 } else if (drv->if_removed) { 668 wpa_printf(MSG_DEBUG, "WEXT: Ignore interface up " 669 "event since interface %s is marked " 670 "removed", drv->ifname); 671 } else { 672 wpa_printf(MSG_DEBUG, "WEXT: Interface up"); 673 drv->if_disabled = 0; 674 wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, 675 NULL); 676 } 677 } 678 679 /* 680 * Some drivers send the association event before the operup event--in 681 * this case, lifting operstate in wpa_driver_wext_set_operstate() 682 * fails. This will hit us when wpa_supplicant does not need to do 683 * IEEE 802.1X authentication 684 */ 685 if (drv->operstate == 1 && 686 (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP && 687 !(ifi->ifi_flags & IFF_RUNNING)) 688 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 689 -1, IF_OPER_UP); 690 691 attrlen = len; 692 attr = (struct rtattr *) buf; 693 694 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 695 while (RTA_OK(attr, attrlen)) { 696 if (attr->rta_type == IFLA_WIRELESS) { 697 wpa_driver_wext_event_wireless( 698 drv, ((char *) attr) + rta_len, 699 attr->rta_len - rta_len); 700 } else if (attr->rta_type == IFLA_IFNAME) { 701 wpa_driver_wext_event_link(drv, 702 ((char *) attr) + rta_len, 703 attr->rta_len - rta_len, 0); 704 } 705 attr = RTA_NEXT(attr, attrlen); 706 } 707} 708 709 710static void wpa_driver_wext_event_rtm_dellink(void *ctx, struct ifinfomsg *ifi, 711 u8 *buf, size_t len) 712{ 713 struct wpa_driver_wext_data *drv = ctx; 714 int attrlen, rta_len; 715 struct rtattr *attr; 716 717 attrlen = len; 718 attr = (struct rtattr *) buf; 719 720 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 721 while (RTA_OK(attr, attrlen)) { 722 if (attr->rta_type == IFLA_IFNAME) { 723 wpa_driver_wext_event_link(drv, 724 ((char *) attr) + rta_len, 725 attr->rta_len - rta_len, 1); 726 } 727 attr = RTA_NEXT(attr, attrlen); 728 } 729} 730 731 732static void wpa_driver_wext_rfkill_blocked(void *ctx) 733{ 734 wpa_printf(MSG_DEBUG, "WEXT: RFKILL blocked"); 735 /* 736 * This may be for any interface; use ifdown event to disable 737 * interface. 738 */ 739} 740 741 742static void wpa_driver_wext_rfkill_unblocked(void *ctx) 743{ 744 struct wpa_driver_wext_data *drv = ctx; 745 wpa_printf(MSG_DEBUG, "WEXT: RFKILL unblocked"); 746 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) { 747 wpa_printf(MSG_DEBUG, "WEXT: Could not set interface UP " 748 "after rfkill unblock"); 749 return; 750 } 751 /* rtnetlink ifup handler will report interface as enabled */ 752} 753 754 755static void wext_get_phy_name(struct wpa_driver_wext_data *drv) 756{ 757 /* Find phy (radio) to which this interface belongs */ 758 char buf[90], *pos; 759 int f, rv; 760 761 drv->phyname[0] = '\0'; 762 snprintf(buf, sizeof(buf) - 1, "/sys/class/net/%s/phy80211/name", 763 drv->ifname); 764 f = open(buf, O_RDONLY); 765 if (f < 0) { 766 wpa_printf(MSG_DEBUG, "Could not open file %s: %s", 767 buf, strerror(errno)); 768 return; 769 } 770 771 rv = read(f, drv->phyname, sizeof(drv->phyname) - 1); 772 close(f); 773 if (rv < 0) { 774 wpa_printf(MSG_DEBUG, "Could not read file %s: %s", 775 buf, strerror(errno)); 776 return; 777 } 778 779 drv->phyname[rv] = '\0'; 780 pos = os_strchr(drv->phyname, '\n'); 781 if (pos) 782 *pos = '\0'; 783 wpa_printf(MSG_DEBUG, "wext: interface %s phy: %s", 784 drv->ifname, drv->phyname); 785} 786 787 788/** 789 * wpa_driver_wext_init - Initialize WE driver interface 790 * @ctx: context to be used when calling wpa_supplicant functions, 791 * e.g., wpa_supplicant_event() 792 * @ifname: interface name, e.g., wlan0 793 * Returns: Pointer to private data, %NULL on failure 794 */ 795void * wpa_driver_wext_init(void *ctx, const char *ifname) 796{ 797 struct wpa_driver_wext_data *drv; 798 struct netlink_config *cfg; 799 struct rfkill_config *rcfg; 800 char path[128]; 801 struct stat buf; 802 803 drv = os_zalloc(sizeof(*drv)); 804 if (drv == NULL) 805 return NULL; 806 drv->ctx = ctx; 807 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 808 809 os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname); 810 if (stat(path, &buf) == 0) { 811 wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected"); 812 drv->cfg80211 = 1; 813 wext_get_phy_name(drv); 814 } 815 816 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 817 if (drv->ioctl_sock < 0) { 818 perror("socket(PF_INET,SOCK_DGRAM)"); 819 goto err1; 820 } 821 822 cfg = os_zalloc(sizeof(*cfg)); 823 if (cfg == NULL) 824 goto err1; 825 cfg->ctx = drv; 826 cfg->newlink_cb = wpa_driver_wext_event_rtm_newlink; 827 cfg->dellink_cb = wpa_driver_wext_event_rtm_dellink; 828 drv->netlink = netlink_init(cfg); 829 if (drv->netlink == NULL) { 830 os_free(cfg); 831 goto err2; 832 } 833 834 rcfg = os_zalloc(sizeof(*rcfg)); 835 if (rcfg == NULL) 836 goto err3; 837 rcfg->ctx = drv; 838 os_strlcpy(rcfg->ifname, ifname, sizeof(rcfg->ifname)); 839 rcfg->blocked_cb = wpa_driver_wext_rfkill_blocked; 840 rcfg->unblocked_cb = wpa_driver_wext_rfkill_unblocked; 841 drv->rfkill = rfkill_init(rcfg); 842 if (drv->rfkill == NULL) { 843 wpa_printf(MSG_DEBUG, "WEXT: RFKILL status not available"); 844 os_free(rcfg); 845 } 846 847 drv->mlme_sock = -1; 848 849 if (wpa_driver_wext_finish_drv_init(drv) < 0) 850 goto err3; 851 852 wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 1); 853 854 return drv; 855 856err3: 857 rfkill_deinit(drv->rfkill); 858 netlink_deinit(drv->netlink); 859err2: 860 close(drv->ioctl_sock); 861err1: 862 os_free(drv); 863 return NULL; 864} 865 866 867static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx) 868{ 869 wpa_supplicant_event(timeout_ctx, EVENT_INTERFACE_DISABLED, NULL); 870} 871 872 873static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv) 874{ 875 int send_rfkill_event = 0; 876 877 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1) < 0) { 878 if (rfkill_is_blocked(drv->rfkill)) { 879 wpa_printf(MSG_DEBUG, "WEXT: Could not yet enable " 880 "interface '%s' due to rfkill", 881 drv->ifname); 882 drv->if_disabled = 1; 883 send_rfkill_event = 1; 884 } else { 885 wpa_printf(MSG_ERROR, "WEXT: Could not set " 886 "interface '%s' UP", drv->ifname); 887 return -1; 888 } 889 } 890 891 /* 892 * Make sure that the driver does not have any obsolete PMKID entries. 893 */ 894 wpa_driver_wext_flush_pmkid(drv); 895 896 if (wpa_driver_wext_set_mode(drv, 0) < 0) { 897 wpa_printf(MSG_DEBUG, "Could not configure driver to use " 898 "managed mode"); 899 /* Try to use it anyway */ 900 } 901 902 wpa_driver_wext_get_range(drv); 903 904 /* 905 * Unlock the driver's BSSID and force to a random SSID to clear any 906 * previous association the driver might have when the supplicant 907 * starts up. 908 */ 909 wpa_driver_wext_disconnect(drv); 910 911 drv->ifindex = if_nametoindex(drv->ifname); 912 913 if (os_strncmp(drv->ifname, "wlan", 4) == 0) { 914 /* 915 * Host AP driver may use both wlan# and wifi# interface in 916 * wireless events. Since some of the versions included WE-18 917 * support, let's add the alternative ifindex also from 918 * driver_wext.c for the time being. This may be removed at 919 * some point once it is believed that old versions of the 920 * driver are not in use anymore. 921 */ 922 char ifname2[IFNAMSIZ + 1]; 923 os_strlcpy(ifname2, drv->ifname, sizeof(ifname2)); 924 os_memcpy(ifname2, "wifi", 4); 925 wpa_driver_wext_alternative_ifindex(drv, ifname2); 926 } 927 928 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 929 1, IF_OPER_DORMANT); 930 931 if (send_rfkill_event) { 932 eloop_register_timeout(0, 0, wpa_driver_wext_send_rfkill, 933 drv, drv->ctx); 934 } 935 936 return 0; 937} 938 939 940/** 941 * wpa_driver_wext_deinit - Deinitialize WE driver interface 942 * @priv: Pointer to private wext data from wpa_driver_wext_init() 943 * 944 * Shut down driver interface and processing of driver events. Free 945 * private data buffer if one was allocated in wpa_driver_wext_init(). 946 */ 947void wpa_driver_wext_deinit(void *priv) 948{ 949 struct wpa_driver_wext_data *drv = priv; 950 951 wpa_driver_wext_set_auth_param(drv, IW_AUTH_WPA_ENABLED, 0); 952 953 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); 954 955 /* 956 * Clear possibly configured driver parameters in order to make it 957 * easier to use the driver after wpa_supplicant has been terminated. 958 */ 959 wpa_driver_wext_disconnect(drv); 960 961 netlink_send_oper_ifla(drv->netlink, drv->ifindex, 0, IF_OPER_UP); 962 netlink_deinit(drv->netlink); 963 rfkill_deinit(drv->rfkill); 964 965 if (drv->mlme_sock >= 0) 966 eloop_unregister_read_sock(drv->mlme_sock); 967 968 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); 969 970 close(drv->ioctl_sock); 971 if (drv->mlme_sock >= 0) 972 close(drv->mlme_sock); 973 os_free(drv->assoc_req_ies); 974 os_free(drv->assoc_resp_ies); 975 os_free(drv); 976} 977 978 979/** 980 * wpa_driver_wext_scan_timeout - Scan timeout to report scan completion 981 * @eloop_ctx: Unused 982 * @timeout_ctx: ctx argument given to wpa_driver_wext_init() 983 * 984 * This function can be used as registered timeout when starting a scan to 985 * generate a scan completed event if the driver does not report this. 986 */ 987void wpa_driver_wext_scan_timeout(void *eloop_ctx, void *timeout_ctx) 988{ 989 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 990 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 991} 992 993 994/** 995 * wpa_driver_wext_scan - Request the driver to initiate scan 996 * @priv: Pointer to private wext data from wpa_driver_wext_init() 997 * @param: Scan parameters (specific SSID to scan for (ProbeReq), etc.) 998 * Returns: 0 on success, -1 on failure 999 */ 1000int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params) 1001{ 1002 struct wpa_driver_wext_data *drv = priv; 1003 struct iwreq iwr; 1004 int ret = 0, timeout; 1005 struct iw_scan_req req; 1006 const u8 *ssid = params->ssids[0].ssid; 1007 size_t ssid_len = params->ssids[0].ssid_len; 1008 1009 if (ssid_len > IW_ESSID_MAX_SIZE) { 1010 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)", 1011 __FUNCTION__, (unsigned long) ssid_len); 1012 return -1; 1013 } 1014 1015 os_memset(&iwr, 0, sizeof(iwr)); 1016 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1017 1018 if (ssid && ssid_len) { 1019 os_memset(&req, 0, sizeof(req)); 1020 req.essid_len = ssid_len; 1021 req.bssid.sa_family = ARPHRD_ETHER; 1022 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN); 1023 os_memcpy(req.essid, ssid, ssid_len); 1024 iwr.u.data.pointer = (caddr_t) &req; 1025 iwr.u.data.length = sizeof(req); 1026 iwr.u.data.flags = IW_SCAN_THIS_ESSID; 1027 } 1028 1029 if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) { 1030 perror("ioctl[SIOCSIWSCAN]"); 1031 ret = -1; 1032 } 1033 1034 /* Not all drivers generate "scan completed" wireless event, so try to 1035 * read results after a timeout. */ 1036 timeout = 10; 1037 if (drv->scan_complete_events) { 1038 /* 1039 * The driver seems to deliver SIOCGIWSCAN events to notify 1040 * when scan is complete, so use longer timeout to avoid race 1041 * conditions with scanning and following association request. 1042 */ 1043 timeout = 30; 1044 } 1045 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d " 1046 "seconds", ret, timeout); 1047 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx); 1048 eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv, 1049 drv->ctx); 1050 1051 return ret; 1052} 1053 1054 1055static u8 * wpa_driver_wext_giwscan(struct wpa_driver_wext_data *drv, 1056 size_t *len) 1057{ 1058 struct iwreq iwr; 1059 u8 *res_buf; 1060 size_t res_buf_len; 1061 1062 res_buf_len = IW_SCAN_MAX_DATA; 1063 for (;;) { 1064 res_buf = os_malloc(res_buf_len); 1065 if (res_buf == NULL) 1066 return NULL; 1067 os_memset(&iwr, 0, sizeof(iwr)); 1068 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1069 iwr.u.data.pointer = res_buf; 1070 iwr.u.data.length = res_buf_len; 1071 1072 if (ioctl(drv->ioctl_sock, SIOCGIWSCAN, &iwr) == 0) 1073 break; 1074 1075 if (errno == E2BIG && res_buf_len < 65535) { 1076 os_free(res_buf); 1077 res_buf = NULL; 1078 res_buf_len *= 2; 1079 if (res_buf_len > 65535) 1080 res_buf_len = 65535; /* 16-bit length field */ 1081 wpa_printf(MSG_DEBUG, "Scan results did not fit - " 1082 "trying larger buffer (%lu bytes)", 1083 (unsigned long) res_buf_len); 1084 } else { 1085 perror("ioctl[SIOCGIWSCAN]"); 1086 os_free(res_buf); 1087 return NULL; 1088 } 1089 } 1090 1091 if (iwr.u.data.length > res_buf_len) { 1092 os_free(res_buf); 1093 return NULL; 1094 } 1095 *len = iwr.u.data.length; 1096 1097 return res_buf; 1098} 1099 1100 1101/* 1102 * Data structure for collecting WEXT scan results. This is needed to allow 1103 * the various methods of reporting IEs to be combined into a single IE buffer. 1104 */ 1105struct wext_scan_data { 1106 struct wpa_scan_res res; 1107 u8 *ie; 1108 size_t ie_len; 1109 u8 ssid[32]; 1110 size_t ssid_len; 1111 int maxrate; 1112}; 1113 1114 1115static void wext_get_scan_mode(struct iw_event *iwe, 1116 struct wext_scan_data *res) 1117{ 1118 if (iwe->u.mode == IW_MODE_ADHOC) 1119 res->res.caps |= IEEE80211_CAP_IBSS; 1120 else if (iwe->u.mode == IW_MODE_MASTER || iwe->u.mode == IW_MODE_INFRA) 1121 res->res.caps |= IEEE80211_CAP_ESS; 1122} 1123 1124 1125static void wext_get_scan_ssid(struct iw_event *iwe, 1126 struct wext_scan_data *res, char *custom, 1127 char *end) 1128{ 1129 int ssid_len = iwe->u.essid.length; 1130 if (custom + ssid_len > end) 1131 return; 1132 if (iwe->u.essid.flags && 1133 ssid_len > 0 && 1134 ssid_len <= IW_ESSID_MAX_SIZE) { 1135 os_memcpy(res->ssid, custom, ssid_len); 1136 res->ssid_len = ssid_len; 1137 } 1138} 1139 1140 1141static void wext_get_scan_freq(struct iw_event *iwe, 1142 struct wext_scan_data *res) 1143{ 1144 int divi = 1000000, i; 1145 1146 if (iwe->u.freq.e == 0) { 1147 /* 1148 * Some drivers do not report frequency, but a channel. 1149 * Try to map this to frequency by assuming they are using 1150 * IEEE 802.11b/g. But don't overwrite a previously parsed 1151 * frequency if the driver sends both frequency and channel, 1152 * since the driver may be sending an A-band channel that we 1153 * don't handle here. 1154 */ 1155 1156 if (res->res.freq) 1157 return; 1158 1159 if (iwe->u.freq.m >= 1 && iwe->u.freq.m <= 13) { 1160 res->res.freq = 2407 + 5 * iwe->u.freq.m; 1161 return; 1162 } else if (iwe->u.freq.m == 14) { 1163 res->res.freq = 2484; 1164 return; 1165 } 1166 } 1167 1168 if (iwe->u.freq.e > 6) { 1169 wpa_printf(MSG_DEBUG, "Invalid freq in scan results (BSSID=" 1170 MACSTR " m=%d e=%d)", 1171 MAC2STR(res->res.bssid), iwe->u.freq.m, 1172 iwe->u.freq.e); 1173 return; 1174 } 1175 1176 for (i = 0; i < iwe->u.freq.e; i++) 1177 divi /= 10; 1178 res->res.freq = iwe->u.freq.m / divi; 1179} 1180 1181 1182static void wext_get_scan_qual(struct wpa_driver_wext_data *drv, 1183 struct iw_event *iwe, 1184 struct wext_scan_data *res) 1185{ 1186 res->res.qual = iwe->u.qual.qual; 1187 res->res.noise = iwe->u.qual.noise; 1188 res->res.level = iwe->u.qual.level; 1189 if (iwe->u.qual.updated & IW_QUAL_QUAL_INVALID) 1190 res->res.flags |= WPA_SCAN_QUAL_INVALID; 1191 if (iwe->u.qual.updated & IW_QUAL_LEVEL_INVALID) 1192 res->res.flags |= WPA_SCAN_LEVEL_INVALID; 1193 if (iwe->u.qual.updated & IW_QUAL_NOISE_INVALID) 1194 res->res.flags |= WPA_SCAN_NOISE_INVALID; 1195 if (iwe->u.qual.updated & IW_QUAL_DBM) 1196 res->res.flags |= WPA_SCAN_LEVEL_DBM; 1197 if ((iwe->u.qual.updated & IW_QUAL_DBM) || 1198 ((iwe->u.qual.level != 0) && 1199 (iwe->u.qual.level > drv->max_level))) { 1200 if (iwe->u.qual.level >= 64) 1201 res->res.level -= 0x100; 1202 if (iwe->u.qual.noise >= 64) 1203 res->res.noise -= 0x100; 1204 } 1205} 1206 1207 1208static void wext_get_scan_encode(struct iw_event *iwe, 1209 struct wext_scan_data *res) 1210{ 1211 if (!(iwe->u.data.flags & IW_ENCODE_DISABLED)) 1212 res->res.caps |= IEEE80211_CAP_PRIVACY; 1213} 1214 1215 1216static void wext_get_scan_rate(struct iw_event *iwe, 1217 struct wext_scan_data *res, char *pos, 1218 char *end) 1219{ 1220 int maxrate; 1221 char *custom = pos + IW_EV_LCP_LEN; 1222 struct iw_param p; 1223 size_t clen; 1224 1225 clen = iwe->len; 1226 if (custom + clen > end) 1227 return; 1228 maxrate = 0; 1229 while (((ssize_t) clen) >= (ssize_t) sizeof(struct iw_param)) { 1230 /* Note: may be misaligned, make a local, aligned copy */ 1231 os_memcpy(&p, custom, sizeof(struct iw_param)); 1232 if (p.value > maxrate) 1233 maxrate = p.value; 1234 clen -= sizeof(struct iw_param); 1235 custom += sizeof(struct iw_param); 1236 } 1237 1238 /* Convert the maxrate from WE-style (b/s units) to 1239 * 802.11 rates (500000 b/s units). 1240 */ 1241 res->maxrate = maxrate / 500000; 1242} 1243 1244 1245static void wext_get_scan_iwevgenie(struct iw_event *iwe, 1246 struct wext_scan_data *res, char *custom, 1247 char *end) 1248{ 1249 char *genie, *gpos, *gend; 1250 u8 *tmp; 1251 1252 if (iwe->u.data.length == 0) 1253 return; 1254 1255 gpos = genie = custom; 1256 gend = genie + iwe->u.data.length; 1257 if (gend > end) { 1258 wpa_printf(MSG_INFO, "IWEVGENIE overflow"); 1259 return; 1260 } 1261 1262 tmp = os_realloc(res->ie, res->ie_len + gend - gpos); 1263 if (tmp == NULL) 1264 return; 1265 os_memcpy(tmp + res->ie_len, gpos, gend - gpos); 1266 res->ie = tmp; 1267 res->ie_len += gend - gpos; 1268} 1269 1270 1271static void wext_get_scan_custom(struct iw_event *iwe, 1272 struct wext_scan_data *res, char *custom, 1273 char *end) 1274{ 1275 size_t clen; 1276 u8 *tmp; 1277 1278 clen = iwe->u.data.length; 1279 if (custom + clen > end) 1280 return; 1281 1282 if (clen > 7 && os_strncmp(custom, "wpa_ie=", 7) == 0) { 1283 char *spos; 1284 int bytes; 1285 spos = custom + 7; 1286 bytes = custom + clen - spos; 1287 if (bytes & 1 || bytes == 0) 1288 return; 1289 bytes /= 2; 1290 tmp = os_realloc(res->ie, res->ie_len + bytes); 1291 if (tmp == NULL) 1292 return; 1293 res->ie = tmp; 1294 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0) 1295 return; 1296 res->ie_len += bytes; 1297 } else if (clen > 7 && os_strncmp(custom, "rsn_ie=", 7) == 0) { 1298 char *spos; 1299 int bytes; 1300 spos = custom + 7; 1301 bytes = custom + clen - spos; 1302 if (bytes & 1 || bytes == 0) 1303 return; 1304 bytes /= 2; 1305 tmp = os_realloc(res->ie, res->ie_len + bytes); 1306 if (tmp == NULL) 1307 return; 1308 res->ie = tmp; 1309 if (hexstr2bin(spos, tmp + res->ie_len, bytes) < 0) 1310 return; 1311 res->ie_len += bytes; 1312 } else if (clen > 4 && os_strncmp(custom, "tsf=", 4) == 0) { 1313 char *spos; 1314 int bytes; 1315 u8 bin[8]; 1316 spos = custom + 4; 1317 bytes = custom + clen - spos; 1318 if (bytes != 16) { 1319 wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes); 1320 return; 1321 } 1322 bytes /= 2; 1323 if (hexstr2bin(spos, bin, bytes) < 0) { 1324 wpa_printf(MSG_DEBUG, "WEXT: Invalid TSF value"); 1325 return; 1326 } 1327 res->res.tsf += WPA_GET_BE64(bin); 1328 } 1329} 1330 1331 1332static int wext_19_iw_point(struct wpa_driver_wext_data *drv, u16 cmd) 1333{ 1334 return drv->we_version_compiled > 18 && 1335 (cmd == SIOCGIWESSID || cmd == SIOCGIWENCODE || 1336 cmd == IWEVGENIE || cmd == IWEVCUSTOM); 1337} 1338 1339 1340static void wpa_driver_wext_add_scan_entry(struct wpa_scan_results *res, 1341 struct wext_scan_data *data) 1342{ 1343 struct wpa_scan_res **tmp; 1344 struct wpa_scan_res *r; 1345 size_t extra_len; 1346 u8 *pos, *end, *ssid_ie = NULL, *rate_ie = NULL; 1347 1348 /* Figure out whether we need to fake any IEs */ 1349 pos = data->ie; 1350 end = pos + data->ie_len; 1351 while (pos && pos + 1 < end) { 1352 if (pos + 2 + pos[1] > end) 1353 break; 1354 if (pos[0] == WLAN_EID_SSID) 1355 ssid_ie = pos; 1356 else if (pos[0] == WLAN_EID_SUPP_RATES) 1357 rate_ie = pos; 1358 else if (pos[0] == WLAN_EID_EXT_SUPP_RATES) 1359 rate_ie = pos; 1360 pos += 2 + pos[1]; 1361 } 1362 1363 extra_len = 0; 1364 if (ssid_ie == NULL) 1365 extra_len += 2 + data->ssid_len; 1366 if (rate_ie == NULL && data->maxrate) 1367 extra_len += 3; 1368 1369 r = os_zalloc(sizeof(*r) + extra_len + data->ie_len); 1370 if (r == NULL) 1371 return; 1372 os_memcpy(r, &data->res, sizeof(*r)); 1373 r->ie_len = extra_len + data->ie_len; 1374 pos = (u8 *) (r + 1); 1375 if (ssid_ie == NULL) { 1376 /* 1377 * Generate a fake SSID IE since the driver did not report 1378 * a full IE list. 1379 */ 1380 *pos++ = WLAN_EID_SSID; 1381 *pos++ = data->ssid_len; 1382 os_memcpy(pos, data->ssid, data->ssid_len); 1383 pos += data->ssid_len; 1384 } 1385 if (rate_ie == NULL && data->maxrate) { 1386 /* 1387 * Generate a fake Supported Rates IE since the driver did not 1388 * report a full IE list. 1389 */ 1390 *pos++ = WLAN_EID_SUPP_RATES; 1391 *pos++ = 1; 1392 *pos++ = data->maxrate; 1393 } 1394 if (data->ie) 1395 os_memcpy(pos, data->ie, data->ie_len); 1396 1397 tmp = os_realloc_array(res->res, res->num + 1, 1398 sizeof(struct wpa_scan_res *)); 1399 if (tmp == NULL) { 1400 os_free(r); 1401 return; 1402 } 1403 tmp[res->num++] = r; 1404 res->res = tmp; 1405} 1406 1407 1408/** 1409 * wpa_driver_wext_get_scan_results - Fetch the latest scan results 1410 * @priv: Pointer to private wext data from wpa_driver_wext_init() 1411 * Returns: Scan results on success, -1 on failure 1412 */ 1413struct wpa_scan_results * wpa_driver_wext_get_scan_results(void *priv) 1414{ 1415 struct wpa_driver_wext_data *drv = priv; 1416 size_t len; 1417 int first; 1418 u8 *res_buf; 1419 struct iw_event iwe_buf, *iwe = &iwe_buf; 1420 char *pos, *end, *custom; 1421 struct wpa_scan_results *res; 1422 struct wext_scan_data data; 1423 1424 res_buf = wpa_driver_wext_giwscan(drv, &len); 1425 if (res_buf == NULL) 1426 return NULL; 1427 1428 first = 1; 1429 1430 res = os_zalloc(sizeof(*res)); 1431 if (res == NULL) { 1432 os_free(res_buf); 1433 return NULL; 1434 } 1435 1436 pos = (char *) res_buf; 1437 end = (char *) res_buf + len; 1438 os_memset(&data, 0, sizeof(data)); 1439 1440 while (pos + IW_EV_LCP_LEN <= end) { 1441 /* Event data may be unaligned, so make a local, aligned copy 1442 * before processing. */ 1443 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 1444 if (iwe->len <= IW_EV_LCP_LEN) 1445 break; 1446 1447 custom = pos + IW_EV_POINT_LEN; 1448 if (wext_19_iw_point(drv, iwe->cmd)) { 1449 /* WE-19 removed the pointer from struct iw_point */ 1450 char *dpos = (char *) &iwe_buf.u.data.length; 1451 int dlen = dpos - (char *) &iwe_buf; 1452 os_memcpy(dpos, pos + IW_EV_LCP_LEN, 1453 sizeof(struct iw_event) - dlen); 1454 } else { 1455 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 1456 custom += IW_EV_POINT_OFF; 1457 } 1458 1459 switch (iwe->cmd) { 1460 case SIOCGIWAP: 1461 if (!first) 1462 wpa_driver_wext_add_scan_entry(res, &data); 1463 first = 0; 1464 os_free(data.ie); 1465 os_memset(&data, 0, sizeof(data)); 1466 os_memcpy(data.res.bssid, 1467 iwe->u.ap_addr.sa_data, ETH_ALEN); 1468 break; 1469 case SIOCGIWMODE: 1470 wext_get_scan_mode(iwe, &data); 1471 break; 1472 case SIOCGIWESSID: 1473 wext_get_scan_ssid(iwe, &data, custom, end); 1474 break; 1475 case SIOCGIWFREQ: 1476 wext_get_scan_freq(iwe, &data); 1477 break; 1478 case IWEVQUAL: 1479 wext_get_scan_qual(drv, iwe, &data); 1480 break; 1481 case SIOCGIWENCODE: 1482 wext_get_scan_encode(iwe, &data); 1483 break; 1484 case SIOCGIWRATE: 1485 wext_get_scan_rate(iwe, &data, pos, end); 1486 break; 1487 case IWEVGENIE: 1488 wext_get_scan_iwevgenie(iwe, &data, custom, end); 1489 break; 1490 case IWEVCUSTOM: 1491 wext_get_scan_custom(iwe, &data, custom, end); 1492 break; 1493 } 1494 1495 pos += iwe->len; 1496 } 1497 os_free(res_buf); 1498 res_buf = NULL; 1499 if (!first) 1500 wpa_driver_wext_add_scan_entry(res, &data); 1501 os_free(data.ie); 1502 1503 wpa_printf(MSG_DEBUG, "Received %lu bytes of scan results (%lu BSSes)", 1504 (unsigned long) len, (unsigned long) res->num); 1505 1506 return res; 1507} 1508 1509 1510static int wpa_driver_wext_get_range(void *priv) 1511{ 1512 struct wpa_driver_wext_data *drv = priv; 1513 struct iw_range *range; 1514 struct iwreq iwr; 1515 int minlen; 1516 size_t buflen; 1517 1518 /* 1519 * Use larger buffer than struct iw_range in order to allow the 1520 * structure to grow in the future. 1521 */ 1522 buflen = sizeof(struct iw_range) + 500; 1523 range = os_zalloc(buflen); 1524 if (range == NULL) 1525 return -1; 1526 1527 os_memset(&iwr, 0, sizeof(iwr)); 1528 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1529 iwr.u.data.pointer = (caddr_t) range; 1530 iwr.u.data.length = buflen; 1531 1532 minlen = ((char *) &range->enc_capa) - (char *) range + 1533 sizeof(range->enc_capa); 1534 1535 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1536 perror("ioctl[SIOCGIWRANGE]"); 1537 os_free(range); 1538 return -1; 1539 } else if (iwr.u.data.length >= minlen && 1540 range->we_version_compiled >= 18) { 1541 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1542 "WE(source)=%d enc_capa=0x%x", 1543 range->we_version_compiled, 1544 range->we_version_source, 1545 range->enc_capa); 1546 drv->has_capability = 1; 1547 drv->we_version_compiled = range->we_version_compiled; 1548 if (range->enc_capa & IW_ENC_CAPA_WPA) { 1549 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA | 1550 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 1551 } 1552 if (range->enc_capa & IW_ENC_CAPA_WPA2) { 1553 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | 1554 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 1555 } 1556 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | 1557 WPA_DRIVER_CAPA_ENC_WEP104; 1558 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP128; 1559 if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP) 1560 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 1561 if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP) 1562 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 1563 if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE) 1564 drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE; 1565 drv->capa.auth = WPA_DRIVER_AUTH_OPEN | 1566 WPA_DRIVER_AUTH_SHARED | 1567 WPA_DRIVER_AUTH_LEAP; 1568 drv->capa.max_scan_ssids = 1; 1569 1570 wpa_printf(MSG_DEBUG, " capabilities: key_mgmt 0x%x enc 0x%x " 1571 "flags 0x%x", 1572 drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags); 1573 } else { 1574 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: too old (short) data - " 1575 "assuming WPA is not supported"); 1576 } 1577 1578 drv->max_level = range->max_qual.level; 1579 1580 os_free(range); 1581 return 0; 1582} 1583 1584 1585static int wpa_driver_wext_set_psk(struct wpa_driver_wext_data *drv, 1586 const u8 *psk) 1587{ 1588 struct iw_encode_ext *ext; 1589 struct iwreq iwr; 1590 int ret; 1591 1592 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1593 1594 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)) 1595 return 0; 1596 1597 if (!psk) 1598 return 0; 1599 1600 os_memset(&iwr, 0, sizeof(iwr)); 1601 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1602 1603 ext = os_zalloc(sizeof(*ext) + PMK_LEN); 1604 if (ext == NULL) 1605 return -1; 1606 1607 iwr.u.encoding.pointer = (caddr_t) ext; 1608 iwr.u.encoding.length = sizeof(*ext) + PMK_LEN; 1609 ext->key_len = PMK_LEN; 1610 os_memcpy(&ext->key, psk, ext->key_len); 1611 ext->alg = IW_ENCODE_ALG_PMK; 1612 1613 ret = ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr); 1614 if (ret < 0) 1615 perror("ioctl[SIOCSIWENCODEEXT] PMK"); 1616 os_free(ext); 1617 1618 return ret; 1619} 1620 1621 1622static int wpa_driver_wext_set_key_ext(void *priv, enum wpa_alg alg, 1623 const u8 *addr, int key_idx, 1624 int set_tx, const u8 *seq, 1625 size_t seq_len, 1626 const u8 *key, size_t key_len) 1627{ 1628 struct wpa_driver_wext_data *drv = priv; 1629 struct iwreq iwr; 1630 int ret = 0; 1631 struct iw_encode_ext *ext; 1632 1633 if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) { 1634 wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu", 1635 __FUNCTION__, (unsigned long) seq_len); 1636 return -1; 1637 } 1638 1639 ext = os_zalloc(sizeof(*ext) + key_len); 1640 if (ext == NULL) 1641 return -1; 1642 os_memset(&iwr, 0, sizeof(iwr)); 1643 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1644 iwr.u.encoding.flags = key_idx + 1; 1645 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1646 if (alg == WPA_ALG_NONE) 1647 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 1648 iwr.u.encoding.pointer = (caddr_t) ext; 1649 iwr.u.encoding.length = sizeof(*ext) + key_len; 1650 1651 if (addr == NULL || is_broadcast_ether_addr(addr)) 1652 ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY; 1653 if (set_tx) 1654 ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY; 1655 1656 ext->addr.sa_family = ARPHRD_ETHER; 1657 if (addr) 1658 os_memcpy(ext->addr.sa_data, addr, ETH_ALEN); 1659 else 1660 os_memset(ext->addr.sa_data, 0xff, ETH_ALEN); 1661 if (key && key_len) { 1662 os_memcpy(ext + 1, key, key_len); 1663 ext->key_len = key_len; 1664 } 1665 switch (alg) { 1666 case WPA_ALG_NONE: 1667 ext->alg = IW_ENCODE_ALG_NONE; 1668 break; 1669 case WPA_ALG_WEP: 1670 ext->alg = IW_ENCODE_ALG_WEP; 1671 break; 1672 case WPA_ALG_TKIP: 1673 ext->alg = IW_ENCODE_ALG_TKIP; 1674 break; 1675 case WPA_ALG_CCMP: 1676 ext->alg = IW_ENCODE_ALG_CCMP; 1677 break; 1678 case WPA_ALG_PMK: 1679 ext->alg = IW_ENCODE_ALG_PMK; 1680 break; 1681#ifdef CONFIG_IEEE80211W 1682 case WPA_ALG_IGTK: 1683 ext->alg = IW_ENCODE_ALG_AES_CMAC; 1684 break; 1685#endif /* CONFIG_IEEE80211W */ 1686 default: 1687 wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d", 1688 __FUNCTION__, alg); 1689 os_free(ext); 1690 return -1; 1691 } 1692 1693 if (seq && seq_len) { 1694 ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID; 1695 os_memcpy(ext->rx_seq, seq, seq_len); 1696 } 1697 1698 if (ioctl(drv->ioctl_sock, SIOCSIWENCODEEXT, &iwr) < 0) { 1699 ret = errno == EOPNOTSUPP ? -2 : -1; 1700 if (errno == ENODEV) { 1701 /* 1702 * ndiswrapper seems to be returning incorrect error 1703 * code.. */ 1704 ret = -2; 1705 } 1706 1707 perror("ioctl[SIOCSIWENCODEEXT]"); 1708 } 1709 1710 os_free(ext); 1711 return ret; 1712} 1713 1714 1715/** 1716 * wpa_driver_wext_set_key - Configure encryption key 1717 * @priv: Pointer to private wext data from wpa_driver_wext_init() 1718 * @priv: Private driver interface data 1719 * @alg: Encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP, 1720 * %WPA_ALG_TKIP, %WPA_ALG_CCMP); %WPA_ALG_NONE clears the key. 1721 * @addr: Address of the peer STA or ff:ff:ff:ff:ff:ff for 1722 * broadcast/default keys 1723 * @key_idx: key index (0..3), usually 0 for unicast keys 1724 * @set_tx: Configure this key as the default Tx key (only used when 1725 * driver does not support separate unicast/individual key 1726 * @seq: Sequence number/packet number, seq_len octets, the next 1727 * packet number to be used for in replay protection; configured 1728 * for Rx keys (in most cases, this is only used with broadcast 1729 * keys and set to zero for unicast keys) 1730 * @seq_len: Length of the seq, depends on the algorithm: 1731 * TKIP: 6 octets, CCMP: 6 octets 1732 * @key: Key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 1733 * 8-byte Rx Mic Key 1734 * @key_len: Length of the key buffer in octets (WEP: 5 or 13, 1735 * TKIP: 32, CCMP: 16) 1736 * Returns: 0 on success, -1 on failure 1737 * 1738 * This function uses SIOCSIWENCODEEXT by default, but tries to use 1739 * SIOCSIWENCODE if the extended ioctl fails when configuring a WEP key. 1740 */ 1741int wpa_driver_wext_set_key(const char *ifname, void *priv, enum wpa_alg alg, 1742 const u8 *addr, int key_idx, 1743 int set_tx, const u8 *seq, size_t seq_len, 1744 const u8 *key, size_t key_len) 1745{ 1746 struct wpa_driver_wext_data *drv = priv; 1747 struct iwreq iwr; 1748 int ret = 0; 1749 1750 wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu " 1751 "key_len=%lu", 1752 __FUNCTION__, alg, key_idx, set_tx, 1753 (unsigned long) seq_len, (unsigned long) key_len); 1754 1755 ret = wpa_driver_wext_set_key_ext(drv, alg, addr, key_idx, set_tx, 1756 seq, seq_len, key, key_len); 1757 if (ret == 0) 1758 return 0; 1759 1760 if (ret == -2 && 1761 (alg == WPA_ALG_NONE || alg == WPA_ALG_WEP)) { 1762 wpa_printf(MSG_DEBUG, "Driver did not support " 1763 "SIOCSIWENCODEEXT, trying SIOCSIWENCODE"); 1764 ret = 0; 1765 } else { 1766 wpa_printf(MSG_DEBUG, "Driver did not support " 1767 "SIOCSIWENCODEEXT"); 1768 return ret; 1769 } 1770 1771 os_memset(&iwr, 0, sizeof(iwr)); 1772 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1773 iwr.u.encoding.flags = key_idx + 1; 1774 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1775 if (alg == WPA_ALG_NONE) 1776 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 1777 iwr.u.encoding.pointer = (caddr_t) key; 1778 iwr.u.encoding.length = key_len; 1779 1780 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 1781 perror("ioctl[SIOCSIWENCODE]"); 1782 ret = -1; 1783 } 1784 1785 if (set_tx && alg != WPA_ALG_NONE) { 1786 os_memset(&iwr, 0, sizeof(iwr)); 1787 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1788 iwr.u.encoding.flags = key_idx + 1; 1789 iwr.u.encoding.flags |= IW_ENCODE_TEMP; 1790 iwr.u.encoding.pointer = (caddr_t) NULL; 1791 iwr.u.encoding.length = 0; 1792 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 1793 perror("ioctl[SIOCSIWENCODE] (set_tx)"); 1794 ret = -1; 1795 } 1796 } 1797 1798 return ret; 1799} 1800 1801 1802static int wpa_driver_wext_set_countermeasures(void *priv, 1803 int enabled) 1804{ 1805 struct wpa_driver_wext_data *drv = priv; 1806 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1807 return wpa_driver_wext_set_auth_param(drv, 1808 IW_AUTH_TKIP_COUNTERMEASURES, 1809 enabled); 1810} 1811 1812 1813static int wpa_driver_wext_set_drop_unencrypted(void *priv, 1814 int enabled) 1815{ 1816 struct wpa_driver_wext_data *drv = priv; 1817 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1818 drv->use_crypt = enabled; 1819 return wpa_driver_wext_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED, 1820 enabled); 1821} 1822 1823 1824static int wpa_driver_wext_mlme(struct wpa_driver_wext_data *drv, 1825 const u8 *addr, int cmd, int reason_code) 1826{ 1827 struct iwreq iwr; 1828 struct iw_mlme mlme; 1829 int ret = 0; 1830 1831 os_memset(&iwr, 0, sizeof(iwr)); 1832 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1833 os_memset(&mlme, 0, sizeof(mlme)); 1834 mlme.cmd = cmd; 1835 mlme.reason_code = reason_code; 1836 mlme.addr.sa_family = ARPHRD_ETHER; 1837 os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN); 1838 iwr.u.data.pointer = (caddr_t) &mlme; 1839 iwr.u.data.length = sizeof(mlme); 1840 1841 if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) { 1842 perror("ioctl[SIOCSIWMLME]"); 1843 ret = -1; 1844 } 1845 1846 return ret; 1847} 1848 1849 1850static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv) 1851{ 1852 struct iwreq iwr; 1853 const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; 1854 u8 ssid[32]; 1855 int i; 1856 1857 /* 1858 * Only force-disconnect when the card is in infrastructure mode, 1859 * otherwise the driver might interpret the cleared BSSID and random 1860 * SSID as an attempt to create a new ad-hoc network. 1861 */ 1862 os_memset(&iwr, 0, sizeof(iwr)); 1863 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1864 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { 1865 perror("ioctl[SIOCGIWMODE]"); 1866 iwr.u.mode = IW_MODE_INFRA; 1867 } 1868 1869 if (iwr.u.mode == IW_MODE_INFRA) { 1870 /* Clear the BSSID selection */ 1871 if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0) { 1872 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear BSSID " 1873 "selection on disconnect"); 1874 } 1875 1876 if (drv->cfg80211) { 1877 /* 1878 * cfg80211 supports SIOCSIWMLME commands, so there is 1879 * no need for the random SSID hack, but clear the 1880 * SSID. 1881 */ 1882 if (wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) { 1883 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear " 1884 "SSID on disconnect"); 1885 } 1886 return; 1887 } 1888 1889 /* 1890 * Set a random SSID to make sure the driver will not be trying 1891 * to associate with something even if it does not understand 1892 * SIOCSIWMLME commands (or tries to associate automatically 1893 * after deauth/disassoc). 1894 */ 1895 for (i = 0; i < 32; i++) 1896 ssid[i] = rand() & 0xFF; 1897 if (wpa_driver_wext_set_ssid(drv, ssid, 32) < 0) { 1898 wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus " 1899 "SSID to disconnect"); 1900 } 1901 } 1902} 1903 1904 1905static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr, 1906 int reason_code) 1907{ 1908 struct wpa_driver_wext_data *drv = priv; 1909 int ret; 1910 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1911 ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code); 1912 wpa_driver_wext_disconnect(drv); 1913 return ret; 1914} 1915 1916 1917static int wpa_driver_wext_set_gen_ie(void *priv, const u8 *ie, 1918 size_t ie_len) 1919{ 1920 struct wpa_driver_wext_data *drv = priv; 1921 struct iwreq iwr; 1922 int ret = 0; 1923 1924 os_memset(&iwr, 0, sizeof(iwr)); 1925 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1926 iwr.u.data.pointer = (caddr_t) ie; 1927 iwr.u.data.length = ie_len; 1928 1929 if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) { 1930 perror("ioctl[SIOCSIWGENIE]"); 1931 ret = -1; 1932 } 1933 1934 return ret; 1935} 1936 1937 1938int wpa_driver_wext_cipher2wext(int cipher) 1939{ 1940 switch (cipher) { 1941 case WPA_CIPHER_NONE: 1942 return IW_AUTH_CIPHER_NONE; 1943 case WPA_CIPHER_WEP40: 1944 return IW_AUTH_CIPHER_WEP40; 1945 case WPA_CIPHER_TKIP: 1946 return IW_AUTH_CIPHER_TKIP; 1947 case WPA_CIPHER_CCMP: 1948 return IW_AUTH_CIPHER_CCMP; 1949 case WPA_CIPHER_WEP104: 1950 return IW_AUTH_CIPHER_WEP104; 1951 default: 1952 return 0; 1953 } 1954} 1955 1956 1957int wpa_driver_wext_keymgmt2wext(int keymgmt) 1958{ 1959 switch (keymgmt) { 1960 case WPA_KEY_MGMT_IEEE8021X: 1961 case WPA_KEY_MGMT_IEEE8021X_NO_WPA: 1962 return IW_AUTH_KEY_MGMT_802_1X; 1963 case WPA_KEY_MGMT_PSK: 1964 return IW_AUTH_KEY_MGMT_PSK; 1965 default: 1966 return 0; 1967 } 1968} 1969 1970 1971static int 1972wpa_driver_wext_auth_alg_fallback(struct wpa_driver_wext_data *drv, 1973 struct wpa_driver_associate_params *params) 1974{ 1975 struct iwreq iwr; 1976 int ret = 0; 1977 1978 wpa_printf(MSG_DEBUG, "WEXT: Driver did not support " 1979 "SIOCSIWAUTH for AUTH_ALG, trying SIOCSIWENCODE"); 1980 1981 os_memset(&iwr, 0, sizeof(iwr)); 1982 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1983 /* Just changing mode, not actual keys */ 1984 iwr.u.encoding.flags = 0; 1985 iwr.u.encoding.pointer = (caddr_t) NULL; 1986 iwr.u.encoding.length = 0; 1987 1988 /* 1989 * Note: IW_ENCODE_{OPEN,RESTRICTED} can be interpreted to mean two 1990 * different things. Here they are used to indicate Open System vs. 1991 * Shared Key authentication algorithm. However, some drivers may use 1992 * them to select between open/restricted WEP encrypted (open = allow 1993 * both unencrypted and encrypted frames; restricted = only allow 1994 * encrypted frames). 1995 */ 1996 1997 if (!drv->use_crypt) { 1998 iwr.u.encoding.flags |= IW_ENCODE_DISABLED; 1999 } else { 2000 if (params->auth_alg & WPA_AUTH_ALG_OPEN) 2001 iwr.u.encoding.flags |= IW_ENCODE_OPEN; 2002 if (params->auth_alg & WPA_AUTH_ALG_SHARED) 2003 iwr.u.encoding.flags |= IW_ENCODE_RESTRICTED; 2004 } 2005 2006 if (ioctl(drv->ioctl_sock, SIOCSIWENCODE, &iwr) < 0) { 2007 perror("ioctl[SIOCSIWENCODE]"); 2008 ret = -1; 2009 } 2010 2011 return ret; 2012} 2013 2014 2015int wpa_driver_wext_associate(void *priv, 2016 struct wpa_driver_associate_params *params) 2017{ 2018 struct wpa_driver_wext_data *drv = priv; 2019 int ret = 0; 2020 int allow_unencrypted_eapol; 2021 int value; 2022 2023 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 2024 2025 if (drv->cfg80211) { 2026 /* 2027 * Stop cfg80211 from trying to associate before we are done 2028 * with all parameters. 2029 */ 2030 if (wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) { 2031 wpa_printf(MSG_DEBUG, 2032 "WEXT: Failed to clear SSID to stop pending cfg80211 association attempts (if any)"); 2033 /* continue anyway */ 2034 } 2035 } 2036 2037 if (wpa_driver_wext_set_drop_unencrypted(drv, params->drop_unencrypted) 2038 < 0) 2039 ret = -1; 2040 if (wpa_driver_wext_set_auth_alg(drv, params->auth_alg) < 0) 2041 ret = -1; 2042 if (wpa_driver_wext_set_mode(drv, params->mode) < 0) 2043 ret = -1; 2044 2045 /* 2046 * If the driver did not support SIOCSIWAUTH, fallback to 2047 * SIOCSIWENCODE here. 2048 */ 2049 if (drv->auth_alg_fallback && 2050 wpa_driver_wext_auth_alg_fallback(drv, params) < 0) 2051 ret = -1; 2052 2053 if (!params->bssid && 2054 wpa_driver_wext_set_bssid(drv, NULL) < 0) 2055 ret = -1; 2056 2057 /* TODO: should consider getting wpa version and cipher/key_mgmt suites 2058 * from configuration, not from here, where only the selected suite is 2059 * available */ 2060 if (wpa_driver_wext_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len) 2061 < 0) 2062 ret = -1; 2063 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) 2064 value = IW_AUTH_WPA_VERSION_DISABLED; 2065 else if (params->wpa_ie[0] == WLAN_EID_RSN) 2066 value = IW_AUTH_WPA_VERSION_WPA2; 2067 else 2068 value = IW_AUTH_WPA_VERSION_WPA; 2069 if (wpa_driver_wext_set_auth_param(drv, 2070 IW_AUTH_WPA_VERSION, value) < 0) 2071 ret = -1; 2072 value = wpa_driver_wext_cipher2wext(params->pairwise_suite); 2073 if (wpa_driver_wext_set_auth_param(drv, 2074 IW_AUTH_CIPHER_PAIRWISE, value) < 0) 2075 ret = -1; 2076 value = wpa_driver_wext_cipher2wext(params->group_suite); 2077 if (wpa_driver_wext_set_auth_param(drv, 2078 IW_AUTH_CIPHER_GROUP, value) < 0) 2079 ret = -1; 2080 value = wpa_driver_wext_keymgmt2wext(params->key_mgmt_suite); 2081 if (wpa_driver_wext_set_auth_param(drv, 2082 IW_AUTH_KEY_MGMT, value) < 0) 2083 ret = -1; 2084 value = params->key_mgmt_suite != WPA_KEY_MGMT_NONE || 2085 params->pairwise_suite != WPA_CIPHER_NONE || 2086 params->group_suite != WPA_CIPHER_NONE || 2087 params->wpa_ie_len; 2088 if (wpa_driver_wext_set_auth_param(drv, 2089 IW_AUTH_PRIVACY_INVOKED, value) < 0) 2090 ret = -1; 2091 2092 /* Allow unencrypted EAPOL messages even if pairwise keys are set when 2093 * not using WPA. IEEE 802.1X specifies that these frames are not 2094 * encrypted, but WPA encrypts them when pairwise keys are in use. */ 2095 if (params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X || 2096 params->key_mgmt_suite == WPA_KEY_MGMT_PSK) 2097 allow_unencrypted_eapol = 0; 2098 else 2099 allow_unencrypted_eapol = 1; 2100 2101 if (wpa_driver_wext_set_psk(drv, params->psk) < 0) 2102 ret = -1; 2103 if (wpa_driver_wext_set_auth_param(drv, 2104 IW_AUTH_RX_UNENCRYPTED_EAPOL, 2105 allow_unencrypted_eapol) < 0) 2106 ret = -1; 2107#ifdef CONFIG_IEEE80211W 2108 switch (params->mgmt_frame_protection) { 2109 case NO_MGMT_FRAME_PROTECTION: 2110 value = IW_AUTH_MFP_DISABLED; 2111 break; 2112 case MGMT_FRAME_PROTECTION_OPTIONAL: 2113 value = IW_AUTH_MFP_OPTIONAL; 2114 break; 2115 case MGMT_FRAME_PROTECTION_REQUIRED: 2116 value = IW_AUTH_MFP_REQUIRED; 2117 break; 2118 }; 2119 if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0) 2120 ret = -1; 2121#endif /* CONFIG_IEEE80211W */ 2122 if (params->freq.freq && 2123 wpa_driver_wext_set_freq(drv, params->freq.freq) < 0) 2124 ret = -1; 2125 if (!drv->cfg80211 && 2126 wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) 2127 ret = -1; 2128 if (params->bssid && 2129 wpa_driver_wext_set_bssid(drv, params->bssid) < 0) 2130 ret = -1; 2131 if (drv->cfg80211 && 2132 wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0) 2133 ret = -1; 2134 2135 return ret; 2136} 2137 2138 2139static int wpa_driver_wext_set_auth_alg(void *priv, int auth_alg) 2140{ 2141 struct wpa_driver_wext_data *drv = priv; 2142 int algs = 0, res; 2143 2144 if (auth_alg & WPA_AUTH_ALG_OPEN) 2145 algs |= IW_AUTH_ALG_OPEN_SYSTEM; 2146 if (auth_alg & WPA_AUTH_ALG_SHARED) 2147 algs |= IW_AUTH_ALG_SHARED_KEY; 2148 if (auth_alg & WPA_AUTH_ALG_LEAP) 2149 algs |= IW_AUTH_ALG_LEAP; 2150 if (algs == 0) { 2151 /* at least one algorithm should be set */ 2152 algs = IW_AUTH_ALG_OPEN_SYSTEM; 2153 } 2154 2155 res = wpa_driver_wext_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG, 2156 algs); 2157 drv->auth_alg_fallback = res == -2; 2158 return res; 2159} 2160 2161 2162/** 2163 * wpa_driver_wext_set_mode - Set wireless mode (infra/adhoc), SIOCSIWMODE 2164 * @priv: Pointer to private wext data from wpa_driver_wext_init() 2165 * @mode: 0 = infra/BSS (associate with an AP), 1 = adhoc/IBSS 2166 * Returns: 0 on success, -1 on failure 2167 */ 2168int wpa_driver_wext_set_mode(void *priv, int mode) 2169{ 2170 struct wpa_driver_wext_data *drv = priv; 2171 struct iwreq iwr; 2172 int ret = -1; 2173 unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA; 2174 2175 os_memset(&iwr, 0, sizeof(iwr)); 2176 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2177 iwr.u.mode = new_mode; 2178 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) { 2179 ret = 0; 2180 goto done; 2181 } 2182 2183 if (errno != EBUSY) { 2184 perror("ioctl[SIOCSIWMODE]"); 2185 goto done; 2186 } 2187 2188 /* mac80211 doesn't allow mode changes while the device is up, so if 2189 * the device isn't in the mode we're about to change to, take device 2190 * down, try to set the mode again, and bring it back up. 2191 */ 2192 if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) { 2193 perror("ioctl[SIOCGIWMODE]"); 2194 goto done; 2195 } 2196 2197 if (iwr.u.mode == new_mode) { 2198 ret = 0; 2199 goto done; 2200 } 2201 2202 if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) { 2203 /* Try to set the mode again while the interface is down */ 2204 iwr.u.mode = new_mode; 2205 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) 2206 perror("ioctl[SIOCSIWMODE]"); 2207 else 2208 ret = 0; 2209 2210 (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1); 2211 } 2212 2213done: 2214 return ret; 2215} 2216 2217 2218static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv, 2219 u32 cmd, const u8 *bssid, const u8 *pmkid) 2220{ 2221 struct iwreq iwr; 2222 struct iw_pmksa pmksa; 2223 int ret = 0; 2224 2225 os_memset(&iwr, 0, sizeof(iwr)); 2226 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2227 os_memset(&pmksa, 0, sizeof(pmksa)); 2228 pmksa.cmd = cmd; 2229 pmksa.bssid.sa_family = ARPHRD_ETHER; 2230 if (bssid) 2231 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN); 2232 if (pmkid) 2233 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN); 2234 iwr.u.data.pointer = (caddr_t) &pmksa; 2235 iwr.u.data.length = sizeof(pmksa); 2236 2237 if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) { 2238 if (errno != EOPNOTSUPP) 2239 perror("ioctl[SIOCSIWPMKSA]"); 2240 ret = -1; 2241 } 2242 2243 return ret; 2244} 2245 2246 2247static int wpa_driver_wext_add_pmkid(void *priv, const u8 *bssid, 2248 const u8 *pmkid) 2249{ 2250 struct wpa_driver_wext_data *drv = priv; 2251 return wpa_driver_wext_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid); 2252} 2253 2254 2255static int wpa_driver_wext_remove_pmkid(void *priv, const u8 *bssid, 2256 const u8 *pmkid) 2257{ 2258 struct wpa_driver_wext_data *drv = priv; 2259 return wpa_driver_wext_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid); 2260} 2261 2262 2263static int wpa_driver_wext_flush_pmkid(void *priv) 2264{ 2265 struct wpa_driver_wext_data *drv = priv; 2266 return wpa_driver_wext_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL); 2267} 2268 2269 2270int wpa_driver_wext_get_capa(void *priv, struct wpa_driver_capa *capa) 2271{ 2272 struct wpa_driver_wext_data *drv = priv; 2273 if (!drv->has_capability) 2274 return -1; 2275 os_memcpy(capa, &drv->capa, sizeof(*capa)); 2276 return 0; 2277} 2278 2279 2280int wpa_driver_wext_alternative_ifindex(struct wpa_driver_wext_data *drv, 2281 const char *ifname) 2282{ 2283 if (ifname == NULL) { 2284 drv->ifindex2 = -1; 2285 return 0; 2286 } 2287 2288 drv->ifindex2 = if_nametoindex(ifname); 2289 if (drv->ifindex2 <= 0) 2290 return -1; 2291 2292 wpa_printf(MSG_DEBUG, "Added alternative ifindex %d (%s) for " 2293 "wireless events", drv->ifindex2, ifname); 2294 2295 return 0; 2296} 2297 2298 2299int wpa_driver_wext_set_operstate(void *priv, int state) 2300{ 2301 struct wpa_driver_wext_data *drv = priv; 2302 2303 wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)", 2304 __func__, drv->operstate, state, state ? "UP" : "DORMANT"); 2305 drv->operstate = state; 2306 return netlink_send_oper_ifla(drv->netlink, drv->ifindex, -1, 2307 state ? IF_OPER_UP : IF_OPER_DORMANT); 2308} 2309 2310 2311int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv) 2312{ 2313 return drv->we_version_compiled; 2314} 2315 2316 2317static const char * wext_get_radio_name(void *priv) 2318{ 2319 struct wpa_driver_wext_data *drv = priv; 2320 return drv->phyname; 2321} 2322 2323 2324static int wpa_driver_wext_signal_poll(void *priv, struct wpa_signal_info *si) 2325{ 2326 struct wpa_driver_wext_data *drv = priv; 2327 struct iw_statistics stats; 2328 struct iwreq iwr; 2329 2330 os_memset(si, 0, sizeof(*si)); 2331 si->current_signal = -9999; 2332 si->current_noise = 9999; 2333 si->chanwidth = CHAN_WIDTH_UNKNOWN; 2334 2335 os_memset(&iwr, 0, sizeof(iwr)); 2336 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 2337 iwr.u.data.pointer = (caddr_t) &stats; 2338 iwr.u.data.length = sizeof(stats); 2339 iwr.u.data.flags = 1; 2340 2341 if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr) < 0) { 2342 wpa_printf(MSG_ERROR, "WEXT: SIOCGIWSTATS: %s", 2343 strerror(errno)); 2344 return -1; 2345 } 2346 2347 si->current_signal = stats.qual.level - 2348 ((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0); 2349 si->current_noise = stats.qual.noise - 2350 ((stats.qual.updated & IW_QUAL_DBM) ? 0x100 : 0); 2351 return 0; 2352} 2353 2354 2355const struct wpa_driver_ops wpa_driver_wext_ops = { 2356 .name = "wext", 2357 .desc = "Linux wireless extensions (generic)", 2358 .get_bssid = wpa_driver_wext_get_bssid, 2359 .get_ssid = wpa_driver_wext_get_ssid, 2360 .set_key = wpa_driver_wext_set_key, 2361 .set_countermeasures = wpa_driver_wext_set_countermeasures, 2362 .scan2 = wpa_driver_wext_scan, 2363 .get_scan_results2 = wpa_driver_wext_get_scan_results, 2364 .deauthenticate = wpa_driver_wext_deauthenticate, 2365 .associate = wpa_driver_wext_associate, 2366 .init = wpa_driver_wext_init, 2367 .deinit = wpa_driver_wext_deinit, 2368 .add_pmkid = wpa_driver_wext_add_pmkid, 2369 .remove_pmkid = wpa_driver_wext_remove_pmkid, 2370 .flush_pmkid = wpa_driver_wext_flush_pmkid, 2371 .get_capa = wpa_driver_wext_get_capa, 2372 .set_operstate = wpa_driver_wext_set_operstate, 2373 .get_radio_name = wext_get_radio_name, 2374 .signal_poll = wpa_driver_wext_signal_poll, 2375}; 2376