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