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