1 /* 2 * hostapd / Driver interaction with Atheros driver 3 * Copyright (c) 2004, Sam Leffler <sam (at) errno.com> 4 * Copyright (c) 2004, Video54 Technologies 5 * Copyright (c) 2005-2007, Jouni Malinen <j (at) w1.fi> 6 * Copyright (c) 2009, Atheros Communications 7 * 8 * This software may be distributed under the terms of the BSD license. 9 * See README for more details. 10 */ 11 12 #include "includes.h" 13 #include <net/if.h> 14 #include <sys/ioctl.h> 15 16 #include "common.h" 17 #include "eloop.h" 18 #include "common/ieee802_11_defs.h" 19 #include "l2_packet/l2_packet.h" 20 #include "p2p/p2p.h" 21 22 #include "common.h" 23 #ifndef _BYTE_ORDER 24 #ifdef WORDS_BIGENDIAN 25 #define _BYTE_ORDER _BIG_ENDIAN 26 #else 27 #define _BYTE_ORDER _LITTLE_ENDIAN 28 #endif 29 #endif /* _BYTE_ORDER */ 30 31 /* 32 * Note, the ATH_WPS_IE setting must match with the driver build.. If the 33 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail. 34 */ 35 #define ATH_WPS_IE 36 37 #include "ieee80211_external.h" 38 39 /* Avoid conflicting definition from the driver header files with 40 * common/wpa_common.h */ 41 #undef WPA_OUI_TYPE 42 43 44 #ifdef CONFIG_WPS 45 #include <netpacket/packet.h> 46 #endif /* CONFIG_WPS */ 47 48 #ifndef ETH_P_80211_RAW 49 #define ETH_P_80211_RAW 0x0019 50 #endif 51 52 #include "linux_wext.h" 53 54 #include "driver.h" 55 #include "eloop.h" 56 #include "priv_netlink.h" 57 #include "l2_packet/l2_packet.h" 58 #include "common/ieee802_11_defs.h" 59 #include "netlink.h" 60 #include "linux_ioctl.h" 61 62 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R) || defined(CONFIG_HS20) || defined(CONFIG_WNM) || defined(CONFIG_WPS) || defined(CONFIG_FILS) 63 #define ATHEROS_USE_RAW_RECEIVE 64 #endif 65 66 67 struct atheros_driver_data { 68 struct hostapd_data *hapd; /* back pointer */ 69 70 char iface[IFNAMSIZ + 1]; 71 int ifindex; 72 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 73 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 74 int ioctl_sock; /* socket for ioctl() use */ 75 struct netlink_data *netlink; 76 int we_version; 77 int fils_en; /* FILS enable/disable in driver */ 78 u8 acct_mac[ETH_ALEN]; 79 struct hostap_sta_driver_data acct_data; 80 81 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 82 struct wpabuf *wpa_ie; 83 struct wpabuf *wps_beacon_ie; 84 struct wpabuf *wps_probe_resp_ie; 85 u8 own_addr[ETH_ALEN]; 86 }; 87 88 static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 89 int reason_code); 90 static int atheros_set_privacy(void *priv, int enabled); 91 92 static const char * athr_get_ioctl_name(int op) 93 { 94 switch (op) { 95 case IEEE80211_IOCTL_SETPARAM: 96 return "SETPARAM"; 97 case IEEE80211_IOCTL_GETPARAM: 98 return "GETPARAM"; 99 case IEEE80211_IOCTL_SETKEY: 100 return "SETKEY"; 101 case IEEE80211_IOCTL_SETWMMPARAMS: 102 return "SETWMMPARAMS"; 103 case IEEE80211_IOCTL_DELKEY: 104 return "DELKEY"; 105 case IEEE80211_IOCTL_GETWMMPARAMS: 106 return "GETWMMPARAMS"; 107 case IEEE80211_IOCTL_SETMLME: 108 return "SETMLME"; 109 case IEEE80211_IOCTL_GETCHANINFO: 110 return "GETCHANINFO"; 111 case IEEE80211_IOCTL_SETOPTIE: 112 return "SETOPTIE"; 113 case IEEE80211_IOCTL_GETOPTIE: 114 return "GETOPTIE"; 115 case IEEE80211_IOCTL_ADDMAC: 116 return "ADDMAC"; 117 case IEEE80211_IOCTL_DELMAC: 118 return "DELMAC"; 119 case IEEE80211_IOCTL_GETCHANLIST: 120 return "GETCHANLIST"; 121 case IEEE80211_IOCTL_SETCHANLIST: 122 return "SETCHANLIST"; 123 case IEEE80211_IOCTL_KICKMAC: 124 return "KICKMAC"; 125 case IEEE80211_IOCTL_CHANSWITCH: 126 return "CHANSWITCH"; 127 case IEEE80211_IOCTL_GETMODE: 128 return "GETMODE"; 129 case IEEE80211_IOCTL_SETMODE: 130 return "SETMODE"; 131 case IEEE80211_IOCTL_GET_APPIEBUF: 132 return "GET_APPIEBUF"; 133 case IEEE80211_IOCTL_SET_APPIEBUF: 134 return "SET_APPIEBUF"; 135 case IEEE80211_IOCTL_SET_ACPARAMS: 136 return "SET_ACPARAMS"; 137 case IEEE80211_IOCTL_FILTERFRAME: 138 return "FILTERFRAME"; 139 case IEEE80211_IOCTL_SET_RTPARAMS: 140 return "SET_RTPARAMS"; 141 case IEEE80211_IOCTL_SET_MEDENYENTRY: 142 return "SET_MEDENYENTRY"; 143 case IEEE80211_IOCTL_GET_MACADDR: 144 return "GET_MACADDR"; 145 case IEEE80211_IOCTL_SET_HBRPARAMS: 146 return "SET_HBRPARAMS"; 147 case IEEE80211_IOCTL_SET_RXTIMEOUT: 148 return "SET_RXTIMEOUT"; 149 case IEEE80211_IOCTL_STA_STATS: 150 return "STA_STATS"; 151 case IEEE80211_IOCTL_GETWPAIE: 152 return "GETWPAIE"; 153 default: 154 return "??"; 155 } 156 } 157 158 159 static const char * athr_get_param_name(int op) 160 { 161 switch (op) { 162 case IEEE80211_IOC_MCASTCIPHER: 163 return "MCASTCIPHER"; 164 case IEEE80211_PARAM_MCASTKEYLEN: 165 return "MCASTKEYLEN"; 166 case IEEE80211_PARAM_UCASTCIPHERS: 167 return "UCASTCIPHERS"; 168 case IEEE80211_PARAM_KEYMGTALGS: 169 return "KEYMGTALGS"; 170 case IEEE80211_PARAM_RSNCAPS: 171 return "RSNCAPS"; 172 case IEEE80211_PARAM_WPA: 173 return "WPA"; 174 case IEEE80211_PARAM_AUTHMODE: 175 return "AUTHMODE"; 176 case IEEE80211_PARAM_PRIVACY: 177 return "PRIVACY"; 178 case IEEE80211_PARAM_COUNTERMEASURES: 179 return "COUNTERMEASURES"; 180 default: 181 return "??"; 182 } 183 } 184 185 186 #ifdef CONFIG_FILS 187 static int 188 get80211param(struct atheros_driver_data *drv, int op, int *data) 189 { 190 struct iwreq iwr; 191 192 os_memset(&iwr, 0, sizeof(iwr)); 193 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 194 iwr.u.mode = op; 195 196 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_GETPARAM, &iwr) < 0) 197 return -1; 198 199 *data = iwr.u.mode; 200 return 0; 201 } 202 #endif /* CONFIG_FILS */ 203 204 205 static int 206 set80211priv(struct atheros_driver_data *drv, int op, void *data, int len) 207 { 208 struct iwreq iwr; 209 int do_inline = len < IFNAMSIZ; 210 211 /* Certain ioctls must use the non-inlined method */ 212 if (op == IEEE80211_IOCTL_SET_APPIEBUF || 213 op == IEEE80211_IOCTL_FILTERFRAME) 214 do_inline = 0; 215 216 os_memset(&iwr, 0, sizeof(iwr)); 217 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 218 if (do_inline) { 219 /* 220 * Argument data fits inline; put it there. 221 */ 222 os_memcpy(iwr.u.name, data, len); 223 } else { 224 /* 225 * Argument data too big for inline transfer; setup a 226 * parameter block instead; the kernel will transfer 227 * the data for the driver. 228 */ 229 iwr.u.data.pointer = data; 230 iwr.u.data.length = len; 231 } 232 233 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 234 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " 235 "(%s) len=%d failed: %d (%s)", 236 __func__, drv->iface, op, 237 athr_get_ioctl_name(op), 238 len, errno, strerror(errno)); 239 return -1; 240 } 241 return 0; 242 } 243 244 static int 245 set80211param(struct atheros_driver_data *drv, int op, int arg) 246 { 247 struct iwreq iwr; 248 249 os_memset(&iwr, 0, sizeof(iwr)); 250 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 251 iwr.u.mode = op; 252 os_memcpy(iwr.u.name + sizeof(__u32), &arg, sizeof(arg)); 253 254 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 255 wpa_printf(MSG_INFO, 256 "%s: %s: Failed to set parameter (op %d (%s) arg %d): ioctl[IEEE80211_IOCTL_SETPARAM]: %s", 257 __func__, drv->iface, op, athr_get_param_name(op), 258 arg, strerror(errno)); 259 return -1; 260 } 261 return 0; 262 } 263 264 #ifndef CONFIG_NO_STDOUT_DEBUG 265 static const char * 266 ether_sprintf(const u8 *addr) 267 { 268 static char buf[sizeof(MACSTR)]; 269 270 if (addr != NULL) 271 os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 272 else 273 os_snprintf(buf, sizeof(buf), MACSTR, 0, 0, 0, 0, 0, 0); 274 return buf; 275 } 276 #endif /* CONFIG_NO_STDOUT_DEBUG */ 277 278 /* 279 * Configure WPA parameters. 280 */ 281 static int 282 atheros_configure_wpa(struct atheros_driver_data *drv, 283 struct wpa_bss_params *params) 284 { 285 int v; 286 287 switch (params->wpa_group) { 288 case WPA_CIPHER_CCMP: 289 v = IEEE80211_CIPHER_AES_CCM; 290 break; 291 #ifdef ATH_GCM_SUPPORT 292 case WPA_CIPHER_CCMP_256: 293 v = IEEE80211_CIPHER_AES_CCM_256; 294 break; 295 case WPA_CIPHER_GCMP: 296 v = IEEE80211_CIPHER_AES_GCM; 297 break; 298 case WPA_CIPHER_GCMP_256: 299 v = IEEE80211_CIPHER_AES_GCM_256; 300 break; 301 #endif /* ATH_GCM_SUPPORT */ 302 case WPA_CIPHER_TKIP: 303 v = IEEE80211_CIPHER_TKIP; 304 break; 305 case WPA_CIPHER_WEP104: 306 v = IEEE80211_CIPHER_WEP; 307 break; 308 case WPA_CIPHER_WEP40: 309 v = IEEE80211_CIPHER_WEP; 310 break; 311 case WPA_CIPHER_NONE: 312 v = IEEE80211_CIPHER_NONE; 313 break; 314 default: 315 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 316 params->wpa_group); 317 return -1; 318 } 319 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 320 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 321 wpa_printf(MSG_INFO, "Unable to set group key cipher to %u", v); 322 return -1; 323 } 324 if (v == IEEE80211_CIPHER_WEP) { 325 /* key length is done only for specific ciphers */ 326 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 327 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 328 wpa_printf(MSG_INFO, 329 "Unable to set group key length to %u", v); 330 return -1; 331 } 332 } 333 334 v = 0; 335 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 336 v |= 1<<IEEE80211_CIPHER_AES_CCM; 337 #ifdef ATH_GCM_SUPPORT 338 if (params->wpa_pairwise & WPA_CIPHER_CCMP_256) 339 v |= 1<<IEEE80211_CIPHER_AES_CCM_256; 340 if (params->wpa_pairwise & WPA_CIPHER_GCMP) 341 v |= 1<<IEEE80211_CIPHER_AES_GCM; 342 if (params->wpa_pairwise & WPA_CIPHER_GCMP_256) 343 v |= 1<<IEEE80211_CIPHER_AES_GCM_256; 344 #endif /* ATH_GCM_SUPPORT */ 345 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 346 v |= 1<<IEEE80211_CIPHER_TKIP; 347 if (params->wpa_pairwise & WPA_CIPHER_NONE) 348 v |= 1<<IEEE80211_CIPHER_NONE; 349 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 350 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 351 wpa_printf(MSG_INFO, 352 "Unable to set pairwise key ciphers to 0x%x", v); 353 return -1; 354 } 355 356 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 357 __func__, params->wpa_key_mgmt); 358 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 359 params->wpa_key_mgmt)) { 360 wpa_printf(MSG_INFO, 361 "Unable to set key management algorithms to 0x%x", 362 params->wpa_key_mgmt); 363 return -1; 364 } 365 366 v = 0; 367 if (params->rsn_preauth) 368 v |= BIT(0); 369 #ifdef CONFIG_IEEE80211W 370 if (params->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 371 v |= BIT(7); 372 if (params->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 373 v |= BIT(6); 374 } 375 #endif /* CONFIG_IEEE80211W */ 376 377 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", __func__, v); 378 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 379 wpa_printf(MSG_INFO, "Unable to set RSN capabilities to 0x%x", 380 v); 381 return -1; 382 } 383 384 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 385 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 386 wpa_printf(MSG_INFO, "Unable to set WPA to %u", params->wpa); 387 return -1; 388 } 389 return 0; 390 } 391 392 static int 393 atheros_set_ieee8021x(void *priv, struct wpa_bss_params *params) 394 { 395 struct atheros_driver_data *drv = priv; 396 397 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 398 399 if (!params->enabled) { 400 /* XXX restore state */ 401 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 402 IEEE80211_AUTH_AUTO) < 0) 403 return -1; 404 /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */ 405 return atheros_set_privacy(drv, 0); 406 } 407 if (!params->wpa && !params->ieee802_1x) { 408 wpa_printf(MSG_WARNING, "No 802.1X or WPA enabled!"); 409 return -1; 410 } 411 if (params->wpa && atheros_configure_wpa(drv, params) != 0) { 412 wpa_printf(MSG_WARNING, "Error configuring WPA state!"); 413 return -1; 414 } 415 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 416 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 417 wpa_printf(MSG_WARNING, "Error enabling WPA/802.1X!"); 418 return -1; 419 } 420 421 return 0; 422 } 423 424 static int 425 atheros_set_privacy(void *priv, int enabled) 426 { 427 struct atheros_driver_data *drv = priv; 428 429 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 430 431 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 432 } 433 434 static int 435 atheros_set_sta_authorized(void *priv, const u8 *addr, int authorized) 436 { 437 struct atheros_driver_data *drv = priv; 438 struct ieee80211req_mlme mlme; 439 int ret; 440 441 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 442 __func__, ether_sprintf(addr), authorized); 443 444 if (authorized) 445 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 446 else 447 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 448 mlme.im_reason = 0; 449 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 450 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 451 if (ret < 0) { 452 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 453 __func__, authorized ? "" : "un", MAC2STR(addr)); 454 } 455 456 return ret; 457 } 458 459 static int 460 atheros_sta_set_flags(void *priv, const u8 *addr, 461 unsigned int total_flags, unsigned int flags_or, 462 unsigned int flags_and) 463 { 464 /* For now, only support setting Authorized flag */ 465 if (flags_or & WPA_STA_AUTHORIZED) 466 return atheros_set_sta_authorized(priv, addr, 1); 467 if (!(flags_and & WPA_STA_AUTHORIZED)) 468 return atheros_set_sta_authorized(priv, addr, 0); 469 return 0; 470 } 471 472 static int 473 atheros_del_key(void *priv, const u8 *addr, int key_idx) 474 { 475 struct atheros_driver_data *drv = priv; 476 struct ieee80211req_del_key wk; 477 int ret; 478 479 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 480 __func__, ether_sprintf(addr), key_idx); 481 482 os_memset(&wk, 0, sizeof(wk)); 483 if (addr != NULL) { 484 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 485 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 486 } else { 487 wk.idk_keyix = key_idx; 488 } 489 490 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 491 if (ret < 0) { 492 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 493 " key_idx %d)", __func__, ether_sprintf(addr), 494 key_idx); 495 } 496 497 return ret; 498 } 499 500 static int 501 atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg, 502 const u8 *addr, int key_idx, int set_tx, const u8 *seq, 503 size_t seq_len, const u8 *key, size_t key_len) 504 { 505 struct atheros_driver_data *drv = priv; 506 struct ieee80211req_key wk; 507 u_int8_t cipher; 508 int ret; 509 510 if (alg == WPA_ALG_NONE) 511 return atheros_del_key(drv, addr, key_idx); 512 513 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 514 __func__, alg, ether_sprintf(addr), key_idx); 515 516 switch (alg) { 517 case WPA_ALG_WEP: 518 cipher = IEEE80211_CIPHER_WEP; 519 break; 520 case WPA_ALG_TKIP: 521 cipher = IEEE80211_CIPHER_TKIP; 522 break; 523 case WPA_ALG_CCMP: 524 cipher = IEEE80211_CIPHER_AES_CCM; 525 break; 526 #ifdef ATH_GCM_SUPPORT 527 case WPA_ALG_CCMP_256: 528 cipher = IEEE80211_CIPHER_AES_CCM_256; 529 break; 530 case WPA_ALG_GCMP: 531 cipher = IEEE80211_CIPHER_AES_GCM; 532 break; 533 case WPA_ALG_GCMP_256: 534 cipher = IEEE80211_CIPHER_AES_GCM_256; 535 break; 536 #endif /* ATH_GCM_SUPPORT */ 537 #ifdef CONFIG_IEEE80211W 538 case WPA_ALG_IGTK: 539 cipher = IEEE80211_CIPHER_AES_CMAC; 540 break; 541 #ifdef ATH_GCM_SUPPORT 542 case WPA_ALG_BIP_CMAC_256: 543 cipher = IEEE80211_CIPHER_AES_CMAC_256; 544 break; 545 case WPA_ALG_BIP_GMAC_128: 546 cipher = IEEE80211_CIPHER_AES_GMAC; 547 break; 548 case WPA_ALG_BIP_GMAC_256: 549 cipher = IEEE80211_CIPHER_AES_GMAC_256; 550 break; 551 #endif /* ATH_GCM_SUPPORT */ 552 #endif /* CONFIG_IEEE80211W */ 553 default: 554 wpa_printf(MSG_INFO, "%s: unknown/unsupported algorithm %d", 555 __func__, alg); 556 return -1; 557 } 558 559 if (key_len > sizeof(wk.ik_keydata)) { 560 wpa_printf(MSG_INFO, "%s: key length %lu too big", __func__, 561 (unsigned long) key_len); 562 return -3; 563 } 564 565 os_memset(&wk, 0, sizeof(wk)); 566 wk.ik_type = cipher; 567 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 568 if (addr == NULL || is_broadcast_ether_addr(addr)) { 569 os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 570 wk.ik_keyix = key_idx; 571 if (set_tx) 572 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 573 } else { 574 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 575 wk.ik_keyix = IEEE80211_KEYIX_NONE; 576 } 577 wk.ik_keylen = key_len; 578 os_memcpy(wk.ik_keydata, key, key_len); 579 580 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 581 if (ret < 0) { 582 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 583 " key_idx %d alg %d key_len %lu set_tx %d)", 584 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 585 alg, (unsigned long) key_len, set_tx); 586 } 587 588 return ret; 589 } 590 591 592 static int 593 atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 594 u8 *seq) 595 { 596 struct atheros_driver_data *drv = priv; 597 struct ieee80211req_key wk; 598 599 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 600 __func__, ether_sprintf(addr), idx); 601 602 os_memset(&wk, 0, sizeof(wk)); 603 if (addr == NULL) 604 os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 605 else 606 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 607 wk.ik_keyix = idx; 608 609 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 610 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 611 "(addr " MACSTR " key_idx %d)", 612 __func__, MAC2STR(wk.ik_macaddr), idx); 613 return -1; 614 } 615 616 #ifdef WORDS_BIGENDIAN 617 { 618 /* 619 * wk.ik_keytsc is in host byte order (big endian), need to 620 * swap it to match with the byte order used in WPA. 621 */ 622 int i; 623 #ifndef WPA_KEY_RSC_LEN 624 #define WPA_KEY_RSC_LEN 8 625 #endif 626 u8 tmp[WPA_KEY_RSC_LEN]; 627 os_memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 628 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 629 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 630 } 631 } 632 #else /* WORDS_BIGENDIAN */ 633 os_memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 634 #endif /* WORDS_BIGENDIAN */ 635 return 0; 636 } 637 638 639 static int 640 atheros_flush(void *priv) 641 { 642 u8 allsta[IEEE80211_ADDR_LEN]; 643 os_memset(allsta, 0xff, IEEE80211_ADDR_LEN); 644 return atheros_sta_deauth(priv, NULL, allsta, 645 IEEE80211_REASON_AUTH_LEAVE); 646 } 647 648 649 static int 650 atheros_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 651 const u8 *addr) 652 { 653 struct atheros_driver_data *drv = priv; 654 struct ieee80211req_sta_stats stats; 655 656 os_memset(data, 0, sizeof(*data)); 657 658 /* 659 * Fetch statistics for station from the system. 660 */ 661 os_memset(&stats, 0, sizeof(stats)); 662 os_memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 663 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS, 664 &stats, sizeof(stats))) { 665 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 666 MACSTR ")", __func__, MAC2STR(addr)); 667 if (os_memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 668 os_memcpy(data, &drv->acct_data, sizeof(*data)); 669 return 0; 670 } 671 672 wpa_printf(MSG_INFO, 673 "Failed to get station stats information element"); 674 return -1; 675 } 676 677 data->rx_packets = stats.is_stats.ns_rx_data; 678 data->rx_bytes = stats.is_stats.ns_rx_bytes; 679 data->tx_packets = stats.is_stats.ns_tx_data; 680 data->tx_bytes = stats.is_stats.ns_tx_bytes; 681 return 0; 682 } 683 684 685 static int 686 atheros_sta_clear_stats(void *priv, const u8 *addr) 687 { 688 struct atheros_driver_data *drv = priv; 689 struct ieee80211req_mlme mlme; 690 int ret; 691 692 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 693 694 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 695 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 696 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 697 sizeof(mlme)); 698 if (ret < 0) { 699 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 700 MACSTR ")", __func__, MAC2STR(addr)); 701 } 702 703 return ret; 704 } 705 706 707 static int 708 atheros_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 709 { 710 struct atheros_driver_data *drv = priv; 711 u8 buf[512]; 712 struct ieee80211req_getset_appiebuf *app_ie; 713 714 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 715 (unsigned long) ie_len); 716 wpa_hexdump(MSG_DEBUG, "atheros: set_generic_elem", ie, ie_len); 717 718 wpabuf_free(drv->wpa_ie); 719 if (ie) 720 drv->wpa_ie = wpabuf_alloc_copy(ie, ie_len); 721 else 722 drv->wpa_ie = NULL; 723 724 app_ie = (struct ieee80211req_getset_appiebuf *) buf; 725 if (ie) 726 os_memcpy(&(app_ie->app_buf[0]), ie, ie_len); 727 app_ie->app_buflen = ie_len; 728 729 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_BEACON; 730 731 /* append WPS IE for Beacon */ 732 if (drv->wps_beacon_ie != NULL) { 733 os_memcpy(&(app_ie->app_buf[ie_len]), 734 wpabuf_head(drv->wps_beacon_ie), 735 wpabuf_len(drv->wps_beacon_ie)); 736 app_ie->app_buflen = ie_len + wpabuf_len(drv->wps_beacon_ie); 737 } 738 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(Beacon)", 739 app_ie->app_buf, app_ie->app_buflen); 740 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 741 sizeof(struct ieee80211req_getset_appiebuf) + 742 app_ie->app_buflen); 743 744 /* append WPS IE for Probe Response */ 745 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_RESP; 746 if (drv->wps_probe_resp_ie != NULL) { 747 os_memcpy(&(app_ie->app_buf[ie_len]), 748 wpabuf_head(drv->wps_probe_resp_ie), 749 wpabuf_len(drv->wps_probe_resp_ie)); 750 app_ie->app_buflen = ie_len + 751 wpabuf_len(drv->wps_probe_resp_ie); 752 } else 753 app_ie->app_buflen = ie_len; 754 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(ProbeResp)", 755 app_ie->app_buf, app_ie->app_buflen); 756 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 757 sizeof(struct ieee80211req_getset_appiebuf) + 758 app_ie->app_buflen); 759 return 0; 760 } 761 762 static int 763 atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 764 int reason_code) 765 { 766 struct atheros_driver_data *drv = priv; 767 struct ieee80211req_mlme mlme; 768 int ret; 769 770 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 771 __func__, ether_sprintf(addr), reason_code); 772 773 mlme.im_op = IEEE80211_MLME_DEAUTH; 774 mlme.im_reason = reason_code; 775 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 776 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 777 if (ret < 0) { 778 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 779 " reason %d)", 780 __func__, MAC2STR(addr), reason_code); 781 } 782 783 return ret; 784 } 785 786 static int 787 atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 788 int reason_code) 789 { 790 struct atheros_driver_data *drv = priv; 791 struct ieee80211req_mlme mlme; 792 int ret; 793 794 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 795 __func__, ether_sprintf(addr), reason_code); 796 797 mlme.im_op = IEEE80211_MLME_DISASSOC; 798 mlme.im_reason = reason_code; 799 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 800 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 801 if (ret < 0) { 802 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 803 MACSTR " reason %d)", 804 __func__, MAC2STR(addr), reason_code); 805 } 806 807 return ret; 808 } 809 810 static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set, 811 u8 qos_map_set_len) 812 { 813 #ifdef CONFIG_ATHEROS_QOS_MAP 814 struct atheros_driver_data *drv = ctx; 815 struct ieee80211req_athdbg req; 816 struct ieee80211_qos_map *qos_map = &req.data.qos_map; 817 struct iwreq iwr; 818 int i, up_start; 819 820 if (qos_map_set_len < 16 || qos_map_set_len > 58 || 821 qos_map_set_len & 1) { 822 wpa_printf(MSG_ERROR, "Invalid QoS Map"); 823 return -1; 824 } else { 825 os_memset(&req, 0, sizeof(struct ieee80211req_athdbg)); 826 req.cmd = IEEE80211_DBGREQ_SETQOSMAPCONF; 827 os_memset(&iwr, 0, sizeof(iwr)); 828 os_strlcpy(iwr.ifr_name, drv->iface, sizeof(iwr.ifr_name)); 829 iwr.u.data.pointer = (void *) &req; 830 iwr.u.data.length = sizeof(struct ieee80211req_athdbg); 831 } 832 833 qos_map->valid = 1; 834 qos_map->num_dscp_except = (qos_map_set_len - 16) / 2; 835 if (qos_map->num_dscp_except) { 836 for (i = 0; i < qos_map->num_dscp_except; i++) { 837 qos_map->dscp_exception[i].dscp = qos_map_set[i * 2]; 838 qos_map->dscp_exception[i].up = qos_map_set[i * 2 + 1]; 839 } 840 } 841 842 up_start = qos_map_set_len - 16; 843 for (i = 0; i < IEEE80211_MAX_QOS_UP_RANGE; i++) { 844 qos_map->up[i].low = qos_map_set[up_start + (i * 2)]; 845 qos_map->up[i].high = qos_map_set[up_start + (i * 2) + 1]; 846 } 847 848 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_DBGREQ, &iwr) < 0) { 849 wpa_printf(MSG_ERROR, 850 "%s: %s: Failed to set QoS Map: ioctl[IEEE80211_IOCTL_DBGREQ]: %s", 851 __func__, drv->iface, strerror(errno)); 852 return -1; 853 } 854 #endif /* CONFIG_ATHEROS_QOS_MAP */ 855 856 return 0; 857 } 858 859 #ifdef ATHEROS_USE_RAW_RECEIVE 860 static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 861 size_t len) 862 { 863 struct atheros_driver_data *drv = ctx; 864 const struct ieee80211_mgmt *mgmt; 865 union wpa_event_data event; 866 u16 fc, stype; 867 int ielen; 868 const u8 *iebuf; 869 870 if (len < IEEE80211_HDRLEN) 871 return; 872 873 mgmt = (const struct ieee80211_mgmt *) buf; 874 875 fc = le_to_host16(mgmt->frame_control); 876 877 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) 878 return; 879 880 stype = WLAN_FC_GET_STYPE(fc); 881 882 wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype, 883 (int) len); 884 885 if (stype == WLAN_FC_STYPE_PROBE_REQ) { 886 if (len < IEEE80211_HDRLEN) 887 return; 888 889 os_memset(&event, 0, sizeof(event)); 890 event.rx_probe_req.sa = mgmt->sa; 891 event.rx_probe_req.da = mgmt->da; 892 event.rx_probe_req.bssid = mgmt->bssid; 893 event.rx_probe_req.ie = buf + IEEE80211_HDRLEN; 894 event.rx_probe_req.ie_len = len - IEEE80211_HDRLEN; 895 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 896 return; 897 } 898 899 if (stype == WLAN_FC_STYPE_ACTION && 900 (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) == 0 || 901 is_broadcast_ether_addr(mgmt->bssid))) { 902 os_memset(&event, 0, sizeof(event)); 903 event.rx_mgmt.frame = buf; 904 event.rx_mgmt.frame_len = len; 905 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); 906 return; 907 } 908 909 if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) { 910 wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore", 911 __func__); 912 return; 913 } 914 915 switch (stype) { 916 case WLAN_FC_STYPE_ASSOC_REQ: 917 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)) 918 break; 919 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 920 iebuf = mgmt->u.assoc_req.variable; 921 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0); 922 break; 923 case WLAN_FC_STYPE_REASSOC_REQ: 924 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)) 925 break; 926 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 927 iebuf = mgmt->u.reassoc_req.variable; 928 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1); 929 break; 930 case WLAN_FC_STYPE_AUTH: 931 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) 932 break; 933 os_memset(&event, 0, sizeof(event)); 934 if (le_to_host16(mgmt->u.auth.auth_alg) == WLAN_AUTH_SAE) { 935 event.rx_mgmt.frame = buf; 936 event.rx_mgmt.frame_len = len; 937 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); 938 break; 939 } 940 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN); 941 os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN); 942 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg); 943 event.auth.status_code = 944 le_to_host16(mgmt->u.auth.status_code); 945 event.auth.auth_transaction = 946 le_to_host16(mgmt->u.auth.auth_transaction); 947 event.auth.ies = mgmt->u.auth.variable; 948 event.auth.ies_len = len - IEEE80211_HDRLEN - 949 sizeof(mgmt->u.auth); 950 wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event); 951 break; 952 default: 953 break; 954 } 955 } 956 #endif /* ATHEROS_USE_RAW_RECEIVE */ 957 958 static int atheros_receive_pkt(struct atheros_driver_data *drv) 959 { 960 int ret = 0; 961 struct ieee80211req_set_filter filt; 962 963 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 964 filt.app_filterype = 0; 965 #ifdef CONFIG_WPS 966 filt.app_filterype |= IEEE80211_FILTER_TYPE_PROBE_REQ; 967 #endif /* CONFIG_WPS */ 968 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS) 969 filt.app_filterype |= (IEEE80211_FILTER_TYPE_ASSOC_REQ | 970 IEEE80211_FILTER_TYPE_AUTH | 971 IEEE80211_FILTER_TYPE_ACTION); 972 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W || CONFIG_FILS */ 973 #ifdef CONFIG_WNM 974 filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION; 975 #endif /* CONFIG_WNM */ 976 #ifdef CONFIG_HS20 977 filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION; 978 #endif /* CONFIG_HS20 */ 979 if (filt.app_filterype) { 980 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 981 sizeof(struct ieee80211req_set_filter)); 982 if (ret) 983 return ret; 984 } 985 986 #if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS) 987 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 988 atheros_raw_receive, drv, 1); 989 if (drv->sock_raw == NULL) 990 return -1; 991 #endif /* CONFIG_WPS || CONFIG_IEEE80211R || CONFIG_FILS */ 992 return ret; 993 } 994 995 static int atheros_reset_appfilter(struct atheros_driver_data *drv) 996 { 997 struct ieee80211req_set_filter filt; 998 filt.app_filterype = 0; 999 return set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 1000 sizeof(struct ieee80211req_set_filter)); 1001 } 1002 1003 #ifdef CONFIG_WPS 1004 static int 1005 atheros_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 1006 { 1007 struct atheros_driver_data *drv = priv; 1008 u8 buf[512]; 1009 struct ieee80211req_getset_appiebuf *beac_ie; 1010 1011 wpa_printf(MSG_DEBUG, "%s buflen = %lu frametype=%u", __func__, 1012 (unsigned long) len, frametype); 1013 wpa_hexdump(MSG_DEBUG, "atheros: IE", ie, len); 1014 1015 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 1016 beac_ie->app_frmtype = frametype; 1017 beac_ie->app_buflen = len; 1018 if (ie) 1019 os_memcpy(&(beac_ie->app_buf[0]), ie, len); 1020 1021 /* append the WPA/RSN IE if it is set already */ 1022 if (((frametype == IEEE80211_APPIE_FRAME_BEACON) || 1023 (frametype == IEEE80211_APPIE_FRAME_PROBE_RESP)) && 1024 (drv->wpa_ie != NULL)) { 1025 wpa_hexdump_buf(MSG_DEBUG, "atheros: Append WPA/RSN IE", 1026 drv->wpa_ie); 1027 os_memcpy(&(beac_ie->app_buf[len]), wpabuf_head(drv->wpa_ie), 1028 wpabuf_len(drv->wpa_ie)); 1029 beac_ie->app_buflen += wpabuf_len(drv->wpa_ie); 1030 } 1031 1032 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF", 1033 beac_ie->app_buf, beac_ie->app_buflen); 1034 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 1035 sizeof(struct ieee80211req_getset_appiebuf) + 1036 beac_ie->app_buflen); 1037 } 1038 1039 static int 1040 atheros_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 1041 const struct wpabuf *proberesp, 1042 const struct wpabuf *assocresp) 1043 { 1044 struct atheros_driver_data *drv = priv; 1045 1046 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - beacon", beacon); 1047 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - proberesp", 1048 proberesp); 1049 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - assocresp", 1050 assocresp); 1051 wpabuf_free(drv->wps_beacon_ie); 1052 drv->wps_beacon_ie = beacon ? wpabuf_dup(beacon) : NULL; 1053 wpabuf_free(drv->wps_probe_resp_ie); 1054 drv->wps_probe_resp_ie = proberesp ? wpabuf_dup(proberesp) : NULL; 1055 1056 atheros_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL, 1057 assocresp ? wpabuf_len(assocresp) : 0, 1058 IEEE80211_APPIE_FRAME_ASSOC_RESP); 1059 if (atheros_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 1060 beacon ? wpabuf_len(beacon) : 0, 1061 IEEE80211_APPIE_FRAME_BEACON)) 1062 return -1; 1063 return atheros_set_wps_ie(priv, 1064 proberesp ? wpabuf_head(proberesp) : NULL, 1065 proberesp ? wpabuf_len(proberesp): 0, 1066 IEEE80211_APPIE_FRAME_PROBE_RESP); 1067 } 1068 #else /* CONFIG_WPS */ 1069 #define atheros_set_ap_wps_ie NULL 1070 #endif /* CONFIG_WPS */ 1071 1072 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) 1073 static int 1074 atheros_sta_auth(void *priv, struct wpa_driver_sta_auth_params *params) 1075 { 1076 struct atheros_driver_data *drv = priv; 1077 struct ieee80211req_mlme mlme; 1078 int ret; 1079 1080 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d", 1081 __func__, ether_sprintf(params->addr), params->status); 1082 1083 #ifdef CONFIG_FILS 1084 /* Copy FILS AAD parameters if the driver supports FILS */ 1085 if (params->fils_auth && drv->fils_en) { 1086 wpa_printf(MSG_DEBUG, "%s: im_op IEEE80211_MLME_AUTH_FILS", 1087 __func__); 1088 os_memcpy(mlme.fils_aad.ANonce, params->fils_anonce, 1089 IEEE80211_FILS_NONCE_LEN); 1090 os_memcpy(mlme.fils_aad.SNonce, params->fils_snonce, 1091 IEEE80211_FILS_NONCE_LEN); 1092 os_memcpy(mlme.fils_aad.kek, params->fils_kek, 1093 IEEE80211_MAX_WPA_KEK_LEN); 1094 mlme.fils_aad.kek_len = params->fils_kek_len; 1095 mlme.im_op = IEEE80211_MLME_AUTH_FILS; 1096 wpa_hexdump(MSG_DEBUG, "FILS: ANonce", 1097 mlme.fils_aad.ANonce, FILS_NONCE_LEN); 1098 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", 1099 mlme.fils_aad.SNonce, FILS_NONCE_LEN); 1100 wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", 1101 mlme.fils_aad.kek, mlme.fils_aad.kek_len); 1102 } else { 1103 mlme.im_op = IEEE80211_MLME_AUTH; 1104 } 1105 #else /* CONFIG_FILS */ 1106 mlme.im_op = IEEE80211_MLME_AUTH; 1107 #endif /* CONFIG_FILS */ 1108 1109 mlme.im_reason = params->status; 1110 mlme.im_seq = params->seq; 1111 os_memcpy(mlme.im_macaddr, params->addr, IEEE80211_ADDR_LEN); 1112 mlme.im_optie_len = params->len; 1113 if (params->len) { 1114 if (params->len < IEEE80211_MAX_OPT_IE) { 1115 os_memcpy(mlme.im_optie, params->ie, params->len); 1116 } else { 1117 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 1118 "opt_ie STA (addr " MACSTR " reason %d, " 1119 "ie_len %d)", 1120 __func__, MAC2STR(params->addr), 1121 params->status, (int) params->len); 1122 return -1; 1123 } 1124 } 1125 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 1126 if (ret < 0) { 1127 wpa_printf(MSG_DEBUG, "%s: Failed to auth STA (addr " MACSTR 1128 " reason %d)", 1129 __func__, MAC2STR(params->addr), params->status); 1130 } 1131 return ret; 1132 } 1133 1134 static int 1135 atheros_sta_assoc(void *priv, const u8 *own_addr, const u8 *addr, 1136 int reassoc, u16 status_code, const u8 *ie, size_t len) 1137 { 1138 struct atheros_driver_data *drv = priv; 1139 struct ieee80211req_mlme mlme; 1140 int ret; 1141 1142 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d reassoc %d", 1143 __func__, ether_sprintf(addr), status_code, reassoc); 1144 1145 if (reassoc) 1146 mlme.im_op = IEEE80211_MLME_REASSOC; 1147 else 1148 mlme.im_op = IEEE80211_MLME_ASSOC; 1149 mlme.im_reason = status_code; 1150 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1151 mlme.im_optie_len = len; 1152 if (len) { 1153 if (len < IEEE80211_MAX_OPT_IE) { 1154 os_memcpy(mlme.im_optie, ie, len); 1155 } else { 1156 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 1157 "opt_ie STA (addr " MACSTR " reason %d, " 1158 "ie_len %d)", 1159 __func__, MAC2STR(addr), status_code, 1160 (int) len); 1161 return -1; 1162 } 1163 } 1164 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 1165 if (ret < 0) { 1166 wpa_printf(MSG_DEBUG, "%s: Failed to assoc STA (addr " MACSTR 1167 " reason %d)", 1168 __func__, MAC2STR(addr), status_code); 1169 } 1170 return ret; 1171 } 1172 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W || CONFIG_FILS */ 1173 1174 static void 1175 atheros_new_sta(struct atheros_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 1176 { 1177 struct hostapd_data *hapd = drv->hapd; 1178 struct ieee80211req_wpaie ie; 1179 int ielen = 0; 1180 u8 *iebuf = NULL; 1181 1182 /* 1183 * Fetch negotiated WPA/RSN parameters from the system. 1184 */ 1185 os_memset(&ie, 0, sizeof(ie)); 1186 os_memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 1187 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 1188 /* 1189 * See ATH_WPS_IE comment in the beginning of the file for a 1190 * possible cause for the failure.. 1191 */ 1192 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", 1193 __func__, strerror(errno)); 1194 goto no_ie; 1195 } 1196 wpa_hexdump(MSG_MSGDUMP, "atheros req WPA IE", 1197 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 1198 wpa_hexdump(MSG_MSGDUMP, "atheros req RSN IE", 1199 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 1200 #ifdef ATH_WPS_IE 1201 wpa_hexdump(MSG_MSGDUMP, "atheros req WPS IE", 1202 ie.wps_ie, IEEE80211_MAX_OPT_IE); 1203 #endif /* ATH_WPS_IE */ 1204 iebuf = ie.wpa_ie; 1205 /* atheros seems to return some random data if WPA/RSN IE is not set. 1206 * Assume the IE was not included if the IE type is unknown. */ 1207 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 1208 iebuf[1] = 0; 1209 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 1210 /* atheros-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 1211 * set. This is needed for WPA2. */ 1212 iebuf = ie.rsn_ie; 1213 if (iebuf[0] != WLAN_EID_RSN) 1214 iebuf[1] = 0; 1215 } 1216 1217 ielen = iebuf[1]; 1218 1219 #ifdef ATH_WPS_IE 1220 /* if WPS IE is present, preference is given to WPS */ 1221 if (ie.wps_ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie.wps_ie[1] > 0) { 1222 iebuf = ie.wps_ie; 1223 ielen = ie.wps_ie[1]; 1224 } 1225 #endif /* ATH_WPS_IE */ 1226 1227 if (ielen == 0) 1228 iebuf = NULL; 1229 else 1230 ielen += 2; 1231 1232 no_ie: 1233 drv_event_assoc(hapd, addr, iebuf, ielen, 0); 1234 1235 if (os_memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 1236 /* Cached accounting data is not valid anymore. */ 1237 os_memset(drv->acct_mac, 0, ETH_ALEN); 1238 os_memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 1239 } 1240 } 1241 1242 static void 1243 atheros_wireless_event_wireless_custom(struct atheros_driver_data *drv, 1244 char *custom, char *end) 1245 { 1246 #define MGMT_FRAM_TAG_SIZE 30 /* hardcoded in driver */ 1247 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 1248 1249 if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 1250 char *pos; 1251 u8 addr[ETH_ALEN]; 1252 pos = os_strstr(custom, "addr="); 1253 if (pos == NULL) { 1254 wpa_printf(MSG_DEBUG, 1255 "MLME-MICHAELMICFAILURE.indication " 1256 "without sender address ignored"); 1257 return; 1258 } 1259 pos += 5; 1260 if (hwaddr_aton(pos, addr) == 0) { 1261 union wpa_event_data data; 1262 os_memset(&data, 0, sizeof(data)); 1263 data.michael_mic_failure.unicast = 1; 1264 data.michael_mic_failure.src = addr; 1265 wpa_supplicant_event(drv->hapd, 1266 EVENT_MICHAEL_MIC_FAILURE, &data); 1267 } else { 1268 wpa_printf(MSG_DEBUG, 1269 "MLME-MICHAELMICFAILURE.indication " 1270 "with invalid MAC address"); 1271 } 1272 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 1273 char *key, *value; 1274 u32 val; 1275 key = custom; 1276 while ((key = os_strchr(key, '\n')) != NULL) { 1277 key++; 1278 value = os_strchr(key, '='); 1279 if (value == NULL) 1280 continue; 1281 *value++ = '\0'; 1282 val = strtoul(value, NULL, 10); 1283 if (os_strcmp(key, "mac") == 0) 1284 hwaddr_aton(value, drv->acct_mac); 1285 else if (os_strcmp(key, "rx_packets") == 0) 1286 drv->acct_data.rx_packets = val; 1287 else if (os_strcmp(key, "tx_packets") == 0) 1288 drv->acct_data.tx_packets = val; 1289 else if (os_strcmp(key, "rx_bytes") == 0) 1290 drv->acct_data.rx_bytes = val; 1291 else if (os_strcmp(key, "tx_bytes") == 0) 1292 drv->acct_data.tx_bytes = val; 1293 key = value; 1294 } 1295 #ifdef CONFIG_WPS 1296 } else if (os_strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) { 1297 /* Some atheros kernels send push button as a wireless event */ 1298 /* PROBLEM! this event is received for ALL BSSs ... 1299 * so all are enabled for WPS... ugh. 1300 */ 1301 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); 1302 } else if (os_strncmp(custom, "Manage.prob_req ", 16) == 0) { 1303 /* 1304 * Atheros driver uses a hack to pass Probe Request frames as a 1305 * binary data in the custom wireless event. The old way (using 1306 * packet sniffing) didn't work when bridging. 1307 * Format: "Manage.prob_req <frame len>" | zero padding | frame 1308 */ 1309 int len = atoi(custom + 16); 1310 if (len < 0 || MGMT_FRAM_TAG_SIZE + len > end - custom) { 1311 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event " 1312 "length %d", len); 1313 return; 1314 } 1315 atheros_raw_receive(drv, NULL, 1316 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1317 #endif /* CONFIG_WPS */ 1318 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) 1319 } else if (os_strncmp(custom, "Manage.assoc_req ", 17) == 0) { 1320 /* Format: "Manage.assoc_req <frame len>" | zero padding | 1321 * frame */ 1322 int len = atoi(custom + 17); 1323 if (len < 0 || MGMT_FRAM_TAG_SIZE + len > end - custom) { 1324 wpa_printf(MSG_DEBUG, 1325 "Invalid Manage.assoc_req event length %d", 1326 len); 1327 return; 1328 } 1329 atheros_raw_receive(drv, NULL, 1330 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1331 } else if (os_strncmp(custom, "Manage.auth ", 12) == 0) { 1332 /* Format: "Manage.auth <frame len>" | zero padding | frame */ 1333 int len = atoi(custom + 12); 1334 if (len < 0 || 1335 MGMT_FRAM_TAG_SIZE + len > end - custom) { 1336 wpa_printf(MSG_DEBUG, 1337 "Invalid Manage.auth event length %d", len); 1338 return; 1339 } 1340 atheros_raw_receive(drv, NULL, 1341 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1342 #endif /* CONFIG_IEEE80211W || CONFIG_IEEE80211R || CONFIG_FILS */ 1343 #ifdef ATHEROS_USE_RAW_RECEIVE 1344 } else if (os_strncmp(custom, "Manage.action ", 14) == 0) { 1345 /* Format: "Manage.assoc_req <frame len>" | zero padding | frame 1346 */ 1347 int len = atoi(custom + 14); 1348 if (len < 0 || MGMT_FRAM_TAG_SIZE + len > end - custom) { 1349 wpa_printf(MSG_DEBUG, 1350 "Invalid Manage.action event length %d", 1351 len); 1352 return; 1353 } 1354 atheros_raw_receive(drv, NULL, 1355 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1356 #endif /* ATHEROS_USE_RAW_RECEIVE */ 1357 } 1358 } 1359 1360 1361 static void send_action_cb_event(struct atheros_driver_data *drv, 1362 char *data, size_t data_len) 1363 { 1364 union wpa_event_data event; 1365 struct ieee80211_send_action_cb *sa; 1366 const struct ieee80211_hdr *hdr; 1367 u16 fc; 1368 1369 if (data_len < sizeof(*sa) + 24) { 1370 wpa_printf(MSG_DEBUG, 1371 "athr: Too short event message (data_len=%d sizeof(*sa)=%d)", 1372 (int) data_len, (int) sizeof(*sa)); 1373 wpa_hexdump(MSG_DEBUG, "athr: Short event message", 1374 data, data_len); 1375 return; 1376 } 1377 1378 sa = (struct ieee80211_send_action_cb *) data; 1379 1380 hdr = (const struct ieee80211_hdr *) (sa + 1); 1381 fc = le_to_host16(hdr->frame_control); 1382 1383 os_memset(&event, 0, sizeof(event)); 1384 event.tx_status.type = WLAN_FC_GET_TYPE(fc); 1385 event.tx_status.stype = WLAN_FC_GET_STYPE(fc); 1386 event.tx_status.dst = sa->dst_addr; 1387 event.tx_status.data = (const u8 *) hdr; 1388 event.tx_status.data_len = data_len - sizeof(*sa); 1389 event.tx_status.ack = sa->ack; 1390 wpa_supplicant_event(drv->hapd, EVENT_TX_STATUS, &event); 1391 } 1392 1393 1394 /* 1395 * Handle size of data problem. WEXT only allows data of 256 bytes for custom 1396 * events, and p2p data can be much bigger. So the athr driver sends a small 1397 * event telling me to collect the big data with an ioctl. 1398 * On the first event, send all pending events to supplicant. 1399 */ 1400 static void fetch_pending_big_events(struct atheros_driver_data *drv) 1401 { 1402 union wpa_event_data event; 1403 const struct ieee80211_mgmt *mgmt; 1404 u8 tbuf[IW_PRIV_SIZE_MASK]; /* max size is 2047 bytes */ 1405 u16 fc, stype; 1406 struct iwreq iwr; 1407 size_t data_len; 1408 u32 freq, frame_type; 1409 1410 while (1) { 1411 os_memset(&iwr, 0, sizeof(iwr)); 1412 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1413 1414 iwr.u.data.pointer = (void *) tbuf; 1415 iwr.u.data.length = sizeof(tbuf); 1416 iwr.u.data.flags = IEEE80211_IOC_P2P_FETCH_FRAME; 1417 1418 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr) 1419 < 0) { 1420 if (errno == ENOSPC) { 1421 wpa_printf(MSG_DEBUG, "%s:%d exit", 1422 __func__, __LINE__); 1423 return; 1424 } 1425 wpa_printf(MSG_DEBUG, "athr: %s: P2P_BIG_PARAM[" 1426 "P2P_FETCH_FRAME] failed: %s", 1427 __func__, strerror(errno)); 1428 return; 1429 } 1430 data_len = iwr.u.data.length; 1431 wpa_hexdump(MSG_DEBUG, "athr: P2P_FETCH_FRAME data", 1432 (u8 *) tbuf, data_len); 1433 if (data_len < sizeof(freq) + sizeof(frame_type) + 24) { 1434 wpa_printf(MSG_DEBUG, "athr: frame too short"); 1435 continue; 1436 } 1437 os_memcpy(&freq, tbuf, sizeof(freq)); 1438 os_memcpy(&frame_type, &tbuf[sizeof(freq)], 1439 sizeof(frame_type)); 1440 mgmt = (void *) &tbuf[sizeof(freq) + sizeof(frame_type)]; 1441 data_len -= sizeof(freq) + sizeof(frame_type); 1442 1443 if (frame_type == IEEE80211_EV_RX_MGMT) { 1444 fc = le_to_host16(mgmt->frame_control); 1445 stype = WLAN_FC_GET_STYPE(fc); 1446 1447 wpa_printf(MSG_DEBUG, "athr: EV_RX_MGMT stype=%u " 1448 "freq=%u len=%u", stype, freq, (int) data_len); 1449 1450 if (stype == WLAN_FC_STYPE_ACTION) { 1451 os_memset(&event, 0, sizeof(event)); 1452 event.rx_mgmt.frame = (const u8 *) mgmt; 1453 event.rx_mgmt.frame_len = data_len; 1454 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, 1455 &event); 1456 continue; 1457 } 1458 } else if (frame_type == IEEE80211_EV_P2P_SEND_ACTION_CB) { 1459 wpa_printf(MSG_DEBUG, 1460 "%s: ACTION_CB frame_type=%u len=%zu", 1461 __func__, frame_type, data_len); 1462 send_action_cb_event(drv, (void *) mgmt, data_len); 1463 } else { 1464 wpa_printf(MSG_DEBUG, "athr: %s unknown type %d", 1465 __func__, frame_type); 1466 continue; 1467 } 1468 } 1469 } 1470 1471 static void 1472 atheros_wireless_event_atheros_custom(struct atheros_driver_data *drv, 1473 int opcode, char *buf, int len) 1474 { 1475 switch (opcode) { 1476 case IEEE80211_EV_P2P_SEND_ACTION_CB: 1477 wpa_printf(MSG_DEBUG, "WEXT: EV_P2P_SEND_ACTION_CB"); 1478 fetch_pending_big_events(drv); 1479 break; 1480 case IEEE80211_EV_RX_MGMT: 1481 wpa_printf(MSG_DEBUG, "WEXT: EV_RX_MGMT"); 1482 fetch_pending_big_events(drv); 1483 break; 1484 default: 1485 break; 1486 } 1487 } 1488 1489 static void 1490 atheros_wireless_event_wireless(struct atheros_driver_data *drv, 1491 char *data, unsigned int len) 1492 { 1493 struct iw_event iwe_buf, *iwe = &iwe_buf; 1494 char *pos, *end, *custom, *buf; 1495 1496 pos = data; 1497 end = data + len; 1498 1499 while ((size_t) (end - pos) >= IW_EV_LCP_LEN) { 1500 /* Event data may be unaligned, so make a local, aligned copy 1501 * before processing. */ 1502 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 1503 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 1504 iwe->cmd, iwe->len); 1505 if (iwe->len <= IW_EV_LCP_LEN || iwe->len > end - pos) 1506 return; 1507 1508 custom = pos + IW_EV_POINT_LEN; 1509 if (drv->we_version > 18 && 1510 (iwe->cmd == IWEVMICHAELMICFAILURE || 1511 iwe->cmd == IWEVASSOCREQIE || 1512 iwe->cmd == IWEVCUSTOM)) { 1513 /* WE-19 removed the pointer from struct iw_point */ 1514 char *dpos = (char *) &iwe_buf.u.data.length; 1515 int dlen = dpos - (char *) &iwe_buf; 1516 os_memcpy(dpos, pos + IW_EV_LCP_LEN, 1517 sizeof(struct iw_event) - dlen); 1518 } else { 1519 os_memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 1520 custom += IW_EV_POINT_OFF; 1521 } 1522 1523 switch (iwe->cmd) { 1524 case IWEVEXPIRED: 1525 drv_event_disassoc(drv->hapd, 1526 (u8 *) iwe->u.addr.sa_data); 1527 break; 1528 case IWEVREGISTERED: 1529 atheros_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 1530 break; 1531 case IWEVASSOCREQIE: 1532 /* Driver hack.. Use IWEVASSOCREQIE to bypass 1533 * IWEVCUSTOM size limitations. Need to handle this 1534 * just like IWEVCUSTOM. 1535 */ 1536 case IWEVCUSTOM: 1537 if (iwe->u.data.length > end - custom) 1538 return; 1539 buf = os_malloc(iwe->u.data.length + 1); 1540 if (buf == NULL) 1541 return; /* XXX */ 1542 os_memcpy(buf, custom, iwe->u.data.length); 1543 buf[iwe->u.data.length] = '\0'; 1544 1545 if (iwe->u.data.flags != 0) { 1546 atheros_wireless_event_atheros_custom( 1547 drv, (int) iwe->u.data.flags, 1548 buf, len); 1549 } else { 1550 atheros_wireless_event_wireless_custom( 1551 drv, buf, buf + iwe->u.data.length); 1552 } 1553 os_free(buf); 1554 break; 1555 } 1556 1557 pos += iwe->len; 1558 } 1559 } 1560 1561 1562 static void 1563 atheros_wireless_event_rtm_newlink(void *ctx, 1564 struct ifinfomsg *ifi, u8 *buf, size_t len) 1565 { 1566 struct atheros_driver_data *drv = ctx; 1567 int attrlen, rta_len; 1568 struct rtattr *attr; 1569 1570 if (ifi->ifi_index != drv->ifindex) 1571 return; 1572 1573 attrlen = len; 1574 attr = (struct rtattr *) buf; 1575 1576 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 1577 while (RTA_OK(attr, attrlen)) { 1578 if (attr->rta_type == IFLA_WIRELESS) { 1579 atheros_wireless_event_wireless( 1580 drv, ((char *) attr) + rta_len, 1581 attr->rta_len - rta_len); 1582 } 1583 attr = RTA_NEXT(attr, attrlen); 1584 } 1585 } 1586 1587 1588 static int 1589 atheros_get_we_version(struct atheros_driver_data *drv) 1590 { 1591 struct iw_range *range; 1592 struct iwreq iwr; 1593 int minlen; 1594 size_t buflen; 1595 1596 drv->we_version = 0; 1597 1598 /* 1599 * Use larger buffer than struct iw_range in order to allow the 1600 * structure to grow in the future. 1601 */ 1602 buflen = sizeof(struct iw_range) + 500; 1603 range = os_zalloc(buflen); 1604 if (range == NULL) 1605 return -1; 1606 1607 os_memset(&iwr, 0, sizeof(iwr)); 1608 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1609 iwr.u.data.pointer = (caddr_t) range; 1610 iwr.u.data.length = buflen; 1611 1612 minlen = ((char *) &range->enc_capa) - (char *) range + 1613 sizeof(range->enc_capa); 1614 1615 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1616 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWRANGE]: %s", 1617 strerror(errno)); 1618 os_free(range); 1619 return -1; 1620 } else if (iwr.u.data.length >= minlen && 1621 range->we_version_compiled >= 18) { 1622 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1623 "WE(source)=%d enc_capa=0x%x", 1624 range->we_version_compiled, 1625 range->we_version_source, 1626 range->enc_capa); 1627 drv->we_version = range->we_version_compiled; 1628 } 1629 1630 os_free(range); 1631 return 0; 1632 } 1633 1634 1635 static int 1636 atheros_wireless_event_init(struct atheros_driver_data *drv) 1637 { 1638 struct netlink_config *cfg; 1639 1640 atheros_get_we_version(drv); 1641 1642 cfg = os_zalloc(sizeof(*cfg)); 1643 if (cfg == NULL) 1644 return -1; 1645 cfg->ctx = drv; 1646 cfg->newlink_cb = atheros_wireless_event_rtm_newlink; 1647 drv->netlink = netlink_init(cfg); 1648 if (drv->netlink == NULL) { 1649 os_free(cfg); 1650 return -1; 1651 } 1652 1653 return 0; 1654 } 1655 1656 1657 static int 1658 atheros_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 1659 int encrypt, const u8 *own_addr, u32 flags) 1660 { 1661 struct atheros_driver_data *drv = priv; 1662 unsigned char buf[3000]; 1663 unsigned char *bp = buf; 1664 struct l2_ethhdr *eth; 1665 size_t len; 1666 int status; 1667 1668 /* 1669 * Prepend the Ethernet header. If the caller left us 1670 * space at the front we could just insert it but since 1671 * we don't know we copy to a local buffer. Given the frequency 1672 * and size of frames this probably doesn't matter. 1673 */ 1674 len = data_len + sizeof(struct l2_ethhdr); 1675 if (len > sizeof(buf)) { 1676 bp = os_malloc(len); 1677 if (bp == NULL) { 1678 wpa_printf(MSG_INFO, 1679 "EAPOL frame discarded, cannot malloc temp buffer of size %lu!", 1680 (unsigned long) len); 1681 return -1; 1682 } 1683 } 1684 eth = (struct l2_ethhdr *) bp; 1685 os_memcpy(eth->h_dest, addr, ETH_ALEN); 1686 os_memcpy(eth->h_source, own_addr, ETH_ALEN); 1687 eth->h_proto = host_to_be16(ETH_P_EAPOL); 1688 os_memcpy(eth + 1, data, data_len); 1689 1690 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); 1691 1692 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); 1693 1694 if (bp != buf) 1695 os_free(bp); 1696 return status; 1697 } 1698 1699 static void 1700 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 1701 { 1702 struct atheros_driver_data *drv = ctx; 1703 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), 1704 len - sizeof(struct l2_ethhdr)); 1705 } 1706 1707 1708 static void atheros_read_fils_cap(struct atheros_driver_data *drv) 1709 { 1710 int fils = 0; 1711 1712 #ifdef CONFIG_FILS 1713 /* TODO: Would be better to have #ifdef on the IEEE80211_PARAM_* value 1714 * to automatically check this against the driver header files. */ 1715 if (get80211param(drv, IEEE80211_PARAM_ENABLE_FILS, &fils) < 0) { 1716 wpa_printf(MSG_DEBUG, 1717 "%s: Failed to get FILS capability from driver", 1718 __func__); 1719 /* Assume driver does not support FILS */ 1720 fils = 0; 1721 } 1722 #endif /* CONFIG_FILS */ 1723 drv->fils_en = fils; 1724 wpa_printf(MSG_DEBUG, "atheros: fils_en=%d", drv->fils_en); 1725 } 1726 1727 1728 static void * 1729 atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params) 1730 { 1731 struct atheros_driver_data *drv; 1732 struct ifreq ifr; 1733 struct iwreq iwr; 1734 char brname[IFNAMSIZ]; 1735 1736 drv = os_zalloc(sizeof(struct atheros_driver_data)); 1737 if (drv == NULL) { 1738 wpa_printf(MSG_INFO, 1739 "Could not allocate memory for atheros driver data"); 1740 return NULL; 1741 } 1742 1743 drv->hapd = hapd; 1744 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 1745 if (drv->ioctl_sock < 0) { 1746 wpa_printf(MSG_ERROR, "socket[PF_INET,SOCK_DGRAM]: %s", 1747 strerror(errno)); 1748 goto bad; 1749 } 1750 os_memcpy(drv->iface, params->ifname, sizeof(drv->iface)); 1751 1752 os_memset(&ifr, 0, sizeof(ifr)); 1753 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); 1754 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { 1755 wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s", 1756 strerror(errno)); 1757 goto bad; 1758 } 1759 drv->ifindex = ifr.ifr_ifindex; 1760 1761 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, 1762 handle_read, drv, 1); 1763 if (drv->sock_xmit == NULL) 1764 goto bad; 1765 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 1766 goto bad; 1767 os_memcpy(drv->own_addr, params->own_addr, ETH_ALEN); 1768 if (params->bridge[0]) { 1769 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", 1770 params->bridge[0]); 1771 drv->sock_recv = l2_packet_init(params->bridge[0], NULL, 1772 ETH_P_EAPOL, handle_read, drv, 1773 1); 1774 if (drv->sock_recv == NULL) 1775 goto bad; 1776 } else if (linux_br_get(brname, drv->iface) == 0) { 1777 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " 1778 "EAPOL receive", brname); 1779 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, 1780 handle_read, drv, 1); 1781 if (drv->sock_recv == NULL) 1782 goto bad; 1783 } else 1784 drv->sock_recv = drv->sock_xmit; 1785 1786 os_memset(&iwr, 0, sizeof(iwr)); 1787 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1788 1789 iwr.u.mode = IW_MODE_MASTER; 1790 1791 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { 1792 wpa_printf(MSG_ERROR, 1793 "Could not set interface to master mode! ioctl[SIOCSIWMODE]: %s", 1794 strerror(errno)); 1795 goto bad; 1796 } 1797 1798 /* mark down during setup */ 1799 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1800 atheros_set_privacy(drv, 0); /* default to no privacy */ 1801 1802 if (atheros_receive_pkt(drv)) 1803 goto bad; 1804 1805 if (atheros_wireless_event_init(drv)) 1806 goto bad; 1807 1808 /* Read FILS capability from the driver */ 1809 atheros_read_fils_cap(drv); 1810 1811 return drv; 1812 bad: 1813 atheros_reset_appfilter(drv); 1814 if (drv->sock_raw) 1815 l2_packet_deinit(drv->sock_raw); 1816 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1817 l2_packet_deinit(drv->sock_recv); 1818 if (drv->sock_xmit != NULL) 1819 l2_packet_deinit(drv->sock_xmit); 1820 if (drv->ioctl_sock >= 0) 1821 close(drv->ioctl_sock); 1822 os_free(drv); 1823 return NULL; 1824 } 1825 1826 1827 static void 1828 atheros_deinit(void *priv) 1829 { 1830 struct atheros_driver_data *drv = priv; 1831 1832 atheros_reset_appfilter(drv); 1833 1834 if (drv->wpa_ie || drv->wps_beacon_ie || drv->wps_probe_resp_ie) { 1835 atheros_set_opt_ie(priv, NULL, 0); 1836 wpabuf_free(drv->wpa_ie); 1837 wpabuf_free(drv->wps_beacon_ie); 1838 wpabuf_free(drv->wps_probe_resp_ie); 1839 } 1840 netlink_deinit(drv->netlink); 1841 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1842 if (drv->ioctl_sock >= 0) 1843 close(drv->ioctl_sock); 1844 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1845 l2_packet_deinit(drv->sock_recv); 1846 if (drv->sock_xmit != NULL) 1847 l2_packet_deinit(drv->sock_xmit); 1848 if (drv->sock_raw) 1849 l2_packet_deinit(drv->sock_raw); 1850 os_free(drv); 1851 } 1852 1853 static int 1854 atheros_set_ssid(void *priv, const u8 *buf, int len) 1855 { 1856 struct atheros_driver_data *drv = priv; 1857 struct iwreq iwr; 1858 1859 os_memset(&iwr, 0, sizeof(iwr)); 1860 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1861 iwr.u.essid.flags = 1; /* SSID active */ 1862 iwr.u.essid.pointer = (caddr_t) buf; 1863 iwr.u.essid.length = len; 1864 1865 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 1866 wpa_printf(MSG_ERROR, "ioctl[SIOCSIWESSID,len=%d]: %s", 1867 len, strerror(errno)); 1868 return -1; 1869 } 1870 return 0; 1871 } 1872 1873 static int 1874 atheros_get_ssid(void *priv, u8 *buf, int len) 1875 { 1876 struct atheros_driver_data *drv = priv; 1877 struct iwreq iwr; 1878 int ret = 0; 1879 1880 os_memset(&iwr, 0, sizeof(iwr)); 1881 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1882 iwr.u.essid.pointer = (caddr_t) buf; 1883 iwr.u.essid.length = (len > IW_ESSID_MAX_SIZE) ? 1884 IW_ESSID_MAX_SIZE : len; 1885 1886 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1887 wpa_printf(MSG_ERROR, "ioctl[SIOCGIWESSID]: %s", 1888 strerror(errno)); 1889 ret = -1; 1890 } else 1891 ret = iwr.u.essid.length; 1892 1893 return ret; 1894 } 1895 1896 static int 1897 atheros_set_countermeasures(void *priv, int enabled) 1898 { 1899 struct atheros_driver_data *drv = priv; 1900 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1901 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 1902 } 1903 1904 static int 1905 atheros_commit(void *priv) 1906 { 1907 struct atheros_driver_data *drv = priv; 1908 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 1909 } 1910 1911 static int atheros_set_authmode(void *priv, int auth_algs) 1912 { 1913 int authmode; 1914 1915 if ((auth_algs & WPA_AUTH_ALG_OPEN) && 1916 (auth_algs & WPA_AUTH_ALG_SHARED)) 1917 authmode = IEEE80211_AUTH_AUTO; 1918 else if (auth_algs & WPA_AUTH_ALG_OPEN) 1919 authmode = IEEE80211_AUTH_OPEN; 1920 else if (auth_algs & WPA_AUTH_ALG_SHARED) 1921 authmode = IEEE80211_AUTH_SHARED; 1922 else 1923 return -1; 1924 1925 return set80211param(priv, IEEE80211_PARAM_AUTHMODE, authmode); 1926 } 1927 1928 static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params) 1929 { 1930 /* 1931 * TODO: Use this to replace set_authmode, set_privacy, set_ieee8021x, 1932 * set_generic_elem, and hapd_set_ssid. 1933 */ 1934 1935 wpa_printf(MSG_DEBUG, "atheros: set_ap - pairwise_ciphers=0x%x " 1936 "group_cipher=0x%x key_mgmt_suites=0x%x auth_algs=0x%x " 1937 "wpa_version=0x%x privacy=%d interworking=%d", 1938 params->pairwise_ciphers, params->group_cipher, 1939 params->key_mgmt_suites, params->auth_algs, 1940 params->wpa_version, params->privacy, params->interworking); 1941 wpa_hexdump_ascii(MSG_DEBUG, "atheros: SSID", 1942 params->ssid, params->ssid_len); 1943 if (params->hessid) 1944 wpa_printf(MSG_DEBUG, "atheros: HESSID " MACSTR, 1945 MAC2STR(params->hessid)); 1946 wpa_hexdump_buf(MSG_DEBUG, "atheros: beacon_ies", 1947 params->beacon_ies); 1948 wpa_hexdump_buf(MSG_DEBUG, "atheros: proberesp_ies", 1949 params->proberesp_ies); 1950 wpa_hexdump_buf(MSG_DEBUG, "atheros: assocresp_ies", 1951 params->assocresp_ies); 1952 1953 #if defined(CONFIG_HS20) && (defined(IEEE80211_PARAM_OSEN) || defined(CONFIG_ATHEROS_OSEN)) 1954 if (params->osen) { 1955 struct wpa_bss_params bss_params; 1956 1957 os_memset(&bss_params, 0, sizeof(struct wpa_bss_params)); 1958 bss_params.enabled = 1; 1959 bss_params.wpa = 2; 1960 bss_params.wpa_pairwise = WPA_CIPHER_CCMP; 1961 bss_params.wpa_group = WPA_CIPHER_CCMP; 1962 bss_params.ieee802_1x = 1; 1963 1964 if (atheros_set_privacy(priv, 1) || 1965 set80211param(priv, IEEE80211_PARAM_OSEN, 1)) 1966 return -1; 1967 1968 return atheros_set_ieee8021x(priv, &bss_params); 1969 } 1970 #endif /* CONFIG_HS20 && IEEE80211_PARAM_OSEN */ 1971 1972 return 0; 1973 } 1974 1975 1976 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) 1977 1978 static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len, 1979 int noack, unsigned int freq, 1980 const u16 *csa_offs, size_t csa_offs_len) 1981 { 1982 struct atheros_driver_data *drv = priv; 1983 u8 buf[1510]; 1984 const struct ieee80211_mgmt *mgmt; 1985 struct ieee80211req_mgmtbuf *mgmt_frm; 1986 1987 mgmt = (const struct ieee80211_mgmt *) frm; 1988 wpa_printf(MSG_DEBUG, "%s frmlen = %lu " MACSTR, __func__, 1989 (unsigned long) data_len, MAC2STR(mgmt->da)); 1990 mgmt_frm = (struct ieee80211req_mgmtbuf *) buf; 1991 os_memcpy(mgmt_frm->macaddr, (u8 *)mgmt->da, IEEE80211_ADDR_LEN); 1992 mgmt_frm->buflen = data_len; 1993 if (&mgmt_frm->buf[0] + data_len > buf + sizeof(buf)) { 1994 wpa_printf(MSG_INFO, "atheros: Too long frame for " 1995 "atheros_send_mgmt (%u)", (unsigned int) data_len); 1996 return -1; 1997 } 1998 os_memcpy(&mgmt_frm->buf[0], frm, data_len); 1999 return set80211priv(drv, IEEE80211_IOCTL_SEND_MGMT, mgmt_frm, 2000 sizeof(struct ieee80211req_mgmtbuf) + data_len); 2001 } 2002 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W || CONFIG_FILS */ 2003 2004 2005 #ifdef CONFIG_IEEE80211R 2006 2007 static int atheros_add_tspec(void *priv, const u8 *addr, u8 *tspec_ie, 2008 size_t tspec_ielen) 2009 { 2010 struct atheros_driver_data *drv = priv; 2011 int retv; 2012 struct ieee80211req_res req; 2013 struct ieee80211req_res_addts *addts = &req.u.addts; 2014 2015 wpa_printf(MSG_DEBUG, "%s", __func__); 2016 req.type = IEEE80211_RESREQ_ADDTS; 2017 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 2018 os_memcpy(addts->tspecie, tspec_ie, tspec_ielen); 2019 retv = set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 2020 sizeof(struct ieee80211req_res)); 2021 if (retv < 0) { 2022 wpa_printf(MSG_DEBUG, "%s IEEE80211_IOCTL_RES_REQ FAILED " 2023 "retv = %d", __func__, retv); 2024 return -1; 2025 } 2026 os_memcpy(tspec_ie, addts->tspecie, tspec_ielen); 2027 return addts->status; 2028 } 2029 2030 2031 static int atheros_add_sta_node(void *priv, const u8 *addr, u16 auth_alg) 2032 { 2033 struct atheros_driver_data *drv = priv; 2034 struct ieee80211req_res req; 2035 struct ieee80211req_res_addnode *addnode = &req.u.addnode; 2036 2037 wpa_printf(MSG_DEBUG, "%s", __func__); 2038 req.type = IEEE80211_RESREQ_ADDNODE; 2039 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 2040 addnode->auth_alg = auth_alg; 2041 return set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 2042 sizeof(struct ieee80211req_res)); 2043 } 2044 2045 #endif /* CONFIG_IEEE80211R */ 2046 2047 2048 /* Use only to set a big param, get will not work. */ 2049 static int 2050 set80211big(struct atheros_driver_data *drv, int op, const void *data, int len) 2051 { 2052 struct iwreq iwr; 2053 2054 os_memset(&iwr, 0, sizeof(iwr)); 2055 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 2056 2057 iwr.u.data.pointer = (void *) data; 2058 iwr.u.data.length = len; 2059 iwr.u.data.flags = op; 2060 wpa_printf(MSG_DEBUG, "%s: op=0x%x=%d (%s) len=0x%x", 2061 __func__, op, op, athr_get_param_name(op), len); 2062 2063 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr) < 0) { 2064 wpa_printf(MSG_DEBUG, "%s: op=0x%x (%s) subop=0x%x=%d " 2065 "value=0x%x,0x%x failed: %d (%s)", 2066 __func__, op, athr_get_ioctl_name(op), iwr.u.mode, 2067 iwr.u.mode, iwr.u.data.length, 2068 iwr.u.data.flags, errno, strerror(errno)); 2069 return -1; 2070 } 2071 return 0; 2072 } 2073 2074 2075 static int atheros_send_action(void *priv, unsigned int freq, 2076 unsigned int wait, 2077 const u8 *dst, const u8 *src, 2078 const u8 *bssid, 2079 const u8 *data, size_t data_len, int no_cck) 2080 { 2081 struct atheros_driver_data *drv = priv; 2082 struct ieee80211_p2p_send_action *act; 2083 int res; 2084 2085 act = os_zalloc(sizeof(*act) + data_len); 2086 if (act == NULL) 2087 return -1; 2088 act->freq = freq; 2089 os_memcpy(act->dst_addr, dst, ETH_ALEN); 2090 os_memcpy(act->src_addr, src, ETH_ALEN); 2091 os_memcpy(act->bssid, bssid, ETH_ALEN); 2092 os_memcpy(act + 1, data, data_len); 2093 wpa_printf(MSG_DEBUG, "%s: freq=%d, wait=%u, dst=" MACSTR ", src=" 2094 MACSTR ", bssid=" MACSTR, 2095 __func__, act->freq, wait, MAC2STR(act->dst_addr), 2096 MAC2STR(act->src_addr), MAC2STR(act->bssid)); 2097 wpa_hexdump(MSG_MSGDUMP, "athr: act", (u8 *) act, sizeof(*act)); 2098 wpa_hexdump(MSG_MSGDUMP, "athr: data", data, data_len); 2099 2100 res = set80211big(drv, IEEE80211_IOC_P2P_SEND_ACTION, 2101 act, sizeof(*act) + data_len); 2102 os_free(act); 2103 return res; 2104 } 2105 2106 2107 #if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM) 2108 static int athr_wnm_tfs(struct atheros_driver_data *drv, const u8* peer, 2109 u8 *ie, u16 *len, enum wnm_oper oper) 2110 { 2111 #define IEEE80211_APPIE_MAX 1024 /* max appie buffer size */ 2112 u8 buf[IEEE80211_APPIE_MAX]; 2113 struct ieee80211req_getset_appiebuf *tfs_ie; 2114 u16 val; 2115 2116 wpa_printf(MSG_DEBUG, "atheros: ifname=%s, WNM TFS IE oper=%d " MACSTR, 2117 drv->iface, oper, MAC2STR(peer)); 2118 2119 switch (oper) { 2120 case WNM_SLEEP_TFS_REQ_IE_SET: 2121 if (*len > IEEE80211_APPIE_MAX - 2122 sizeof(struct ieee80211req_getset_appiebuf)) { 2123 wpa_printf(MSG_DEBUG, "TFS Req IE(s) too large"); 2124 return -1; 2125 } 2126 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2127 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2128 tfs_ie->app_buflen = ETH_ALEN + 2 + 2 + *len; 2129 2130 /* Command header for driver */ 2131 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2132 val = oper; 2133 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2134 val = *len; 2135 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2136 2137 /* copy the ie */ 2138 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2 + 2, ie, *len); 2139 2140 if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie, 2141 IEEE80211_APPIE_MAX)) { 2142 wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: " 2143 "%s", __func__, strerror(errno)); 2144 return -1; 2145 } 2146 break; 2147 case WNM_SLEEP_TFS_RESP_IE_ADD: 2148 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2149 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2150 tfs_ie->app_buflen = IEEE80211_APPIE_MAX - 2151 sizeof(struct ieee80211req_getset_appiebuf); 2152 /* Command header for driver */ 2153 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2154 val = oper; 2155 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2156 val = 0; 2157 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2158 2159 if (set80211priv(drv, IEEE80211_IOCTL_GET_APPIEBUF, tfs_ie, 2160 IEEE80211_APPIE_MAX)) { 2161 wpa_printf(MSG_DEBUG, "%s: Failed to get WNM TFS IE: " 2162 "%s", __func__, strerror(errno)); 2163 return -1; 2164 } 2165 2166 *len = tfs_ie->app_buflen; 2167 os_memcpy(ie, &(tfs_ie->app_buf[0]), *len); 2168 wpa_printf(MSG_DEBUG, "atheros: %c len=%d", tfs_ie->app_buf[0], 2169 *len); 2170 break; 2171 case WNM_SLEEP_TFS_RESP_IE_NONE: 2172 *len = 0; 2173 break; 2174 case WNM_SLEEP_TFS_IE_DEL: 2175 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2176 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2177 tfs_ie->app_buflen = IEEE80211_APPIE_MAX - 2178 sizeof(struct ieee80211req_getset_appiebuf); 2179 /* Command header for driver */ 2180 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2181 val = oper; 2182 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2183 val = 0; 2184 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2185 2186 if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie, 2187 IEEE80211_APPIE_MAX)) { 2188 wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: " 2189 "%s", __func__, strerror(errno)); 2190 return -1; 2191 } 2192 break; 2193 default: 2194 wpa_printf(MSG_DEBUG, "Unsupported TFS oper %d", oper); 2195 break; 2196 } 2197 2198 return 0; 2199 } 2200 2201 2202 static int atheros_wnm_sleep(struct atheros_driver_data *drv, 2203 const u8 *peer, enum wnm_oper oper) 2204 { 2205 u8 *data, *pos; 2206 size_t dlen; 2207 int ret; 2208 u16 val; 2209 2210 wpa_printf(MSG_DEBUG, "atheros: WNM-Sleep Oper %d, " MACSTR, 2211 oper, MAC2STR(peer)); 2212 2213 dlen = ETH_ALEN + 2 + 2; 2214 data = os_malloc(dlen); 2215 if (data == NULL) 2216 return -1; 2217 2218 /* Command header for driver */ 2219 pos = data; 2220 os_memcpy(pos, peer, ETH_ALEN); 2221 pos += ETH_ALEN; 2222 2223 val = oper; 2224 os_memcpy(pos, &val, 2); 2225 pos += 2; 2226 2227 val = 0; 2228 os_memcpy(pos, &val, 2); 2229 2230 ret = atheros_set_wps_ie(drv, data, dlen, IEEE80211_APPIE_FRAME_WNM); 2231 2232 os_free(data); 2233 2234 return ret; 2235 } 2236 2237 2238 static int atheros_wnm_oper(void *priv, enum wnm_oper oper, const u8 *peer, 2239 u8 *buf, u16 *buf_len) 2240 { 2241 struct atheros_driver_data *drv = priv; 2242 2243 switch (oper) { 2244 case WNM_SLEEP_ENTER_CONFIRM: 2245 case WNM_SLEEP_ENTER_FAIL: 2246 case WNM_SLEEP_EXIT_CONFIRM: 2247 case WNM_SLEEP_EXIT_FAIL: 2248 return atheros_wnm_sleep(drv, peer, oper); 2249 case WNM_SLEEP_TFS_REQ_IE_SET: 2250 case WNM_SLEEP_TFS_RESP_IE_ADD: 2251 case WNM_SLEEP_TFS_RESP_IE_NONE: 2252 case WNM_SLEEP_TFS_IE_DEL: 2253 return athr_wnm_tfs(drv, peer, buf, buf_len, oper); 2254 default: 2255 wpa_printf(MSG_DEBUG, "atheros: Unsupported WNM operation %d", 2256 oper); 2257 return -1; 2258 } 2259 } 2260 #endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */ 2261 2262 2263 const struct wpa_driver_ops wpa_driver_atheros_ops = { 2264 .name = "atheros", 2265 .hapd_init = atheros_init, 2266 .hapd_deinit = atheros_deinit, 2267 .set_ieee8021x = atheros_set_ieee8021x, 2268 .set_privacy = atheros_set_privacy, 2269 .set_key = atheros_set_key, 2270 .get_seqnum = atheros_get_seqnum, 2271 .flush = atheros_flush, 2272 .set_generic_elem = atheros_set_opt_ie, 2273 .sta_set_flags = atheros_sta_set_flags, 2274 .read_sta_data = atheros_read_sta_driver_data, 2275 .hapd_send_eapol = atheros_send_eapol, 2276 .sta_disassoc = atheros_sta_disassoc, 2277 .sta_deauth = atheros_sta_deauth, 2278 .hapd_set_ssid = atheros_set_ssid, 2279 .hapd_get_ssid = atheros_get_ssid, 2280 .set_countermeasures = atheros_set_countermeasures, 2281 .sta_clear_stats = atheros_sta_clear_stats, 2282 .commit = atheros_commit, 2283 .set_ap_wps_ie = atheros_set_ap_wps_ie, 2284 .set_authmode = atheros_set_authmode, 2285 .set_ap = atheros_set_ap, 2286 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) 2287 .sta_assoc = atheros_sta_assoc, 2288 .sta_auth = atheros_sta_auth, 2289 .send_mlme = atheros_send_mgmt, 2290 #endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W || CONFIG_FILS */ 2291 #ifdef CONFIG_IEEE80211R 2292 .add_tspec = atheros_add_tspec, 2293 .add_sta_node = atheros_add_sta_node, 2294 #endif /* CONFIG_IEEE80211R */ 2295 .send_action = atheros_send_action, 2296 #if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM) 2297 .wnm_oper = atheros_wnm_oper, 2298 #endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */ 2299 .set_qos_map = atheros_set_qos_map, 2300 }; 2301