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