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