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