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