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