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