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