1/* 2 * WPA Supplicant - driver interaction with MADWIFI 802.11 driver 3 * Copyright (c) 2004, Sam Leffler <sam@errno.com> 4 * Copyright (c) 2004, Video54 Technologies 5 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Alternatively, this software may be distributed under the terms of BSD 12 * license. 13 * 14 * See README and COPYING for more details. 15 * 16 * While this driver wrapper supports both AP (hostapd) and station 17 * (wpa_supplicant) operations, the station side is deprecated and 18 * driver_wext.c should be used instead. This driver wrapper should only be 19 * used with hostapd for AP mode functionality. 20 */ 21 22#include "includes.h" 23#include <sys/ioctl.h> 24 25#include "common.h" 26#include "driver.h" 27#include "driver_wext.h" 28#include "eloop.h" 29#include "common/ieee802_11_defs.h" 30#include "wireless_copy.h" 31 32/* 33 * Avoid conflicts with wpa_supplicant definitions by undefining a definition. 34 */ 35#undef WME_OUI_TYPE 36 37#include <include/compat.h> 38#include <net80211/ieee80211.h> 39#ifdef WME_NUM_AC 40/* Assume this is built against BSD branch of madwifi driver. */ 41#define MADWIFI_BSD 42#include <net80211/_ieee80211.h> 43#endif /* WME_NUM_AC */ 44#include <net80211/ieee80211_crypto.h> 45#include <net80211/ieee80211_ioctl.h> 46 47#ifdef CONFIG_WPS 48#ifdef IEEE80211_IOCTL_FILTERFRAME 49#include <netpacket/packet.h> 50 51#ifndef ETH_P_80211_RAW 52#define ETH_P_80211_RAW 0x0019 53#endif 54#endif /* IEEE80211_IOCTL_FILTERFRAME */ 55#endif /* CONFIG_WPS */ 56 57/* 58 * Avoid conflicts with hostapd definitions by undefining couple of defines 59 * from madwifi header files. 60 */ 61#undef RSN_VERSION 62#undef WPA_VERSION 63#undef WPA_OUI_TYPE 64#undef WME_OUI_TYPE 65 66 67#ifdef IEEE80211_IOCTL_SETWMMPARAMS 68/* Assume this is built against madwifi-ng */ 69#define MADWIFI_NG 70#endif /* IEEE80211_IOCTL_SETWMMPARAMS */ 71 72 73#ifdef HOSTAPD 74 75#include "priv_netlink.h" 76#include "netlink.h" 77#include "linux_ioctl.h" 78#include "l2_packet/l2_packet.h" 79 80 81struct madwifi_driver_data { 82 struct hostapd_data *hapd; /* back pointer */ 83 84 char iface[IFNAMSIZ + 1]; 85 int ifindex; 86 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 87 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 88 int ioctl_sock; /* socket for ioctl() use */ 89 struct netlink_data *netlink; 90 int we_version; 91 u8 acct_mac[ETH_ALEN]; 92 struct hostap_sta_driver_data acct_data; 93 94 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 95}; 96 97static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 98 int reason_code); 99 100static int 101set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) 102{ 103 struct iwreq iwr; 104 int do_inline = len < IFNAMSIZ; 105 106 memset(&iwr, 0, sizeof(iwr)); 107 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 108#ifdef IEEE80211_IOCTL_FILTERFRAME 109 /* FILTERFRAME must be NOT inline, regardless of size. */ 110 if (op == IEEE80211_IOCTL_FILTERFRAME) 111 do_inline = 0; 112#endif /* IEEE80211_IOCTL_FILTERFRAME */ 113 if (op == IEEE80211_IOCTL_SET_APPIEBUF) 114 do_inline = 0; 115 if (do_inline) { 116 /* 117 * Argument data fits inline; put it there. 118 */ 119 memcpy(iwr.u.name, data, len); 120 } else { 121 /* 122 * Argument data too big for inline transfer; setup a 123 * parameter block instead; the kernel will transfer 124 * the data for the driver. 125 */ 126 iwr.u.data.pointer = data; 127 iwr.u.data.length = len; 128 } 129 130 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 131#ifdef MADWIFI_NG 132 int first = IEEE80211_IOCTL_SETPARAM; 133 static const char *opnames[] = { 134 "ioctl[IEEE80211_IOCTL_SETPARAM]", 135 "ioctl[IEEE80211_IOCTL_GETPARAM]", 136 "ioctl[IEEE80211_IOCTL_SETMODE]", 137 "ioctl[IEEE80211_IOCTL_GETMODE]", 138 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]", 139 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]", 140 "ioctl[IEEE80211_IOCTL_SETCHANLIST]", 141 "ioctl[IEEE80211_IOCTL_GETCHANLIST]", 142 "ioctl[IEEE80211_IOCTL_CHANSWITCH]", 143 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]", 144 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]", 145 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]", 146 "ioctl[IEEE80211_IOCTL_FILTERFRAME]", 147 "ioctl[IEEE80211_IOCTL_GETCHANINFO]", 148 "ioctl[IEEE80211_IOCTL_SETOPTIE]", 149 "ioctl[IEEE80211_IOCTL_GETOPTIE]", 150 "ioctl[IEEE80211_IOCTL_SETMLME]", 151 NULL, 152 "ioctl[IEEE80211_IOCTL_SETKEY]", 153 NULL, 154 "ioctl[IEEE80211_IOCTL_DELKEY]", 155 NULL, 156 "ioctl[IEEE80211_IOCTL_ADDMAC]", 157 NULL, 158 "ioctl[IEEE80211_IOCTL_DELMAC]", 159 NULL, 160 "ioctl[IEEE80211_IOCTL_WDSMAC]", 161 NULL, 162 "ioctl[IEEE80211_IOCTL_WDSDELMAC]", 163 NULL, 164 "ioctl[IEEE80211_IOCTL_KICKMAC]", 165 }; 166#else /* MADWIFI_NG */ 167 int first = IEEE80211_IOCTL_SETPARAM; 168 static const char *opnames[] = { 169 "ioctl[IEEE80211_IOCTL_SETPARAM]", 170 "ioctl[IEEE80211_IOCTL_GETPARAM]", 171 "ioctl[IEEE80211_IOCTL_SETKEY]", 172 "ioctl[SIOCIWFIRSTPRIV+3]", 173 "ioctl[IEEE80211_IOCTL_DELKEY]", 174 "ioctl[SIOCIWFIRSTPRIV+5]", 175 "ioctl[IEEE80211_IOCTL_SETMLME]", 176 "ioctl[SIOCIWFIRSTPRIV+7]", 177 "ioctl[IEEE80211_IOCTL_SETOPTIE]", 178 "ioctl[IEEE80211_IOCTL_GETOPTIE]", 179 "ioctl[IEEE80211_IOCTL_ADDMAC]", 180 "ioctl[SIOCIWFIRSTPRIV+11]", 181 "ioctl[IEEE80211_IOCTL_DELMAC]", 182 "ioctl[SIOCIWFIRSTPRIV+13]", 183 "ioctl[IEEE80211_IOCTL_CHANLIST]", 184 "ioctl[SIOCIWFIRSTPRIV+15]", 185 "ioctl[IEEE80211_IOCTL_GETRSN]", 186 "ioctl[SIOCIWFIRSTPRIV+17]", 187 "ioctl[IEEE80211_IOCTL_GETKEY]", 188 }; 189#endif /* MADWIFI_NG */ 190 int idx = op - first; 191 if (first <= op && 192 idx < (int) (sizeof(opnames) / sizeof(opnames[0])) && 193 opnames[idx]) 194 perror(opnames[idx]); 195 else 196 perror("ioctl[unknown???]"); 197 return -1; 198 } 199 return 0; 200} 201 202static int 203set80211param(struct madwifi_driver_data *drv, int op, int arg) 204{ 205 struct iwreq iwr; 206 207 memset(&iwr, 0, sizeof(iwr)); 208 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 209 iwr.u.mode = op; 210 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); 211 212 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 213 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 214 wpa_printf(MSG_DEBUG, "%s: Failed to set parameter (op %d " 215 "arg %d)", __func__, op, arg); 216 return -1; 217 } 218 return 0; 219} 220 221#ifndef CONFIG_NO_STDOUT_DEBUG 222static const char * 223ether_sprintf(const u8 *addr) 224{ 225 static char buf[sizeof(MACSTR)]; 226 227 if (addr != NULL) 228 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 229 else 230 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 231 return buf; 232} 233#endif /* CONFIG_NO_STDOUT_DEBUG */ 234 235/* 236 * Configure WPA parameters. 237 */ 238static int 239madwifi_configure_wpa(struct madwifi_driver_data *drv, 240 struct wpa_bss_params *params) 241{ 242 int v; 243 244 switch (params->wpa_group) { 245 case WPA_CIPHER_CCMP: 246 v = IEEE80211_CIPHER_AES_CCM; 247 break; 248 case WPA_CIPHER_TKIP: 249 v = IEEE80211_CIPHER_TKIP; 250 break; 251 case WPA_CIPHER_WEP104: 252 v = IEEE80211_CIPHER_WEP; 253 break; 254 case WPA_CIPHER_WEP40: 255 v = IEEE80211_CIPHER_WEP; 256 break; 257 case WPA_CIPHER_NONE: 258 v = IEEE80211_CIPHER_NONE; 259 break; 260 default: 261 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 262 params->wpa_group); 263 return -1; 264 } 265 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 266 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 267 printf("Unable to set group key cipher to %u\n", v); 268 return -1; 269 } 270 if (v == IEEE80211_CIPHER_WEP) { 271 /* key length is done only for specific ciphers */ 272 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 273 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 274 printf("Unable to set group key length to %u\n", v); 275 return -1; 276 } 277 } 278 279 v = 0; 280 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 281 v |= 1<<IEEE80211_CIPHER_AES_CCM; 282 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 283 v |= 1<<IEEE80211_CIPHER_TKIP; 284 if (params->wpa_pairwise & WPA_CIPHER_NONE) 285 v |= 1<<IEEE80211_CIPHER_NONE; 286 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 287 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 288 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 289 return -1; 290 } 291 292 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 293 __func__, params->wpa_key_mgmt); 294 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 295 params->wpa_key_mgmt)) { 296 printf("Unable to set key management algorithms to 0x%x\n", 297 params->wpa_key_mgmt); 298 return -1; 299 } 300 301 v = 0; 302 if (params->rsn_preauth) 303 v |= BIT(0); 304 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", 305 __func__, params->rsn_preauth); 306 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 307 printf("Unable to set RSN capabilities to 0x%x\n", v); 308 return -1; 309 } 310 311 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 312 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 313 printf("Unable to set WPA to %u\n", params->wpa); 314 return -1; 315 } 316 return 0; 317} 318 319static int 320madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) 321{ 322 struct madwifi_driver_data *drv = priv; 323 324 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 325 326 if (!params->enabled) { 327 /* XXX restore state */ 328 return set80211param(priv, IEEE80211_PARAM_AUTHMODE, 329 IEEE80211_AUTH_AUTO); 330 } 331 if (!params->wpa && !params->ieee802_1x) { 332 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 333 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); 334 return -1; 335 } 336 if (params->wpa && madwifi_configure_wpa(drv, params) != 0) { 337 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 338 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); 339 return -1; 340 } 341 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 342 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 343 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 344 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); 345 return -1; 346 } 347 348 return 0; 349} 350 351static int 352madwifi_set_privacy(void *priv, int enabled) 353{ 354 struct madwifi_driver_data *drv = priv; 355 356 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 357 358 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 359} 360 361static int 362madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized) 363{ 364 struct madwifi_driver_data *drv = priv; 365 struct ieee80211req_mlme mlme; 366 int ret; 367 368 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 369 __func__, ether_sprintf(addr), authorized); 370 371 if (authorized) 372 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 373 else 374 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 375 mlme.im_reason = 0; 376 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 377 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 378 if (ret < 0) { 379 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 380 __func__, authorized ? "" : "un", MAC2STR(addr)); 381 } 382 383 return ret; 384} 385 386static int 387madwifi_sta_set_flags(void *priv, const u8 *addr, 388 int total_flags, int flags_or, int flags_and) 389{ 390 /* For now, only support setting Authorized flag */ 391 if (flags_or & WPA_STA_AUTHORIZED) 392 return madwifi_set_sta_authorized(priv, addr, 1); 393 if (!(flags_and & WPA_STA_AUTHORIZED)) 394 return madwifi_set_sta_authorized(priv, addr, 0); 395 return 0; 396} 397 398static int 399madwifi_del_key(void *priv, const u8 *addr, int key_idx) 400{ 401 struct madwifi_driver_data *drv = priv; 402 struct ieee80211req_del_key wk; 403 int ret; 404 405 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 406 __func__, ether_sprintf(addr), key_idx); 407 408 memset(&wk, 0, sizeof(wk)); 409 if (addr != NULL) { 410 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 411 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 412 } else { 413 wk.idk_keyix = key_idx; 414 } 415 416 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 417 if (ret < 0) { 418 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 419 " key_idx %d)", __func__, ether_sprintf(addr), 420 key_idx); 421 } 422 423 return ret; 424} 425 426static int 427wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, 428 const u8 *addr, int key_idx, int set_tx, 429 const u8 *seq, size_t seq_len, 430 const u8 *key, size_t key_len) 431{ 432 struct madwifi_driver_data *drv = priv; 433 struct ieee80211req_key wk; 434 u_int8_t cipher; 435 int ret; 436 437 if (alg == WPA_ALG_NONE) 438 return madwifi_del_key(drv, addr, key_idx); 439 440 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 441 __func__, alg, ether_sprintf(addr), key_idx); 442 443 if (alg == WPA_ALG_WEP) 444 cipher = IEEE80211_CIPHER_WEP; 445 else if (alg == WPA_ALG_TKIP) 446 cipher = IEEE80211_CIPHER_TKIP; 447 else if (alg == WPA_ALG_CCMP) 448 cipher = IEEE80211_CIPHER_AES_CCM; 449 else { 450 printf("%s: unknown/unsupported algorithm %d\n", 451 __func__, alg); 452 return -1; 453 } 454 455 if (key_len > sizeof(wk.ik_keydata)) { 456 printf("%s: key length %lu too big\n", __func__, 457 (unsigned long) key_len); 458 return -3; 459 } 460 461 memset(&wk, 0, sizeof(wk)); 462 wk.ik_type = cipher; 463 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 464 if (addr == NULL) { 465 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 466 wk.ik_keyix = key_idx; 467 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 468 } else { 469 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 470 wk.ik_keyix = IEEE80211_KEYIX_NONE; 471 } 472 wk.ik_keylen = key_len; 473 memcpy(wk.ik_keydata, key, key_len); 474 475 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 476 if (ret < 0) { 477 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 478 " key_idx %d alg %d key_len %lu set_tx %d)", 479 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 480 alg, (unsigned long) key_len, set_tx); 481 } 482 483 return ret; 484} 485 486 487static int 488madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 489 u8 *seq) 490{ 491 struct madwifi_driver_data *drv = priv; 492 struct ieee80211req_key wk; 493 494 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 495 __func__, ether_sprintf(addr), idx); 496 497 memset(&wk, 0, sizeof(wk)); 498 if (addr == NULL) 499 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 500 else 501 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 502 wk.ik_keyix = idx; 503 504 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 505 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 506 "(addr " MACSTR " key_idx %d)", 507 __func__, MAC2STR(wk.ik_macaddr), idx); 508 return -1; 509 } 510 511#ifdef WORDS_BIGENDIAN 512 { 513 /* 514 * wk.ik_keytsc is in host byte order (big endian), need to 515 * swap it to match with the byte order used in WPA. 516 */ 517 int i; 518 u8 tmp[WPA_KEY_RSC_LEN]; 519 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 520 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 521 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 522 } 523 } 524#else /* WORDS_BIGENDIAN */ 525 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 526#endif /* WORDS_BIGENDIAN */ 527 return 0; 528} 529 530 531static int 532madwifi_flush(void *priv) 533{ 534#ifdef MADWIFI_BSD 535 u8 allsta[IEEE80211_ADDR_LEN]; 536 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 537 return madwifi_sta_deauth(priv, NULL, allsta, 538 IEEE80211_REASON_AUTH_LEAVE); 539#else /* MADWIFI_BSD */ 540 return 0; /* XXX */ 541#endif /* MADWIFI_BSD */ 542} 543 544 545static int 546madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 547 const u8 *addr) 548{ 549 struct madwifi_driver_data *drv = priv; 550 551#ifdef MADWIFI_BSD 552 struct ieee80211req_sta_stats stats; 553 554 memset(data, 0, sizeof(*data)); 555 556 /* 557 * Fetch statistics for station from the system. 558 */ 559 memset(&stats, 0, sizeof(stats)); 560 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 561 if (set80211priv(drv, 562#ifdef MADWIFI_NG 563 IEEE80211_IOCTL_STA_STATS, 564#else /* MADWIFI_NG */ 565 IEEE80211_IOCTL_GETSTASTATS, 566#endif /* MADWIFI_NG */ 567 &stats, sizeof(stats))) { 568 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 569 MACSTR ")", __func__, MAC2STR(addr)); 570 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 571 memcpy(data, &drv->acct_data, sizeof(*data)); 572 return 0; 573 } 574 575 printf("Failed to get station stats information element.\n"); 576 return -1; 577 } 578 579 data->rx_packets = stats.is_stats.ns_rx_data; 580 data->rx_bytes = stats.is_stats.ns_rx_bytes; 581 data->tx_packets = stats.is_stats.ns_tx_data; 582 data->tx_bytes = stats.is_stats.ns_tx_bytes; 583 return 0; 584 585#else /* MADWIFI_BSD */ 586 587 char buf[1024], line[128], *pos; 588 FILE *f; 589 unsigned long val; 590 591 memset(data, 0, sizeof(*data)); 592 snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR, 593 drv->iface, MAC2STR(addr)); 594 595 f = fopen(buf, "r"); 596 if (!f) { 597 if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0) 598 return -1; 599 memcpy(data, &drv->acct_data, sizeof(*data)); 600 return 0; 601 } 602 /* Need to read proc file with in one piece, so use large enough 603 * buffer. */ 604 setbuffer(f, buf, sizeof(buf)); 605 606 while (fgets(line, sizeof(line), f)) { 607 pos = strchr(line, '='); 608 if (!pos) 609 continue; 610 *pos++ = '\0'; 611 val = strtoul(pos, NULL, 10); 612 if (strcmp(line, "rx_packets") == 0) 613 data->rx_packets = val; 614 else if (strcmp(line, "tx_packets") == 0) 615 data->tx_packets = val; 616 else if (strcmp(line, "rx_bytes") == 0) 617 data->rx_bytes = val; 618 else if (strcmp(line, "tx_bytes") == 0) 619 data->tx_bytes = val; 620 } 621 622 fclose(f); 623 624 return 0; 625#endif /* MADWIFI_BSD */ 626} 627 628 629static int 630madwifi_sta_clear_stats(void *priv, const u8 *addr) 631{ 632#if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS) 633 struct madwifi_driver_data *drv = priv; 634 struct ieee80211req_mlme mlme; 635 int ret; 636 637 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 638 639 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 640 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 641 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 642 sizeof(mlme)); 643 if (ret < 0) { 644 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 645 MACSTR ")", __func__, MAC2STR(addr)); 646 } 647 648 return ret; 649#else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */ 650 return 0; /* FIX */ 651#endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */ 652} 653 654 655static int 656madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 657{ 658 /* 659 * Do nothing; we setup parameters at startup that define the 660 * contents of the beacon information element. 661 */ 662 return 0; 663} 664 665static int 666madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 667 int reason_code) 668{ 669 struct madwifi_driver_data *drv = priv; 670 struct ieee80211req_mlme mlme; 671 int ret; 672 673 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 674 __func__, ether_sprintf(addr), reason_code); 675 676 mlme.im_op = IEEE80211_MLME_DEAUTH; 677 mlme.im_reason = reason_code; 678 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 679 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 680 if (ret < 0) { 681 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 682 " reason %d)", 683 __func__, MAC2STR(addr), reason_code); 684 } 685 686 return ret; 687} 688 689static int 690madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 691 int reason_code) 692{ 693 struct madwifi_driver_data *drv = priv; 694 struct ieee80211req_mlme mlme; 695 int ret; 696 697 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 698 __func__, ether_sprintf(addr), reason_code); 699 700 mlme.im_op = IEEE80211_MLME_DISASSOC; 701 mlme.im_reason = reason_code; 702 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 703 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 704 if (ret < 0) { 705 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 706 MACSTR " reason %d)", 707 __func__, MAC2STR(addr), reason_code); 708 } 709 710 return ret; 711} 712 713#ifdef CONFIG_WPS 714#ifdef IEEE80211_IOCTL_FILTERFRAME 715static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 716 size_t len) 717{ 718 struct madwifi_driver_data *drv = ctx; 719 const struct ieee80211_mgmt *mgmt; 720 u16 fc; 721 union wpa_event_data event; 722 723 /* Send Probe Request information to WPS processing */ 724 725 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 726 return; 727 mgmt = (const struct ieee80211_mgmt *) buf; 728 729 fc = le_to_host16(mgmt->frame_control); 730 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 731 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) 732 return; 733 734 os_memset(&event, 0, sizeof(event)); 735 event.rx_probe_req.sa = mgmt->sa; 736 event.rx_probe_req.ie = mgmt->u.probe_req.variable; 737 event.rx_probe_req.ie_len = 738 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 739 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 740} 741#endif /* IEEE80211_IOCTL_FILTERFRAME */ 742#endif /* CONFIG_WPS */ 743 744static int madwifi_receive_probe_req(struct madwifi_driver_data *drv) 745{ 746 int ret = 0; 747#ifdef CONFIG_WPS 748#ifdef IEEE80211_IOCTL_FILTERFRAME 749 struct ieee80211req_set_filter filt; 750 751 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 752 filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ; 753 754 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 755 sizeof(struct ieee80211req_set_filter)); 756 if (ret) 757 return ret; 758 759 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 760 madwifi_raw_receive, drv, 1); 761 if (drv->sock_raw == NULL) 762 return -1; 763#endif /* IEEE80211_IOCTL_FILTERFRAME */ 764#endif /* CONFIG_WPS */ 765 return ret; 766} 767 768#ifdef CONFIG_WPS 769static int 770madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 771{ 772 struct madwifi_driver_data *drv = priv; 773 u8 buf[256]; 774 struct ieee80211req_getset_appiebuf *beac_ie; 775 776 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 777 (unsigned long) len); 778 779 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 780 beac_ie->app_frmtype = frametype; 781 beac_ie->app_buflen = len; 782 memcpy(&(beac_ie->app_buf[0]), ie, len); 783 784 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 785 sizeof(struct ieee80211req_getset_appiebuf) + len); 786} 787 788static int 789madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 790 const struct wpabuf *proberesp) 791{ 792 if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 793 beacon ? wpabuf_len(beacon) : 0, 794 IEEE80211_APPIE_FRAME_BEACON) < 0) 795 return -1; 796 return madwifi_set_wps_ie(priv, 797 proberesp ? wpabuf_head(proberesp) : NULL, 798 proberesp ? wpabuf_len(proberesp) : 0, 799 IEEE80211_APPIE_FRAME_PROBE_RESP); 800} 801#else /* CONFIG_WPS */ 802#define madwifi_set_ap_wps_ie NULL 803#endif /* CONFIG_WPS */ 804 805static void 806madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 807{ 808 struct hostapd_data *hapd = drv->hapd; 809 struct ieee80211req_wpaie ie; 810 int ielen = 0; 811 u8 *iebuf = NULL; 812 813 /* 814 * Fetch negotiated WPA/RSN parameters from the system. 815 */ 816 memset(&ie, 0, sizeof(ie)); 817 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 818 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 819 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE", 820 __func__); 821 goto no_ie; 822 } 823 wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE", 824 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 825 iebuf = ie.wpa_ie; 826 /* madwifi seems to return some random data if WPA/RSN IE is not set. 827 * Assume the IE was not included if the IE type is unknown. */ 828 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 829 iebuf[1] = 0; 830#ifdef MADWIFI_NG 831 wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE", 832 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 833 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 834 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 835 * set. This is needed for WPA2. */ 836 iebuf = ie.rsn_ie; 837 if (iebuf[0] != WLAN_EID_RSN) 838 iebuf[1] = 0; 839 } 840#endif /* MADWIFI_NG */ 841 842 ielen = iebuf[1]; 843 if (ielen == 0) 844 iebuf = NULL; 845 else 846 ielen += 2; 847 848no_ie: 849 drv_event_assoc(hapd, addr, iebuf, ielen); 850 851 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 852 /* Cached accounting data is not valid anymore. */ 853 memset(drv->acct_mac, 0, ETH_ALEN); 854 memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 855 } 856} 857 858static void 859madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, 860 char *custom) 861{ 862 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 863 864 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 865 char *pos; 866 u8 addr[ETH_ALEN]; 867 pos = strstr(custom, "addr="); 868 if (pos == NULL) { 869 wpa_printf(MSG_DEBUG, 870 "MLME-MICHAELMICFAILURE.indication " 871 "without sender address ignored"); 872 return; 873 } 874 pos += 5; 875 if (hwaddr_aton(pos, addr) == 0) { 876 union wpa_event_data data; 877 os_memset(&data, 0, sizeof(data)); 878 data.michael_mic_failure.unicast = 1; 879 data.michael_mic_failure.src = addr; 880 wpa_supplicant_event(drv->hapd, 881 EVENT_MICHAEL_MIC_FAILURE, &data); 882 } else { 883 wpa_printf(MSG_DEBUG, 884 "MLME-MICHAELMICFAILURE.indication " 885 "with invalid MAC address"); 886 } 887 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 888 char *key, *value; 889 u32 val; 890 key = custom; 891 while ((key = strchr(key, '\n')) != NULL) { 892 key++; 893 value = strchr(key, '='); 894 if (value == NULL) 895 continue; 896 *value++ = '\0'; 897 val = strtoul(value, NULL, 10); 898 if (strcmp(key, "mac") == 0) 899 hwaddr_aton(value, drv->acct_mac); 900 else if (strcmp(key, "rx_packets") == 0) 901 drv->acct_data.rx_packets = val; 902 else if (strcmp(key, "tx_packets") == 0) 903 drv->acct_data.tx_packets = val; 904 else if (strcmp(key, "rx_bytes") == 0) 905 drv->acct_data.rx_bytes = val; 906 else if (strcmp(key, "tx_bytes") == 0) 907 drv->acct_data.tx_bytes = val; 908 key = value; 909 } 910 } 911} 912 913static void 914madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, 915 char *data, int len) 916{ 917 struct iw_event iwe_buf, *iwe = &iwe_buf; 918 char *pos, *end, *custom, *buf; 919 920 pos = data; 921 end = data + len; 922 923 while (pos + IW_EV_LCP_LEN <= end) { 924 /* Event data may be unaligned, so make a local, aligned copy 925 * before processing. */ 926 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 927 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 928 iwe->cmd, iwe->len); 929 if (iwe->len <= IW_EV_LCP_LEN) 930 return; 931 932 custom = pos + IW_EV_POINT_LEN; 933 if (drv->we_version > 18 && 934 (iwe->cmd == IWEVMICHAELMICFAILURE || 935 iwe->cmd == IWEVCUSTOM)) { 936 /* WE-19 removed the pointer from struct iw_point */ 937 char *dpos = (char *) &iwe_buf.u.data.length; 938 int dlen = dpos - (char *) &iwe_buf; 939 memcpy(dpos, pos + IW_EV_LCP_LEN, 940 sizeof(struct iw_event) - dlen); 941 } else { 942 memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 943 custom += IW_EV_POINT_OFF; 944 } 945 946 switch (iwe->cmd) { 947 case IWEVEXPIRED: 948 drv_event_disassoc(drv->hapd, 949 (u8 *) iwe->u.addr.sa_data); 950 break; 951 case IWEVREGISTERED: 952 madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 953 break; 954 case IWEVCUSTOM: 955 if (custom + iwe->u.data.length > end) 956 return; 957 buf = malloc(iwe->u.data.length + 1); 958 if (buf == NULL) 959 return; /* XXX */ 960 memcpy(buf, custom, iwe->u.data.length); 961 buf[iwe->u.data.length] = '\0'; 962 madwifi_wireless_event_wireless_custom(drv, buf); 963 free(buf); 964 break; 965 } 966 967 pos += iwe->len; 968 } 969} 970 971 972static void 973madwifi_wireless_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, 974 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_xmit != NULL) 1192 l2_packet_deinit(drv->sock_xmit); 1193 if (drv->ioctl_sock >= 0) 1194 close(drv->ioctl_sock); 1195 if (drv != NULL) 1196 free(drv); 1197 return NULL; 1198} 1199 1200 1201static void 1202madwifi_deinit(void *priv) 1203{ 1204 struct madwifi_driver_data *drv = priv; 1205 1206 netlink_deinit(drv->netlink); 1207 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1208 if (drv->ioctl_sock >= 0) 1209 close(drv->ioctl_sock); 1210 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1211 l2_packet_deinit(drv->sock_recv); 1212 if (drv->sock_xmit != NULL) 1213 l2_packet_deinit(drv->sock_xmit); 1214 if (drv->sock_raw) 1215 l2_packet_deinit(drv->sock_raw); 1216 free(drv); 1217} 1218 1219static int 1220madwifi_set_ssid(void *priv, const u8 *buf, int len) 1221{ 1222 struct madwifi_driver_data *drv = priv; 1223 struct iwreq iwr; 1224 1225 memset(&iwr, 0, sizeof(iwr)); 1226 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1227 iwr.u.essid.flags = 1; /* SSID active */ 1228 iwr.u.essid.pointer = (caddr_t) buf; 1229 iwr.u.essid.length = len + 1; 1230 1231 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 1232 perror("ioctl[SIOCSIWESSID]"); 1233 printf("len=%d\n", len); 1234 return -1; 1235 } 1236 return 0; 1237} 1238 1239static int 1240madwifi_get_ssid(void *priv, u8 *buf, int len) 1241{ 1242 struct madwifi_driver_data *drv = priv; 1243 struct iwreq iwr; 1244 int ret = 0; 1245 1246 memset(&iwr, 0, sizeof(iwr)); 1247 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1248 iwr.u.essid.pointer = (caddr_t) buf; 1249 iwr.u.essid.length = len; 1250 1251 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1252 perror("ioctl[SIOCGIWESSID]"); 1253 ret = -1; 1254 } else 1255 ret = iwr.u.essid.length; 1256 1257 return ret; 1258} 1259 1260static int 1261madwifi_set_countermeasures(void *priv, int enabled) 1262{ 1263 struct madwifi_driver_data *drv = priv; 1264 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1265 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 1266} 1267 1268static int 1269madwifi_commit(void *priv) 1270{ 1271 struct madwifi_driver_data *drv = priv; 1272 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 1273} 1274 1275#else /* HOSTAPD */ 1276 1277struct wpa_driver_madwifi_data { 1278 void *wext; /* private data for driver_wext */ 1279 void *ctx; 1280 char ifname[IFNAMSIZ + 1]; 1281 int sock; 1282}; 1283 1284static int wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg); 1285static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies, 1286 size_t ies_len); 1287 1288 1289static int 1290set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len, 1291 int show_err) 1292{ 1293 struct iwreq iwr; 1294 1295 os_memset(&iwr, 0, sizeof(iwr)); 1296 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1297 if (len < IFNAMSIZ && 1298 op != IEEE80211_IOCTL_SET_APPIEBUF) { 1299 /* 1300 * Argument data fits inline; put it there. 1301 */ 1302 os_memcpy(iwr.u.name, data, len); 1303 } else { 1304 /* 1305 * Argument data too big for inline transfer; setup a 1306 * parameter block instead; the kernel will transfer 1307 * the data for the driver. 1308 */ 1309 iwr.u.data.pointer = data; 1310 iwr.u.data.length = len; 1311 } 1312 1313 if (ioctl(drv->sock, op, &iwr) < 0) { 1314 if (show_err) { 1315#ifdef MADWIFI_NG 1316 int first = IEEE80211_IOCTL_SETPARAM; 1317 int last = IEEE80211_IOCTL_KICKMAC; 1318 static const char *opnames[] = { 1319 "ioctl[IEEE80211_IOCTL_SETPARAM]", 1320 "ioctl[IEEE80211_IOCTL_GETPARAM]", 1321 "ioctl[IEEE80211_IOCTL_SETMODE]", 1322 "ioctl[IEEE80211_IOCTL_GETMODE]", 1323 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]", 1324 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]", 1325 "ioctl[IEEE80211_IOCTL_SETCHANLIST]", 1326 "ioctl[IEEE80211_IOCTL_GETCHANLIST]", 1327 "ioctl[IEEE80211_IOCTL_CHANSWITCH]", 1328 NULL, 1329 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]", 1330 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]", 1331 NULL, 1332 "ioctl[IEEE80211_IOCTL_GETCHANINFO]", 1333 "ioctl[IEEE80211_IOCTL_SETOPTIE]", 1334 "ioctl[IEEE80211_IOCTL_GETOPTIE]", 1335 "ioctl[IEEE80211_IOCTL_SETMLME]", 1336 NULL, 1337 "ioctl[IEEE80211_IOCTL_SETKEY]", 1338 NULL, 1339 "ioctl[IEEE80211_IOCTL_DELKEY]", 1340 NULL, 1341 "ioctl[IEEE80211_IOCTL_ADDMAC]", 1342 NULL, 1343 "ioctl[IEEE80211_IOCTL_DELMAC]", 1344 NULL, 1345 "ioctl[IEEE80211_IOCTL_WDSMAC]", 1346 NULL, 1347 "ioctl[IEEE80211_IOCTL_WDSDELMAC]", 1348 NULL, 1349 "ioctl[IEEE80211_IOCTL_KICKMAC]", 1350 }; 1351#else /* MADWIFI_NG */ 1352 int first = IEEE80211_IOCTL_SETPARAM; 1353 int last = IEEE80211_IOCTL_CHANLIST; 1354 static const char *opnames[] = { 1355 "ioctl[IEEE80211_IOCTL_SETPARAM]", 1356 "ioctl[IEEE80211_IOCTL_GETPARAM]", 1357 "ioctl[IEEE80211_IOCTL_SETKEY]", 1358 "ioctl[IEEE80211_IOCTL_GETKEY]", 1359 "ioctl[IEEE80211_IOCTL_DELKEY]", 1360 NULL, 1361 "ioctl[IEEE80211_IOCTL_SETMLME]", 1362 NULL, 1363 "ioctl[IEEE80211_IOCTL_SETOPTIE]", 1364 "ioctl[IEEE80211_IOCTL_GETOPTIE]", 1365 "ioctl[IEEE80211_IOCTL_ADDMAC]", 1366 NULL, 1367 "ioctl[IEEE80211_IOCTL_DELMAC]", 1368 NULL, 1369 "ioctl[IEEE80211_IOCTL_CHANLIST]", 1370 }; 1371#endif /* MADWIFI_NG */ 1372 int idx = op - first; 1373 if (first <= op && op <= last && 1374 idx < (int) (sizeof(opnames) / sizeof(opnames[0])) 1375 && opnames[idx]) 1376 perror(opnames[idx]); 1377 else 1378 perror("ioctl[unknown???]"); 1379 } 1380 return -1; 1381 } 1382 return 0; 1383} 1384 1385static int 1386set80211param(struct wpa_driver_madwifi_data *drv, int op, int arg, 1387 int show_err) 1388{ 1389 struct iwreq iwr; 1390 1391 os_memset(&iwr, 0, sizeof(iwr)); 1392 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1393 iwr.u.mode = op; 1394 os_memcpy(iwr.u.name+sizeof(u32), &arg, sizeof(arg)); 1395 1396 if (ioctl(drv->sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 1397 if (show_err) 1398 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 1399 return -1; 1400 } 1401 return 0; 1402} 1403 1404static int 1405wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data *drv, 1406 const u8 *wpa_ie, size_t wpa_ie_len) 1407{ 1408 struct iwreq iwr; 1409 1410 os_memset(&iwr, 0, sizeof(iwr)); 1411 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1412 /* NB: SETOPTIE is not fixed-size so must not be inlined */ 1413 iwr.u.data.pointer = (void *) wpa_ie; 1414 iwr.u.data.length = wpa_ie_len; 1415 1416 if (ioctl(drv->sock, IEEE80211_IOCTL_SETOPTIE, &iwr) < 0) { 1417 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]"); 1418 return -1; 1419 } 1420 return 0; 1421} 1422 1423static int 1424wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data *drv, int key_idx, 1425 const u8 *addr) 1426{ 1427 struct ieee80211req_del_key wk; 1428 1429 wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx); 1430 os_memset(&wk, 0, sizeof(wk)); 1431 wk.idk_keyix = key_idx; 1432 if (addr != NULL) 1433 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 1434 1435 return set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk), 1); 1436} 1437 1438static int 1439wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, 1440 const u8 *addr, int key_idx, int set_tx, 1441 const u8 *seq, size_t seq_len, 1442 const u8 *key, size_t key_len) 1443{ 1444 struct wpa_driver_madwifi_data *drv = priv; 1445 struct ieee80211req_key wk; 1446 char *alg_name; 1447 u_int8_t cipher; 1448 1449 if (alg == WPA_ALG_NONE) 1450 return wpa_driver_madwifi_del_key(drv, key_idx, addr); 1451 1452 switch (alg) { 1453 case WPA_ALG_WEP: 1454 if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", 1455 ETH_ALEN) == 0) { 1456 /* 1457 * madwifi did not seem to like static WEP key 1458 * configuration with IEEE80211_IOCTL_SETKEY, so use 1459 * Linux wireless extensions ioctl for this. 1460 */ 1461 return wpa_driver_wext_set_key(ifname, drv->wext, alg, 1462 addr, key_idx, set_tx, 1463 seq, seq_len, 1464 key, key_len); 1465 } 1466 alg_name = "WEP"; 1467 cipher = IEEE80211_CIPHER_WEP; 1468 break; 1469 case WPA_ALG_TKIP: 1470 alg_name = "TKIP"; 1471 cipher = IEEE80211_CIPHER_TKIP; 1472 break; 1473 case WPA_ALG_CCMP: 1474 alg_name = "CCMP"; 1475 cipher = IEEE80211_CIPHER_AES_CCM; 1476 break; 1477 default: 1478 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", 1479 __FUNCTION__, alg); 1480 return -1; 1481 } 1482 1483 wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " 1484 "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, 1485 (unsigned long) seq_len, (unsigned long) key_len); 1486 1487 if (seq_len > sizeof(u_int64_t)) { 1488 wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big", 1489 __FUNCTION__, (unsigned long) seq_len); 1490 return -2; 1491 } 1492 if (key_len > sizeof(wk.ik_keydata)) { 1493 wpa_printf(MSG_DEBUG, "%s: key length %lu too big", 1494 __FUNCTION__, (unsigned long) key_len); 1495 return -3; 1496 } 1497 1498 os_memset(&wk, 0, sizeof(wk)); 1499 wk.ik_type = cipher; 1500 wk.ik_flags = IEEE80211_KEY_RECV; 1501 if (addr == NULL || 1502 os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) 1503 wk.ik_flags |= IEEE80211_KEY_GROUP; 1504 if (set_tx) { 1505 wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT; 1506 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 1507 } else 1508 os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN); 1509 wk.ik_keyix = key_idx; 1510 wk.ik_keylen = key_len; 1511#ifdef WORDS_BIGENDIAN 1512#define WPA_KEY_RSC_LEN 8 1513 { 1514 size_t i; 1515 u8 tmp[WPA_KEY_RSC_LEN]; 1516 os_memset(tmp, 0, sizeof(tmp)); 1517 for (i = 0; i < seq_len; i++) 1518 tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; 1519 os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); 1520 } 1521#else /* WORDS_BIGENDIAN */ 1522 os_memcpy(&wk.ik_keyrsc, seq, seq_len); 1523#endif /* WORDS_BIGENDIAN */ 1524 os_memcpy(wk.ik_keydata, key, key_len); 1525 1526 return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1); 1527} 1528 1529static int 1530wpa_driver_madwifi_set_countermeasures(void *priv, int enabled) 1531{ 1532 struct wpa_driver_madwifi_data *drv = priv; 1533 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1534 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled, 1); 1535} 1536 1537static int 1538wpa_driver_madwifi_deauthenticate(void *priv, const u8 *addr, int reason_code) 1539{ 1540 struct wpa_driver_madwifi_data *drv = priv; 1541 struct ieee80211req_mlme mlme; 1542 1543 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1544 mlme.im_op = IEEE80211_MLME_DEAUTH; 1545 mlme.im_reason = reason_code; 1546 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1547 return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1); 1548} 1549 1550static int 1551wpa_driver_madwifi_disassociate(void *priv, const u8 *addr, int reason_code) 1552{ 1553 struct wpa_driver_madwifi_data *drv = priv; 1554 struct ieee80211req_mlme mlme; 1555 1556 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1557 mlme.im_op = IEEE80211_MLME_DISASSOC; 1558 mlme.im_reason = reason_code; 1559 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1560 return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1); 1561} 1562 1563static int 1564wpa_driver_madwifi_associate(void *priv, 1565 struct wpa_driver_associate_params *params) 1566{ 1567 struct wpa_driver_madwifi_data *drv = priv; 1568 struct ieee80211req_mlme mlme; 1569 int ret = 0, privacy = 1; 1570 1571 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 1572 1573 if (set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED, 1574 params->drop_unencrypted, 1) < 0) 1575 ret = -1; 1576 if (wpa_driver_madwifi_set_auth_alg(drv, params->auth_alg) < 0) 1577 ret = -1; 1578 1579 /* 1580 * NB: Don't need to set the freq or cipher-related state as 1581 * this is implied by the bssid which is used to locate 1582 * the scanned node state which holds it. The ssid is 1583 * needed to disambiguate an AP that broadcasts multiple 1584 * ssid's but uses the same bssid. 1585 */ 1586 /* XXX error handling is wrong but unclear what to do... */ 1587 if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie, 1588 params->wpa_ie_len) < 0) 1589 ret = -1; 1590 1591 if (params->pairwise_suite == CIPHER_NONE && 1592 params->group_suite == CIPHER_NONE && 1593 params->key_mgmt_suite == KEY_MGMT_NONE && 1594 params->wpa_ie_len == 0) 1595 privacy = 0; 1596 1597 if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0) 1598 ret = -1; 1599 1600 if (params->wpa_ie_len && 1601 set80211param(drv, IEEE80211_PARAM_WPA, 1602 params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1, 1) < 0) 1603 ret = -1; 1604 1605 if (params->bssid == NULL) { 1606 /* ap_scan=2 mode - driver takes care of AP selection and 1607 * roaming */ 1608 /* FIX: this does not seem to work; would probably need to 1609 * change something in the driver */ 1610 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) 1611 ret = -1; 1612 1613 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, 1614 params->ssid_len) < 0) 1615 ret = -1; 1616 } else { 1617 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) 1618 ret = -1; 1619 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, 1620 params->ssid_len) < 0) 1621 ret = -1; 1622 os_memset(&mlme, 0, sizeof(mlme)); 1623 mlme.im_op = IEEE80211_MLME_ASSOC; 1624 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); 1625 if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 1626 sizeof(mlme), 1) < 0) { 1627 wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed", 1628 __func__); 1629 ret = -1; 1630 } 1631 } 1632 1633 return ret; 1634} 1635 1636static int 1637wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg) 1638{ 1639 struct wpa_driver_madwifi_data *drv = priv; 1640 int authmode; 1641 1642 if ((auth_alg & WPA_AUTH_ALG_OPEN) && 1643 (auth_alg & WPA_AUTH_ALG_SHARED)) 1644 authmode = IEEE80211_AUTH_AUTO; 1645 else if (auth_alg & WPA_AUTH_ALG_SHARED) 1646 authmode = IEEE80211_AUTH_SHARED; 1647 else 1648 authmode = IEEE80211_AUTH_OPEN; 1649 1650 return set80211param(drv, IEEE80211_PARAM_AUTHMODE, authmode, 1); 1651} 1652 1653static int 1654wpa_driver_madwifi_scan(void *priv, struct wpa_driver_scan_params *params) 1655{ 1656 struct wpa_driver_madwifi_data *drv = priv; 1657 struct iwreq iwr; 1658 int ret = 0; 1659 const u8 *ssid = params->ssids[0].ssid; 1660 size_t ssid_len = params->ssids[0].ssid_len; 1661 1662 wpa_driver_madwifi_set_probe_req_ie(drv, params->extra_ies, 1663 params->extra_ies_len); 1664 1665 os_memset(&iwr, 0, sizeof(iwr)); 1666 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 1667 1668 /* set desired ssid before scan */ 1669 /* FIX: scan should not break the current association, so using 1670 * set_ssid may not be the best way of doing this.. */ 1671 if (wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len) < 0) 1672 ret = -1; 1673 1674 if (ioctl(drv->sock, SIOCSIWSCAN, &iwr) < 0) { 1675 perror("ioctl[SIOCSIWSCAN]"); 1676 ret = -1; 1677 } 1678 1679 /* 1680 * madwifi delivers a scan complete event so no need to poll, but 1681 * register a backup timeout anyway to make sure that we recover even 1682 * if the driver does not send this event for any reason. This timeout 1683 * will only be used if the event is not delivered (event handler will 1684 * cancel the timeout). 1685 */ 1686 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, 1687 drv->ctx); 1688 eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext, 1689 drv->ctx); 1690 1691 return ret; 1692} 1693 1694static int wpa_driver_madwifi_get_bssid(void *priv, u8 *bssid) 1695{ 1696 struct wpa_driver_madwifi_data *drv = priv; 1697 return wpa_driver_wext_get_bssid(drv->wext, bssid); 1698} 1699 1700 1701static int wpa_driver_madwifi_get_ssid(void *priv, u8 *ssid) 1702{ 1703 struct wpa_driver_madwifi_data *drv = priv; 1704 return wpa_driver_wext_get_ssid(drv->wext, ssid); 1705} 1706 1707 1708static struct wpa_scan_results * 1709wpa_driver_madwifi_get_scan_results(void *priv) 1710{ 1711 struct wpa_driver_madwifi_data *drv = priv; 1712 return wpa_driver_wext_get_scan_results(drv->wext); 1713} 1714 1715 1716static int wpa_driver_madwifi_set_operstate(void *priv, int state) 1717{ 1718 struct wpa_driver_madwifi_data *drv = priv; 1719 return wpa_driver_wext_set_operstate(drv->wext, state); 1720} 1721 1722 1723static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies, 1724 size_t ies_len) 1725{ 1726 struct ieee80211req_getset_appiebuf *probe_req_ie; 1727 int ret; 1728 1729 probe_req_ie = os_malloc(sizeof(*probe_req_ie) + ies_len); 1730 if (probe_req_ie == NULL) 1731 return -1; 1732 1733 probe_req_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_REQ; 1734 probe_req_ie->app_buflen = ies_len; 1735 os_memcpy(probe_req_ie->app_buf, ies, ies_len); 1736 1737 ret = set80211priv(priv, IEEE80211_IOCTL_SET_APPIEBUF, probe_req_ie, 1738 sizeof(struct ieee80211req_getset_appiebuf) + 1739 ies_len, 1); 1740 1741 os_free(probe_req_ie); 1742 1743 return ret; 1744} 1745 1746 1747static void * wpa_driver_madwifi_init(void *ctx, const char *ifname) 1748{ 1749 struct wpa_driver_madwifi_data *drv; 1750 1751 drv = os_zalloc(sizeof(*drv)); 1752 if (drv == NULL) 1753 return NULL; 1754 drv->wext = wpa_driver_wext_init(ctx, ifname); 1755 if (drv->wext == NULL) 1756 goto fail; 1757 1758 drv->ctx = ctx; 1759 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 1760 drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 1761 if (drv->sock < 0) 1762 goto fail2; 1763 1764 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) { 1765 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " 1766 "roaming", __FUNCTION__); 1767 goto fail3; 1768 } 1769 1770 if (set80211param(drv, IEEE80211_PARAM_WPA, 3, 1) < 0) { 1771 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support", 1772 __FUNCTION__); 1773 goto fail3; 1774 } 1775 1776 return drv; 1777 1778fail3: 1779 close(drv->sock); 1780fail2: 1781 wpa_driver_wext_deinit(drv->wext); 1782fail: 1783 os_free(drv); 1784 return NULL; 1785} 1786 1787 1788static void wpa_driver_madwifi_deinit(void *priv) 1789{ 1790 struct wpa_driver_madwifi_data *drv = priv; 1791 1792 if (wpa_driver_madwifi_set_wpa_ie(drv, NULL, 0) < 0) { 1793 wpa_printf(MSG_DEBUG, "%s: failed to clear WPA IE", 1794 __FUNCTION__); 1795 } 1796 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) { 1797 wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based " 1798 "roaming", __FUNCTION__); 1799 } 1800 if (set80211param(drv, IEEE80211_PARAM_PRIVACY, 0, 1) < 0) { 1801 wpa_printf(MSG_DEBUG, "%s: failed to disable forced Privacy " 1802 "flag", __FUNCTION__); 1803 } 1804 if (set80211param(drv, IEEE80211_PARAM_WPA, 0, 1) < 0) { 1805 wpa_printf(MSG_DEBUG, "%s: failed to disable WPA", 1806 __FUNCTION__); 1807 } 1808 1809 wpa_driver_wext_deinit(drv->wext); 1810 1811 close(drv->sock); 1812 os_free(drv); 1813} 1814 1815#endif /* HOSTAPD */ 1816 1817 1818const struct wpa_driver_ops wpa_driver_madwifi_ops = { 1819 .name = "madwifi", 1820 .desc = "MADWIFI 802.11 support (Atheros, etc.)", 1821 .set_key = wpa_driver_madwifi_set_key, 1822#ifdef HOSTAPD 1823 .hapd_init = madwifi_init, 1824 .hapd_deinit = madwifi_deinit, 1825 .set_ieee8021x = madwifi_set_ieee8021x, 1826 .set_privacy = madwifi_set_privacy, 1827 .get_seqnum = madwifi_get_seqnum, 1828 .flush = madwifi_flush, 1829 .set_generic_elem = madwifi_set_opt_ie, 1830 .sta_set_flags = madwifi_sta_set_flags, 1831 .read_sta_data = madwifi_read_sta_driver_data, 1832 .hapd_send_eapol = madwifi_send_eapol, 1833 .sta_disassoc = madwifi_sta_disassoc, 1834 .sta_deauth = madwifi_sta_deauth, 1835 .hapd_set_ssid = madwifi_set_ssid, 1836 .hapd_get_ssid = madwifi_get_ssid, 1837 .hapd_set_countermeasures = madwifi_set_countermeasures, 1838 .sta_clear_stats = madwifi_sta_clear_stats, 1839 .commit = madwifi_commit, 1840 .set_ap_wps_ie = madwifi_set_ap_wps_ie, 1841#else /* HOSTAPD */ 1842 .get_bssid = wpa_driver_madwifi_get_bssid, 1843 .get_ssid = wpa_driver_madwifi_get_ssid, 1844 .init = wpa_driver_madwifi_init, 1845 .deinit = wpa_driver_madwifi_deinit, 1846 .set_countermeasures = wpa_driver_madwifi_set_countermeasures, 1847 .scan2 = wpa_driver_madwifi_scan, 1848 .get_scan_results2 = wpa_driver_madwifi_get_scan_results, 1849 .deauthenticate = wpa_driver_madwifi_deauthenticate, 1850 .disassociate = wpa_driver_madwifi_disassociate, 1851 .associate = wpa_driver_madwifi_associate, 1852 .set_operstate = wpa_driver_madwifi_set_operstate, 1853#endif /* HOSTAPD */ 1854}; 1855