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