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