1/* 2 * hostapd / Driver interaction with Atheros driver 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> 4 * Copyright (c) 2004, Video54 Technologies 5 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 6 * Copyright (c) 2009, Atheros Communications 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * Alternatively, this software may be distributed under the terms of BSD 13 * license. 14 * 15 * See README and COPYING for more details. 16 */ 17 18#include "includes.h" 19#include <net/if.h> 20#include <sys/ioctl.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 "os/linux/include/ieee80211_external.h" 38 39 40#ifdef CONFIG_WPS 41#include <netpacket/packet.h> 42 43#ifndef ETH_P_80211_RAW 44#define ETH_P_80211_RAW 0x0019 45#endif 46#endif /* CONFIG_WPS */ 47 48#include "wireless_copy.h" 49 50#include "driver.h" 51#include "eloop.h" 52#include "priv_netlink.h" 53#include "l2_packet/l2_packet.h" 54#include "common/ieee802_11_defs.h" 55#include "netlink.h" 56#include "linux_ioctl.h" 57 58 59struct madwifi_driver_data { 60 struct hostapd_data *hapd; /* back pointer */ 61 62 char iface[IFNAMSIZ + 1]; 63 int ifindex; 64 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 65 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 66 int ioctl_sock; /* socket for ioctl() use */ 67 struct netlink_data *netlink; 68 int we_version; 69 u8 acct_mac[ETH_ALEN]; 70 struct hostap_sta_driver_data acct_data; 71 72 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 73}; 74 75static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 76 int reason_code); 77static int madwifi_set_privacy(void *priv, int enabled); 78 79static const char * athr_get_ioctl_name(int op) 80{ 81 switch (op) { 82 case IEEE80211_IOCTL_SETPARAM: 83 return "SETPARAM"; 84 case IEEE80211_IOCTL_GETPARAM: 85 return "GETPARAM"; 86 case IEEE80211_IOCTL_SETKEY: 87 return "SETKEY"; 88 case IEEE80211_IOCTL_SETWMMPARAMS: 89 return "SETWMMPARAMS"; 90 case IEEE80211_IOCTL_DELKEY: 91 return "DELKEY"; 92 case IEEE80211_IOCTL_GETWMMPARAMS: 93 return "GETWMMPARAMS"; 94 case IEEE80211_IOCTL_SETMLME: 95 return "SETMLME"; 96 case IEEE80211_IOCTL_GETCHANINFO: 97 return "GETCHANINFO"; 98 case IEEE80211_IOCTL_SETOPTIE: 99 return "SETOPTIE"; 100 case IEEE80211_IOCTL_GETOPTIE: 101 return "GETOPTIE"; 102 case IEEE80211_IOCTL_ADDMAC: 103 return "ADDMAC"; 104 case IEEE80211_IOCTL_DELMAC: 105 return "DELMAC"; 106 case IEEE80211_IOCTL_GETCHANLIST: 107 return "GETCHANLIST"; 108 case IEEE80211_IOCTL_SETCHANLIST: 109 return "SETCHANLIST"; 110 case IEEE80211_IOCTL_KICKMAC: 111 return "KICKMAC"; 112 case IEEE80211_IOCTL_CHANSWITCH: 113 return "CHANSWITCH"; 114 case IEEE80211_IOCTL_GETMODE: 115 return "GETMODE"; 116 case IEEE80211_IOCTL_SETMODE: 117 return "SETMODE"; 118 case IEEE80211_IOCTL_GET_APPIEBUF: 119 return "GET_APPIEBUF"; 120 case IEEE80211_IOCTL_SET_APPIEBUF: 121 return "SET_APPIEBUF"; 122 case IEEE80211_IOCTL_SET_ACPARAMS: 123 return "SET_ACPARAMS"; 124 case IEEE80211_IOCTL_FILTERFRAME: 125 return "FILTERFRAME"; 126 case IEEE80211_IOCTL_SET_RTPARAMS: 127 return "SET_RTPARAMS"; 128 case IEEE80211_IOCTL_SENDADDBA: 129 return "SENDADDBA"; 130 case IEEE80211_IOCTL_GETADDBASTATUS: 131 return "GETADDBASTATUS"; 132 case IEEE80211_IOCTL_SENDDELBA: 133 return "SENDDELBA"; 134 case IEEE80211_IOCTL_SET_MEDENYENTRY: 135 return "SET_MEDENYENTRY"; 136 case IEEE80211_IOCTL_SET_ADDBARESP: 137 return "SET_ADDBARESP"; 138 case IEEE80211_IOCTL_GET_MACADDR: 139 return "GET_MACADDR"; 140 case IEEE80211_IOCTL_SET_HBRPARAMS: 141 return "SET_HBRPARAMS"; 142 case IEEE80211_IOCTL_SET_RXTIMEOUT: 143 return "SET_RXTIMEOUT"; 144 case IEEE80211_IOCTL_STA_STATS: 145 return "STA_STATS"; 146 case IEEE80211_IOCTL_GETWPAIE: 147 return "GETWPAIE"; 148 default: 149 return "??"; 150 } 151} 152 153 154static const char * athr_get_param_name(int op) 155{ 156 switch (op) { 157 case IEEE80211_IOC_MCASTCIPHER: 158 return "MCASTCIPHER"; 159 case IEEE80211_PARAM_MCASTKEYLEN: 160 return "MCASTKEYLEN"; 161 case IEEE80211_PARAM_UCASTCIPHERS: 162 return "UCASTCIPHERS"; 163 case IEEE80211_PARAM_KEYMGTALGS: 164 return "KEYMGTALGS"; 165 case IEEE80211_PARAM_RSNCAPS: 166 return "RSNCAPS"; 167 case IEEE80211_PARAM_WPA: 168 return "WPA"; 169 case IEEE80211_PARAM_AUTHMODE: 170 return "AUTHMODE"; 171 case IEEE80211_PARAM_PRIVACY: 172 return "PRIVACY"; 173 case IEEE80211_PARAM_COUNTERMEASURES: 174 return "COUNTERMEASURES"; 175 default: 176 return "??"; 177 } 178} 179 180 181static int 182set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) 183{ 184 struct iwreq iwr; 185 int do_inline = len < IFNAMSIZ; 186 187 /* Certain ioctls must use the non-inlined method */ 188 if (op == IEEE80211_IOCTL_SET_APPIEBUF || 189 op == IEEE80211_IOCTL_FILTERFRAME) 190 do_inline = 0; 191 192 memset(&iwr, 0, sizeof(iwr)); 193 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 194 if (do_inline) { 195 /* 196 * Argument data fits inline; put it there. 197 */ 198 memcpy(iwr.u.name, data, len); 199 } else { 200 /* 201 * Argument data too big for inline transfer; setup a 202 * parameter block instead; the kernel will transfer 203 * the data for the driver. 204 */ 205 iwr.u.data.pointer = data; 206 iwr.u.data.length = len; 207 } 208 209 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 210 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " 211 "(%s) len=%d failed: %d (%s)", 212 __func__, drv->iface, op, 213 athr_get_ioctl_name(op), 214 len, errno, strerror(errno)); 215 return -1; 216 } 217 return 0; 218} 219 220static int 221set80211param(struct madwifi_driver_data *drv, int op, int arg) 222{ 223 struct iwreq iwr; 224 225 memset(&iwr, 0, sizeof(iwr)); 226 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 227 iwr.u.mode = op; 228 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); 229 230 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 231 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 232 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d " 233 "(%s) arg %d)", __func__, drv->iface, op, 234 athr_get_param_name(op), arg); 235 return -1; 236 } 237 return 0; 238} 239 240#ifndef CONFIG_NO_STDOUT_DEBUG 241static const char * 242ether_sprintf(const u8 *addr) 243{ 244 static char buf[sizeof(MACSTR)]; 245 246 if (addr != NULL) 247 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 248 else 249 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 250 return buf; 251} 252#endif /* CONFIG_NO_STDOUT_DEBUG */ 253 254/* 255 * Configure WPA parameters. 256 */ 257static int 258madwifi_configure_wpa(struct madwifi_driver_data *drv, 259 struct wpa_bss_params *params) 260{ 261 int v; 262 263 switch (params->wpa_group) { 264 case WPA_CIPHER_CCMP: 265 v = IEEE80211_CIPHER_AES_CCM; 266 break; 267 case WPA_CIPHER_TKIP: 268 v = IEEE80211_CIPHER_TKIP; 269 break; 270 case WPA_CIPHER_WEP104: 271 v = IEEE80211_CIPHER_WEP; 272 break; 273 case WPA_CIPHER_WEP40: 274 v = IEEE80211_CIPHER_WEP; 275 break; 276 case WPA_CIPHER_NONE: 277 v = IEEE80211_CIPHER_NONE; 278 break; 279 default: 280 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 281 params->wpa_group); 282 return -1; 283 } 284 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 285 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 286 printf("Unable to set group key cipher to %u\n", v); 287 return -1; 288 } 289 if (v == IEEE80211_CIPHER_WEP) { 290 /* key length is done only for specific ciphers */ 291 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 292 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 293 printf("Unable to set group key length to %u\n", v); 294 return -1; 295 } 296 } 297 298 v = 0; 299 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 300 v |= 1<<IEEE80211_CIPHER_AES_CCM; 301 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 302 v |= 1<<IEEE80211_CIPHER_TKIP; 303 if (params->wpa_pairwise & WPA_CIPHER_NONE) 304 v |= 1<<IEEE80211_CIPHER_NONE; 305 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 306 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 307 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 308 return -1; 309 } 310 311 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 312 __func__, params->wpa_key_mgmt); 313 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 314 params->wpa_key_mgmt)) { 315 printf("Unable to set key management algorithms to 0x%x\n", 316 params->wpa_key_mgmt); 317 return -1; 318 } 319 320 v = 0; 321 if (params->rsn_preauth) 322 v |= BIT(0); 323 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", 324 __func__, params->rsn_preauth); 325 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 326 printf("Unable to set RSN capabilities to 0x%x\n", v); 327 return -1; 328 } 329 330 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 331 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 332 printf("Unable to set WPA to %u\n", params->wpa); 333 return -1; 334 } 335 return 0; 336} 337 338static int 339madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) 340{ 341 struct madwifi_driver_data *drv = priv; 342 343 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 344 345 if (!params->enabled) { 346 /* XXX restore state */ 347 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 348 IEEE80211_AUTH_AUTO) < 0) 349 return -1; 350 /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */ 351 return madwifi_set_privacy(drv, 0); 352 } 353 if (!params->wpa && !params->ieee802_1x) { 354 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 355 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); 356 return -1; 357 } 358 if (params->wpa && madwifi_configure_wpa(drv, params) != 0) { 359 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 360 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); 361 return -1; 362 } 363 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 364 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 365 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 366 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); 367 return -1; 368 } 369 370 return 0; 371} 372 373static int 374madwifi_set_privacy(void *priv, int enabled) 375{ 376 struct madwifi_driver_data *drv = priv; 377 378 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 379 380 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 381} 382 383static int 384madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized) 385{ 386 struct madwifi_driver_data *drv = priv; 387 struct ieee80211req_mlme mlme; 388 int ret; 389 390 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 391 __func__, ether_sprintf(addr), authorized); 392 393 if (authorized) 394 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 395 else 396 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 397 mlme.im_reason = 0; 398 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 399 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 400 if (ret < 0) { 401 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 402 __func__, authorized ? "" : "un", MAC2STR(addr)); 403 } 404 405 return ret; 406} 407 408static int 409madwifi_sta_set_flags(void *priv, const u8 *addr, 410 int total_flags, int flags_or, int flags_and) 411{ 412 /* For now, only support setting Authorized flag */ 413 if (flags_or & WPA_STA_AUTHORIZED) 414 return madwifi_set_sta_authorized(priv, addr, 1); 415 if (!(flags_and & WPA_STA_AUTHORIZED)) 416 return madwifi_set_sta_authorized(priv, addr, 0); 417 return 0; 418} 419 420static int 421madwifi_del_key(void *priv, const u8 *addr, int key_idx) 422{ 423 struct madwifi_driver_data *drv = priv; 424 struct ieee80211req_del_key wk; 425 int ret; 426 427 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 428 __func__, ether_sprintf(addr), key_idx); 429 430 memset(&wk, 0, sizeof(wk)); 431 if (addr != NULL) { 432 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 433 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 434 } else { 435 wk.idk_keyix = key_idx; 436 } 437 438 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 439 if (ret < 0) { 440 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 441 " key_idx %d)", __func__, ether_sprintf(addr), 442 key_idx); 443 } 444 445 return ret; 446} 447 448static int 449madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, 450 const u8 *addr, int key_idx, int set_tx, const u8 *seq, 451 size_t seq_len, const u8 *key, size_t key_len) 452{ 453 struct madwifi_driver_data *drv = priv; 454 struct ieee80211req_key wk; 455 u_int8_t cipher; 456 int ret; 457 458 if (alg == WPA_ALG_NONE) 459 return madwifi_del_key(drv, addr, key_idx); 460 461 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 462 __func__, alg, ether_sprintf(addr), key_idx); 463 464 switch (alg) { 465 case WPA_ALG_WEP: 466 cipher = IEEE80211_CIPHER_WEP; 467 break; 468 case WPA_ALG_TKIP: 469 cipher = IEEE80211_CIPHER_TKIP; 470 break; 471 case WPA_ALG_CCMP: 472 cipher = IEEE80211_CIPHER_AES_CCM; 473 break; 474 default: 475 printf("%s: unknown/unsupported algorithm %d\n", 476 __func__, alg); 477 return -1; 478 } 479 480 if (key_len > sizeof(wk.ik_keydata)) { 481 printf("%s: key length %lu too big\n", __func__, 482 (unsigned long) key_len); 483 return -3; 484 } 485 486 memset(&wk, 0, sizeof(wk)); 487 wk.ik_type = cipher; 488 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 489 if (addr == NULL) { 490 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 491 wk.ik_keyix = key_idx; 492 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 493 } else { 494 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 495 wk.ik_keyix = IEEE80211_KEYIX_NONE; 496 } 497 wk.ik_keylen = key_len; 498 memcpy(wk.ik_keydata, key, key_len); 499 500 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 501 if (ret < 0) { 502 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 503 " key_idx %d alg %d key_len %lu set_tx %d)", 504 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 505 alg, (unsigned long) key_len, set_tx); 506 } 507 508 return ret; 509} 510 511 512static int 513madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 514 u8 *seq) 515{ 516 struct madwifi_driver_data *drv = priv; 517 struct ieee80211req_key wk; 518 519 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 520 __func__, ether_sprintf(addr), idx); 521 522 memset(&wk, 0, sizeof(wk)); 523 if (addr == NULL) 524 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 525 else 526 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 527 wk.ik_keyix = idx; 528 529 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 530 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 531 "(addr " MACSTR " key_idx %d)", 532 __func__, MAC2STR(wk.ik_macaddr), idx); 533 return -1; 534 } 535 536#ifdef WORDS_BIGENDIAN 537 { 538 /* 539 * wk.ik_keytsc is in host byte order (big endian), need to 540 * swap it to match with the byte order used in WPA. 541 */ 542 int i; 543#ifndef WPA_KEY_RSC_LEN 544#define WPA_KEY_RSC_LEN 8 545#endif 546 u8 tmp[WPA_KEY_RSC_LEN]; 547 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 548 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 549 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 550 } 551 } 552#else /* WORDS_BIGENDIAN */ 553 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 554#endif /* WORDS_BIGENDIAN */ 555 return 0; 556} 557 558 559static int 560madwifi_flush(void *priv) 561{ 562 u8 allsta[IEEE80211_ADDR_LEN]; 563 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 564 return madwifi_sta_deauth(priv, NULL, allsta, 565 IEEE80211_REASON_AUTH_LEAVE); 566} 567 568 569static int 570madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 571 const u8 *addr) 572{ 573 struct madwifi_driver_data *drv = priv; 574 struct ieee80211req_sta_stats stats; 575 576 memset(data, 0, sizeof(*data)); 577 578 /* 579 * Fetch statistics for station from the system. 580 */ 581 memset(&stats, 0, sizeof(stats)); 582 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 583 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS, 584 &stats, sizeof(stats))) { 585 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 586 MACSTR ")", __func__, MAC2STR(addr)); 587 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 588 memcpy(data, &drv->acct_data, sizeof(*data)); 589 return 0; 590 } 591 592 printf("Failed to get station stats information element.\n"); 593 return -1; 594 } 595 596 data->rx_packets = stats.is_stats.ns_rx_data; 597 data->rx_bytes = stats.is_stats.ns_rx_bytes; 598 data->tx_packets = stats.is_stats.ns_tx_data; 599 data->tx_bytes = stats.is_stats.ns_tx_bytes; 600 return 0; 601} 602 603 604static int 605madwifi_sta_clear_stats(void *priv, const u8 *addr) 606{ 607 struct madwifi_driver_data *drv = priv; 608 struct ieee80211req_mlme mlme; 609 int ret; 610 611 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 612 613 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 614 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 615 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 616 sizeof(mlme)); 617 if (ret < 0) { 618 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 619 MACSTR ")", __func__, MAC2STR(addr)); 620 } 621 622 return ret; 623} 624 625 626static int 627madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 628{ 629 /* 630 * Do nothing; we setup parameters at startup that define the 631 * contents of the beacon information element. 632 */ 633 return 0; 634} 635 636static int 637madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 638 int reason_code) 639{ 640 struct madwifi_driver_data *drv = priv; 641 struct ieee80211req_mlme mlme; 642 int ret; 643 644 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 645 __func__, ether_sprintf(addr), reason_code); 646 647 mlme.im_op = IEEE80211_MLME_DEAUTH; 648 mlme.im_reason = reason_code; 649 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 650 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 651 if (ret < 0) { 652 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 653 " reason %d)", 654 __func__, MAC2STR(addr), reason_code); 655 } 656 657 return ret; 658} 659 660static int 661madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 662 int reason_code) 663{ 664 struct madwifi_driver_data *drv = priv; 665 struct ieee80211req_mlme mlme; 666 int ret; 667 668 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 669 __func__, ether_sprintf(addr), reason_code); 670 671 mlme.im_op = IEEE80211_MLME_DISASSOC; 672 mlme.im_reason = reason_code; 673 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 674 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 675 if (ret < 0) { 676 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 677 MACSTR " reason %d)", 678 __func__, MAC2STR(addr), reason_code); 679 } 680 681 return ret; 682} 683 684#ifdef CONFIG_WPS 685static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 686 size_t len) 687{ 688 struct madwifi_driver_data *drv = ctx; 689 const struct ieee80211_mgmt *mgmt; 690 u16 fc; 691 union wpa_event_data event; 692 693 /* Send Probe Request information to WPS processing */ 694 695 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 696 return; 697 mgmt = (const struct ieee80211_mgmt *) buf; 698 699 fc = le_to_host16(mgmt->frame_control); 700 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 701 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) 702 return; 703 704 os_memset(&event, 0, sizeof(event)); 705 event.rx_probe_req.sa = mgmt->sa; 706 event.rx_probe_req.ie = mgmt->u.probe_req.variable; 707 event.rx_probe_req.ie_len = 708 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 709 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 710} 711#endif /* CONFIG_WPS */ 712 713static int madwifi_receive_probe_req(struct madwifi_driver_data *drv) 714{ 715 int ret = 0; 716#ifdef CONFIG_WPS 717 struct ieee80211req_set_filter filt; 718 719 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 720 filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ; 721 722 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 723 sizeof(struct ieee80211req_set_filter)); 724 if (ret) 725 return ret; 726 727 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 728 madwifi_raw_receive, drv, 1); 729 if (drv->sock_raw == NULL) 730 return -1; 731#endif /* CONFIG_WPS */ 732 return ret; 733} 734 735#ifdef CONFIG_WPS 736static int 737madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 738{ 739 struct madwifi_driver_data *drv = priv; 740 u8 buf[256]; 741 struct ieee80211req_getset_appiebuf *beac_ie; 742 743 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 744 (unsigned long) len); 745 746 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 747 beac_ie->app_frmtype = frametype; 748 beac_ie->app_buflen = len; 749 memcpy(&(beac_ie->app_buf[0]), ie, len); 750 751 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 752 sizeof(struct ieee80211req_getset_appiebuf) + len); 753} 754 755static int 756madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 757 const struct wpabuf *proberesp) 758{ 759 if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 760 beacon ? wpabuf_len(beacon) : 0, 761 IEEE80211_APPIE_FRAME_BEACON)) 762 return -1; 763 return madwifi_set_wps_ie(priv, 764 proberesp ? wpabuf_head(proberesp) : NULL, 765 proberesp ? wpabuf_len(proberesp): 0, 766 IEEE80211_APPIE_FRAME_PROBE_RESP); 767} 768#else /* CONFIG_WPS */ 769#define madwifi_set_ap_wps_ie NULL 770#endif /* CONFIG_WPS */ 771 772static void 773madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 774{ 775 struct hostapd_data *hapd = drv->hapd; 776 struct ieee80211req_wpaie ie; 777 int ielen = 0; 778 u8 *iebuf = NULL; 779 780 /* 781 * Fetch negotiated WPA/RSN parameters from the system. 782 */ 783 memset(&ie, 0, sizeof(ie)); 784 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 785 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 786 /* 787 * See ATH_WPS_IE comment in the beginning of the file for a 788 * possible cause for the failure.. 789 */ 790 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", 791 __func__, strerror(errno)); 792 goto no_ie; 793 } 794 wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE", 795 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 796 wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE", 797 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 798 iebuf = ie.wpa_ie; 799 /* madwifi seems to return some random data if WPA/RSN IE is not set. 800 * Assume the IE was not included if the IE type is unknown. */ 801 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 802 iebuf[1] = 0; 803 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 804 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 805 * set. This is needed for WPA2. */ 806 iebuf = ie.rsn_ie; 807 if (iebuf[0] != WLAN_EID_RSN) 808 iebuf[1] = 0; 809 } 810 811 ielen = iebuf[1]; 812 if (ielen == 0) 813 iebuf = NULL; 814 else 815 ielen += 2; 816 817no_ie: 818 drv_event_assoc(hapd, addr, iebuf, ielen); 819 820 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 821 /* Cached accounting data is not valid anymore. */ 822 memset(drv->acct_mac, 0, ETH_ALEN); 823 memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 824 } 825} 826 827static void 828madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, 829 char *custom, char *end) 830{ 831 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 832 833 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 834 char *pos; 835 u8 addr[ETH_ALEN]; 836 pos = strstr(custom, "addr="); 837 if (pos == NULL) { 838 wpa_printf(MSG_DEBUG, 839 "MLME-MICHAELMICFAILURE.indication " 840 "without sender address ignored"); 841 return; 842 } 843 pos += 5; 844 if (hwaddr_aton(pos, addr) == 0) { 845 union wpa_event_data data; 846 os_memset(&data, 0, sizeof(data)); 847 data.michael_mic_failure.unicast = 1; 848 data.michael_mic_failure.src = addr; 849 wpa_supplicant_event(drv->hapd, 850 EVENT_MICHAEL_MIC_FAILURE, &data); 851 } else { 852 wpa_printf(MSG_DEBUG, 853 "MLME-MICHAELMICFAILURE.indication " 854 "with invalid MAC address"); 855 } 856 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 857 char *key, *value; 858 u32 val; 859 key = custom; 860 while ((key = strchr(key, '\n')) != NULL) { 861 key++; 862 value = strchr(key, '='); 863 if (value == NULL) 864 continue; 865 *value++ = '\0'; 866 val = strtoul(value, NULL, 10); 867 if (strcmp(key, "mac") == 0) 868 hwaddr_aton(value, drv->acct_mac); 869 else if (strcmp(key, "rx_packets") == 0) 870 drv->acct_data.rx_packets = val; 871 else if (strcmp(key, "tx_packets") == 0) 872 drv->acct_data.tx_packets = val; 873 else if (strcmp(key, "rx_bytes") == 0) 874 drv->acct_data.rx_bytes = val; 875 else if (strcmp(key, "tx_bytes") == 0) 876 drv->acct_data.tx_bytes = val; 877 key = value; 878 } 879#ifdef CONFIG_WPS 880 } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) { 881 /* Some atheros kernels send push button as a wireless event */ 882 /* PROBLEM! this event is received for ALL BSSs ... 883 * so all are enabled for WPS... ugh. 884 */ 885 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); 886 } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) { 887 /* 888 * Atheros driver uses a hack to pass Probe Request frames as a 889 * binary data in the custom wireless event. The old way (using 890 * packet sniffing) didn't work when bridging. 891 * Format: "Manage.prob_req <frame len>" | zero padding | frame 892 */ 893#define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */ 894 int len = atoi(custom + 16); 895 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 896 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event " 897 "length %d", len); 898 return; 899 } 900 madwifi_raw_receive(drv, NULL, 901 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 902#endif /* CONFIG_WPS */ 903 } 904} 905 906static void 907madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, 908 char *data, int len) 909{ 910 struct iw_event iwe_buf, *iwe = &iwe_buf; 911 char *pos, *end, *custom, *buf; 912 913 pos = data; 914 end = data + len; 915 916 while (pos + IW_EV_LCP_LEN <= end) { 917 /* Event data may be unaligned, so make a local, aligned copy 918 * before processing. */ 919 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 920 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 921 iwe->cmd, iwe->len); 922 if (iwe->len <= IW_EV_LCP_LEN) 923 return; 924 925 custom = pos + IW_EV_POINT_LEN; 926 if (drv->we_version > 18 && 927 (iwe->cmd == IWEVMICHAELMICFAILURE || 928 iwe->cmd == IWEVASSOCREQIE || 929 iwe->cmd == IWEVCUSTOM)) { 930 /* WE-19 removed the pointer from struct iw_point */ 931 char *dpos = (char *) &iwe_buf.u.data.length; 932 int dlen = dpos - (char *) &iwe_buf; 933 memcpy(dpos, pos + IW_EV_LCP_LEN, 934 sizeof(struct iw_event) - dlen); 935 } else { 936 memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 937 custom += IW_EV_POINT_OFF; 938 } 939 940 switch (iwe->cmd) { 941 case IWEVEXPIRED: 942 drv_event_disassoc(drv->hapd, 943 (u8 *) iwe->u.addr.sa_data); 944 break; 945 case IWEVREGISTERED: 946 madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 947 break; 948 case IWEVASSOCREQIE: 949 /* Driver hack.. Use IWEVASSOCREQIE to bypass 950 * IWEVCUSTOM size limitations. Need to handle this 951 * just like IWEVCUSTOM. 952 */ 953 case IWEVCUSTOM: 954 if (custom + iwe->u.data.length > end) 955 return; 956 buf = malloc(iwe->u.data.length + 1); 957 if (buf == NULL) 958 return; /* XXX */ 959 memcpy(buf, custom, iwe->u.data.length); 960 buf[iwe->u.data.length] = '\0'; 961 madwifi_wireless_event_wireless_custom( 962 drv, buf, buf + iwe->u.data.length); 963 free(buf); 964 break; 965 } 966 967 pos += iwe->len; 968 } 969} 970 971 972static void 973madwifi_wireless_event_rtm_newlink(void *ctx, 974 struct ifinfomsg *ifi, u8 *buf, size_t len) 975{ 976 struct madwifi_driver_data *drv = ctx; 977 int attrlen, rta_len; 978 struct rtattr *attr; 979 980 if (ifi->ifi_index != drv->ifindex) 981 return; 982 983 attrlen = len; 984 attr = (struct rtattr *) buf; 985 986 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 987 while (RTA_OK(attr, attrlen)) { 988 if (attr->rta_type == IFLA_WIRELESS) { 989 madwifi_wireless_event_wireless( 990 drv, ((char *) attr) + rta_len, 991 attr->rta_len - rta_len); 992 } 993 attr = RTA_NEXT(attr, attrlen); 994 } 995} 996 997 998static int 999madwifi_get_we_version(struct madwifi_driver_data *drv) 1000{ 1001 struct iw_range *range; 1002 struct iwreq iwr; 1003 int minlen; 1004 size_t buflen; 1005 1006 drv->we_version = 0; 1007 1008 /* 1009 * Use larger buffer than struct iw_range in order to allow the 1010 * structure to grow in the future. 1011 */ 1012 buflen = sizeof(struct iw_range) + 500; 1013 range = os_zalloc(buflen); 1014 if (range == NULL) 1015 return -1; 1016 1017 memset(&iwr, 0, sizeof(iwr)); 1018 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1019 iwr.u.data.pointer = (caddr_t) range; 1020 iwr.u.data.length = buflen; 1021 1022 minlen = ((char *) &range->enc_capa) - (char *) range + 1023 sizeof(range->enc_capa); 1024 1025 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1026 perror("ioctl[SIOCGIWRANGE]"); 1027 free(range); 1028 return -1; 1029 } else if (iwr.u.data.length >= minlen && 1030 range->we_version_compiled >= 18) { 1031 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1032 "WE(source)=%d enc_capa=0x%x", 1033 range->we_version_compiled, 1034 range->we_version_source, 1035 range->enc_capa); 1036 drv->we_version = range->we_version_compiled; 1037 } 1038 1039 free(range); 1040 return 0; 1041} 1042 1043 1044static int 1045madwifi_wireless_event_init(struct madwifi_driver_data *drv) 1046{ 1047 struct netlink_config *cfg; 1048 1049 madwifi_get_we_version(drv); 1050 1051 cfg = os_zalloc(sizeof(*cfg)); 1052 if (cfg == NULL) 1053 return -1; 1054 cfg->ctx = drv; 1055 cfg->newlink_cb = madwifi_wireless_event_rtm_newlink; 1056 drv->netlink = netlink_init(cfg); 1057 if (drv->netlink == NULL) { 1058 os_free(cfg); 1059 return -1; 1060 } 1061 1062 return 0; 1063} 1064 1065 1066static int 1067madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 1068 int encrypt, const u8 *own_addr) 1069{ 1070 struct madwifi_driver_data *drv = priv; 1071 unsigned char buf[3000]; 1072 unsigned char *bp = buf; 1073 struct l2_ethhdr *eth; 1074 size_t len; 1075 int status; 1076 1077 /* 1078 * Prepend the Ethernet header. If the caller left us 1079 * space at the front we could just insert it but since 1080 * we don't know we copy to a local buffer. Given the frequency 1081 * and size of frames this probably doesn't matter. 1082 */ 1083 len = data_len + sizeof(struct l2_ethhdr); 1084 if (len > sizeof(buf)) { 1085 bp = malloc(len); 1086 if (bp == NULL) { 1087 printf("EAPOL frame discarded, cannot malloc temp " 1088 "buffer of size %lu!\n", (unsigned long) len); 1089 return -1; 1090 } 1091 } 1092 eth = (struct l2_ethhdr *) bp; 1093 memcpy(eth->h_dest, addr, ETH_ALEN); 1094 memcpy(eth->h_source, own_addr, ETH_ALEN); 1095 eth->h_proto = host_to_be16(ETH_P_EAPOL); 1096 memcpy(eth+1, data, data_len); 1097 1098 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); 1099 1100 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); 1101 1102 if (bp != buf) 1103 free(bp); 1104 return status; 1105} 1106 1107static void 1108handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 1109{ 1110 struct madwifi_driver_data *drv = ctx; 1111 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), 1112 len - sizeof(struct l2_ethhdr)); 1113} 1114 1115static void * 1116madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) 1117{ 1118 struct madwifi_driver_data *drv; 1119 struct ifreq ifr; 1120 struct iwreq iwr; 1121 char brname[IFNAMSIZ]; 1122 1123 drv = os_zalloc(sizeof(struct madwifi_driver_data)); 1124 if (drv == NULL) { 1125 printf("Could not allocate memory for madwifi driver data\n"); 1126 return NULL; 1127 } 1128 1129 drv->hapd = hapd; 1130 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 1131 if (drv->ioctl_sock < 0) { 1132 perror("socket[PF_INET,SOCK_DGRAM]"); 1133 goto bad; 1134 } 1135 memcpy(drv->iface, params->ifname, sizeof(drv->iface)); 1136 1137 memset(&ifr, 0, sizeof(ifr)); 1138 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); 1139 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { 1140 perror("ioctl(SIOCGIFINDEX)"); 1141 goto bad; 1142 } 1143 drv->ifindex = ifr.ifr_ifindex; 1144 1145 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, 1146 handle_read, drv, 1); 1147 if (drv->sock_xmit == NULL) 1148 goto bad; 1149 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 1150 goto bad; 1151 if (params->bridge[0]) { 1152 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", 1153 params->bridge[0]); 1154 drv->sock_recv = l2_packet_init(params->bridge[0], NULL, 1155 ETH_P_EAPOL, handle_read, drv, 1156 1); 1157 if (drv->sock_recv == NULL) 1158 goto bad; 1159 } else if (linux_br_get(brname, drv->iface) == 0) { 1160 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " 1161 "EAPOL receive", brname); 1162 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, 1163 handle_read, drv, 1); 1164 if (drv->sock_recv == NULL) 1165 goto bad; 1166 } else 1167 drv->sock_recv = drv->sock_xmit; 1168 1169 memset(&iwr, 0, sizeof(iwr)); 1170 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1171 1172 iwr.u.mode = IW_MODE_MASTER; 1173 1174 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { 1175 perror("ioctl[SIOCSIWMODE]"); 1176 printf("Could not set interface to master mode!\n"); 1177 goto bad; 1178 } 1179 1180 /* mark down during setup */ 1181 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1182 madwifi_set_privacy(drv, 0); /* default to no privacy */ 1183 1184 madwifi_receive_probe_req(drv); 1185 1186 if (madwifi_wireless_event_init(drv)) 1187 goto bad; 1188 1189 return drv; 1190bad: 1191 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1192 l2_packet_deinit(drv->sock_recv); 1193 if (drv->sock_xmit != NULL) 1194 l2_packet_deinit(drv->sock_xmit); 1195 if (drv->ioctl_sock >= 0) 1196 close(drv->ioctl_sock); 1197 if (drv != NULL) 1198 free(drv); 1199 return NULL; 1200} 1201 1202 1203static void 1204madwifi_deinit(void *priv) 1205{ 1206 struct madwifi_driver_data *drv = priv; 1207 1208 netlink_deinit(drv->netlink); 1209 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1210 if (drv->ioctl_sock >= 0) 1211 close(drv->ioctl_sock); 1212 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1213 l2_packet_deinit(drv->sock_recv); 1214 if (drv->sock_xmit != NULL) 1215 l2_packet_deinit(drv->sock_xmit); 1216 if (drv->sock_raw) 1217 l2_packet_deinit(drv->sock_raw); 1218 free(drv); 1219} 1220 1221static int 1222madwifi_set_ssid(void *priv, const u8 *buf, int len) 1223{ 1224 struct madwifi_driver_data *drv = priv; 1225 struct iwreq iwr; 1226 1227 memset(&iwr, 0, sizeof(iwr)); 1228 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1229 iwr.u.essid.flags = 1; /* SSID active */ 1230 iwr.u.essid.pointer = (caddr_t) buf; 1231 iwr.u.essid.length = len + 1; 1232 1233 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 1234 perror("ioctl[SIOCSIWESSID]"); 1235 printf("len=%d\n", len); 1236 return -1; 1237 } 1238 return 0; 1239} 1240 1241static int 1242madwifi_get_ssid(void *priv, u8 *buf, int len) 1243{ 1244 struct madwifi_driver_data *drv = priv; 1245 struct iwreq iwr; 1246 int ret = 0; 1247 1248 memset(&iwr, 0, sizeof(iwr)); 1249 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1250 iwr.u.essid.pointer = (caddr_t) buf; 1251 iwr.u.essid.length = len; 1252 1253 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1254 perror("ioctl[SIOCGIWESSID]"); 1255 ret = -1; 1256 } else 1257 ret = iwr.u.essid.length; 1258 1259 return ret; 1260} 1261 1262static int 1263madwifi_set_countermeasures(void *priv, int enabled) 1264{ 1265 struct madwifi_driver_data *drv = priv; 1266 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1267 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 1268} 1269 1270static int 1271madwifi_commit(void *priv) 1272{ 1273 struct madwifi_driver_data *drv = priv; 1274 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 1275} 1276 1277const struct wpa_driver_ops wpa_driver_atheros_ops = { 1278 .name = "atheros", 1279 .hapd_init = madwifi_init, 1280 .hapd_deinit = madwifi_deinit, 1281 .set_ieee8021x = madwifi_set_ieee8021x, 1282 .set_privacy = madwifi_set_privacy, 1283 .set_key = madwifi_set_key, 1284 .get_seqnum = madwifi_get_seqnum, 1285 .flush = madwifi_flush, 1286 .set_generic_elem = madwifi_set_opt_ie, 1287 .sta_set_flags = madwifi_sta_set_flags, 1288 .read_sta_data = madwifi_read_sta_driver_data, 1289 .hapd_send_eapol = madwifi_send_eapol, 1290 .sta_disassoc = madwifi_sta_disassoc, 1291 .sta_deauth = madwifi_sta_deauth, 1292 .hapd_set_ssid = madwifi_set_ssid, 1293 .hapd_get_ssid = madwifi_get_ssid, 1294 .set_countermeasures = madwifi_set_countermeasures, 1295 .sta_clear_stats = madwifi_sta_clear_stats, 1296 .commit = madwifi_commit, 1297 .set_ap_wps_ie = madwifi_set_ap_wps_ie, 1298}; 1299