00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023 #include <sys/ioctl.h>
00024
00025 #include "common.h"
00026 #include "driver.h"
00027 #include "driver_wext.h"
00028 #include "eloop.h"
00029 #include "common/ieee802_11_defs.h"
00030 #include "wireless_copy.h"
00031
00032
00033
00034
00035 #undef WME_OUI_TYPE
00036
00037 #include <include/compat.h>
00038 #include <net80211/ieee80211.h>
00039 #ifdef WME_NUM_AC
00040
00041 #define MADWIFI_BSD
00042 #include <net80211/_ieee80211.h>
00043 #endif
00044 #include <net80211/ieee80211_crypto.h>
00045 #include <net80211/ieee80211_ioctl.h>
00046
00047 #ifdef CONFIG_WPS
00048 #ifdef IEEE80211_IOCTL_FILTERFRAME
00049 #include <netpacket/packet.h>
00050
00051 #ifndef ETH_P_80211_RAW
00052 #define ETH_P_80211_RAW 0x0019
00053 #endif
00054 #endif
00055 #endif
00056
00057
00058
00059
00060
00061 #undef RSN_VERSION
00062 #undef WPA_VERSION
00063 #undef WPA_OUI_TYPE
00064 #undef WME_OUI_TYPE
00065
00066
00067 #ifdef IEEE80211_IOCTL_SETWMMPARAMS
00068
00069 #define MADWIFI_NG
00070 #endif
00071
00072
00073 #ifdef HOSTAPD
00074
00075 #include "priv_netlink.h"
00076 #include "netlink.h"
00077 #include "linux_ioctl.h"
00078 #include "l2_packet/l2_packet.h"
00079
00080
00081 struct madwifi_driver_data {
00082 struct hostapd_data *hapd;
00083
00084 char iface[IFNAMSIZ + 1];
00085 int ifindex;
00086 struct l2_packet_data *sock_xmit;
00087 struct l2_packet_data *sock_recv;
00088 int ioctl_sock;
00089 struct netlink_data *netlink;
00090 int we_version;
00091 u8 acct_mac[ETH_ALEN];
00092 struct hostap_sta_driver_data acct_data;
00093
00094 struct l2_packet_data *sock_raw;
00095 };
00096
00097 static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
00098 int reason_code);
00099
00100 static int
00101 set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
00102 {
00103 struct iwreq iwr;
00104 int do_inline = len < IFNAMSIZ;
00105
00106 memset(&iwr, 0, sizeof(iwr));
00107 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
00108 #ifdef IEEE80211_IOCTL_FILTERFRAME
00109
00110 if (op == IEEE80211_IOCTL_FILTERFRAME)
00111 do_inline = 0;
00112 #endif
00113 if (op == IEEE80211_IOCTL_SET_APPIEBUF)
00114 do_inline = 0;
00115 if (do_inline) {
00116
00117
00118
00119 memcpy(iwr.u.name, data, len);
00120 } else {
00121
00122
00123
00124
00125
00126 iwr.u.data.pointer = data;
00127 iwr.u.data.length = len;
00128 }
00129
00130 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
00131 #ifdef MADWIFI_NG
00132 int first = IEEE80211_IOCTL_SETPARAM;
00133 static const char *opnames[] = {
00134 "ioctl[IEEE80211_IOCTL_SETPARAM]",
00135 "ioctl[IEEE80211_IOCTL_GETPARAM]",
00136 "ioctl[IEEE80211_IOCTL_SETMODE]",
00137 "ioctl[IEEE80211_IOCTL_GETMODE]",
00138 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
00139 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
00140 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
00141 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
00142 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
00143 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
00144 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
00145 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
00146 "ioctl[IEEE80211_IOCTL_FILTERFRAME]",
00147 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
00148 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
00149 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
00150 "ioctl[IEEE80211_IOCTL_SETMLME]",
00151 NULL,
00152 "ioctl[IEEE80211_IOCTL_SETKEY]",
00153 NULL,
00154 "ioctl[IEEE80211_IOCTL_DELKEY]",
00155 NULL,
00156 "ioctl[IEEE80211_IOCTL_ADDMAC]",
00157 NULL,
00158 "ioctl[IEEE80211_IOCTL_DELMAC]",
00159 NULL,
00160 "ioctl[IEEE80211_IOCTL_WDSMAC]",
00161 NULL,
00162 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
00163 NULL,
00164 "ioctl[IEEE80211_IOCTL_KICKMAC]",
00165 };
00166 #else
00167 int first = IEEE80211_IOCTL_SETPARAM;
00168 static const char *opnames[] = {
00169 "ioctl[IEEE80211_IOCTL_SETPARAM]",
00170 "ioctl[IEEE80211_IOCTL_GETPARAM]",
00171 "ioctl[IEEE80211_IOCTL_SETKEY]",
00172 "ioctl[SIOCIWFIRSTPRIV+3]",
00173 "ioctl[IEEE80211_IOCTL_DELKEY]",
00174 "ioctl[SIOCIWFIRSTPRIV+5]",
00175 "ioctl[IEEE80211_IOCTL_SETMLME]",
00176 "ioctl[SIOCIWFIRSTPRIV+7]",
00177 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
00178 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
00179 "ioctl[IEEE80211_IOCTL_ADDMAC]",
00180 "ioctl[SIOCIWFIRSTPRIV+11]",
00181 "ioctl[IEEE80211_IOCTL_DELMAC]",
00182 "ioctl[SIOCIWFIRSTPRIV+13]",
00183 "ioctl[IEEE80211_IOCTL_CHANLIST]",
00184 "ioctl[SIOCIWFIRSTPRIV+15]",
00185 "ioctl[IEEE80211_IOCTL_GETRSN]",
00186 "ioctl[SIOCIWFIRSTPRIV+17]",
00187 "ioctl[IEEE80211_IOCTL_GETKEY]",
00188 };
00189 #endif
00190 int idx = op - first;
00191 if (first <= op &&
00192 idx < (int) (sizeof(opnames) / sizeof(opnames[0])) &&
00193 opnames[idx])
00194 perror(opnames[idx]);
00195 else
00196 perror("ioctl[unknown???]");
00197 return -1;
00198 }
00199 return 0;
00200 }
00201
00202 static int
00203 set80211param(struct madwifi_driver_data *drv, int op, int arg)
00204 {
00205 struct iwreq iwr;
00206
00207 memset(&iwr, 0, sizeof(iwr));
00208 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
00209 iwr.u.mode = op;
00210 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
00211
00212 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
00213 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
00214 wpa_printf(MSG_DEBUG, "%s: Failed to set parameter (op %d "
00215 "arg %d)", __func__, op, arg);
00216 return -1;
00217 }
00218 return 0;
00219 }
00220
00221 #ifndef CONFIG_NO_STDOUT_DEBUG
00222 static const char *
00223 ether_sprintf(const u8 *addr)
00224 {
00225 static char buf[sizeof(MACSTR)];
00226
00227 if (addr != NULL)
00228 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
00229 else
00230 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
00231 return buf;
00232 }
00233 #endif
00234
00235
00236
00237
00238 static int
00239 madwifi_configure_wpa(struct madwifi_driver_data *drv,
00240 struct wpa_bss_params *params)
00241 {
00242 int v;
00243
00244 switch (params->wpa_group) {
00245 case WPA_CIPHER_CCMP:
00246 v = IEEE80211_CIPHER_AES_CCM;
00247 break;
00248 case WPA_CIPHER_TKIP:
00249 v = IEEE80211_CIPHER_TKIP;
00250 break;
00251 case WPA_CIPHER_WEP104:
00252 v = IEEE80211_CIPHER_WEP;
00253 break;
00254 case WPA_CIPHER_WEP40:
00255 v = IEEE80211_CIPHER_WEP;
00256 break;
00257 case WPA_CIPHER_NONE:
00258 v = IEEE80211_CIPHER_NONE;
00259 break;
00260 default:
00261 wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
00262 params->wpa_group);
00263 return -1;
00264 }
00265 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
00266 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) {
00267 printf("Unable to set group key cipher to %u\n", v);
00268 return -1;
00269 }
00270 if (v == IEEE80211_CIPHER_WEP) {
00271
00272 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
00273 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
00274 printf("Unable to set group key length to %u\n", v);
00275 return -1;
00276 }
00277 }
00278
00279 v = 0;
00280 if (params->wpa_pairwise & WPA_CIPHER_CCMP)
00281 v |= 1<<IEEE80211_CIPHER_AES_CCM;
00282 if (params->wpa_pairwise & WPA_CIPHER_TKIP)
00283 v |= 1<<IEEE80211_CIPHER_TKIP;
00284 if (params->wpa_pairwise & WPA_CIPHER_NONE)
00285 v |= 1<<IEEE80211_CIPHER_NONE;
00286 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
00287 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
00288 printf("Unable to set pairwise key ciphers to 0x%x\n", v);
00289 return -1;
00290 }
00291
00292 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
00293 __func__, params->wpa_key_mgmt);
00294 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
00295 params->wpa_key_mgmt)) {
00296 printf("Unable to set key management algorithms to 0x%x\n",
00297 params->wpa_key_mgmt);
00298 return -1;
00299 }
00300
00301 v = 0;
00302 if (params->rsn_preauth)
00303 v |= BIT(0);
00304 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
00305 __func__, params->rsn_preauth);
00306 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
00307 printf("Unable to set RSN capabilities to 0x%x\n", v);
00308 return -1;
00309 }
00310
00311 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
00312 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
00313 printf("Unable to set WPA to %u\n", params->wpa);
00314 return -1;
00315 }
00316 return 0;
00317 }
00318
00319 static int
00320 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
00321 {
00322 struct madwifi_driver_data *drv = priv;
00323
00324 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
00325
00326 if (!params->enabled) {
00327
00328 return set80211param(priv, IEEE80211_PARAM_AUTHMODE,
00329 IEEE80211_AUTH_AUTO);
00330 }
00331 if (!params->wpa && !params->ieee802_1x) {
00332 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00333 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
00334 return -1;
00335 }
00336 if (params->wpa && madwifi_configure_wpa(drv, params) != 0) {
00337 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00338 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
00339 return -1;
00340 }
00341 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
00342 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
00343 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00344 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
00345 return -1;
00346 }
00347
00348 return 0;
00349 }
00350
00351 static int
00352 madwifi_set_privacy(void *priv, int enabled)
00353 {
00354 struct madwifi_driver_data *drv = priv;
00355
00356 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
00357
00358 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
00359 }
00360
00361 static int
00362 madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized)
00363 {
00364 struct madwifi_driver_data *drv = priv;
00365 struct ieee80211req_mlme mlme;
00366 int ret;
00367
00368 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
00369 __func__, ether_sprintf(addr), authorized);
00370
00371 if (authorized)
00372 mlme.im_op = IEEE80211_MLME_AUTHORIZE;
00373 else
00374 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
00375 mlme.im_reason = 0;
00376 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00377 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00378 if (ret < 0) {
00379 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
00380 __func__, authorized ? "" : "un", MAC2STR(addr));
00381 }
00382
00383 return ret;
00384 }
00385
00386 static int
00387 madwifi_sta_set_flags(void *priv, const u8 *addr,
00388 int total_flags, int flags_or, int flags_and)
00389 {
00390
00391 if (flags_or & WPA_STA_AUTHORIZED)
00392 return madwifi_set_sta_authorized(priv, addr, 1);
00393 if (!(flags_and & WPA_STA_AUTHORIZED))
00394 return madwifi_set_sta_authorized(priv, addr, 0);
00395 return 0;
00396 }
00397
00398 static int
00399 madwifi_del_key(void *priv, const u8 *addr, int key_idx)
00400 {
00401 struct madwifi_driver_data *drv = priv;
00402 struct ieee80211req_del_key wk;
00403 int ret;
00404
00405 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
00406 __func__, ether_sprintf(addr), key_idx);
00407
00408 memset(&wk, 0, sizeof(wk));
00409 if (addr != NULL) {
00410 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
00411 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE;
00412 } else {
00413 wk.idk_keyix = key_idx;
00414 }
00415
00416 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
00417 if (ret < 0) {
00418 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
00419 " key_idx %d)", __func__, ether_sprintf(addr),
00420 key_idx);
00421 }
00422
00423 return ret;
00424 }
00425
00426 static int
00427 wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
00428 const u8 *addr, int key_idx, int set_tx,
00429 const u8 *seq, size_t seq_len,
00430 const u8 *key, size_t key_len)
00431 {
00432 struct madwifi_driver_data *drv = priv;
00433 struct ieee80211req_key wk;
00434 u_int8_t cipher;
00435 int ret;
00436
00437 if (alg == WPA_ALG_NONE)
00438 return madwifi_del_key(drv, addr, key_idx);
00439
00440 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
00441 __func__, alg, ether_sprintf(addr), key_idx);
00442
00443 if (alg == WPA_ALG_WEP)
00444 cipher = IEEE80211_CIPHER_WEP;
00445 else if (alg == WPA_ALG_TKIP)
00446 cipher = IEEE80211_CIPHER_TKIP;
00447 else if (alg == WPA_ALG_CCMP)
00448 cipher = IEEE80211_CIPHER_AES_CCM;
00449 else {
00450 printf("%s: unknown/unsupported algorithm %d\n",
00451 __func__, alg);
00452 return -1;
00453 }
00454
00455 if (key_len > sizeof(wk.ik_keydata)) {
00456 printf("%s: key length %lu too big\n", __func__,
00457 (unsigned long) key_len);
00458 return -3;
00459 }
00460
00461 memset(&wk, 0, sizeof(wk));
00462 wk.ik_type = cipher;
00463 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
00464 if (addr == NULL) {
00465 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
00466 wk.ik_keyix = key_idx;
00467 wk.ik_flags |= IEEE80211_KEY_DEFAULT;
00468 } else {
00469 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
00470 wk.ik_keyix = IEEE80211_KEYIX_NONE;
00471 }
00472 wk.ik_keylen = key_len;
00473 memcpy(wk.ik_keydata, key, key_len);
00474
00475 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
00476 if (ret < 0) {
00477 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
00478 " key_idx %d alg %d key_len %lu set_tx %d)",
00479 __func__, ether_sprintf(wk.ik_macaddr), key_idx,
00480 alg, (unsigned long) key_len, set_tx);
00481 }
00482
00483 return ret;
00484 }
00485
00486
00487 static int
00488 madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
00489 u8 *seq)
00490 {
00491 struct madwifi_driver_data *drv = priv;
00492 struct ieee80211req_key wk;
00493
00494 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
00495 __func__, ether_sprintf(addr), idx);
00496
00497 memset(&wk, 0, sizeof(wk));
00498 if (addr == NULL)
00499 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
00500 else
00501 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
00502 wk.ik_keyix = idx;
00503
00504 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
00505 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
00506 "(addr " MACSTR " key_idx %d)",
00507 __func__, MAC2STR(wk.ik_macaddr), idx);
00508 return -1;
00509 }
00510
00511 #ifdef WORDS_BIGENDIAN
00512 {
00513
00514
00515
00516
00517 int i;
00518 u8 tmp[WPA_KEY_RSC_LEN];
00519 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
00520 for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
00521 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
00522 }
00523 }
00524 #else
00525 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
00526 #endif
00527 return 0;
00528 }
00529
00530
00531 static int
00532 madwifi_flush(void *priv)
00533 {
00534 #ifdef MADWIFI_BSD
00535 u8 allsta[IEEE80211_ADDR_LEN];
00536 memset(allsta, 0xff, IEEE80211_ADDR_LEN);
00537 return madwifi_sta_deauth(priv, NULL, allsta,
00538 IEEE80211_REASON_AUTH_LEAVE);
00539 #else
00540 return 0;
00541 #endif
00542 }
00543
00544
00545 static int
00546 madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
00547 const u8 *addr)
00548 {
00549 struct madwifi_driver_data *drv = priv;
00550
00551 #ifdef MADWIFI_BSD
00552 struct ieee80211req_sta_stats stats;
00553
00554 memset(data, 0, sizeof(*data));
00555
00556
00557
00558
00559 memset(&stats, 0, sizeof(stats));
00560 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
00561 if (set80211priv(drv,
00562 #ifdef MADWIFI_NG
00563 IEEE80211_IOCTL_STA_STATS,
00564 #else
00565 IEEE80211_IOCTL_GETSTASTATS,
00566 #endif
00567 &stats, sizeof(stats))) {
00568 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
00569 MACSTR ")", __func__, MAC2STR(addr));
00570 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
00571 memcpy(data, &drv->acct_data, sizeof(*data));
00572 return 0;
00573 }
00574
00575 printf("Failed to get station stats information element.\n");
00576 return -1;
00577 }
00578
00579 data->rx_packets = stats.is_stats.ns_rx_data;
00580 data->rx_bytes = stats.is_stats.ns_rx_bytes;
00581 data->tx_packets = stats.is_stats.ns_tx_data;
00582 data->tx_bytes = stats.is_stats.ns_tx_bytes;
00583 return 0;
00584
00585 #else
00586
00587 char buf[1024], line[128], *pos;
00588 FILE *f;
00589 unsigned long val;
00590
00591 memset(data, 0, sizeof(*data));
00592 snprintf(buf, sizeof(buf), "/proc/net/madwifi/%s/" MACSTR,
00593 drv->iface, MAC2STR(addr));
00594
00595 f = fopen(buf, "r");
00596 if (!f) {
00597 if (memcmp(addr, drv->acct_mac, ETH_ALEN) != 0)
00598 return -1;
00599 memcpy(data, &drv->acct_data, sizeof(*data));
00600 return 0;
00601 }
00602
00603
00604 setbuffer(f, buf, sizeof(buf));
00605
00606 while (fgets(line, sizeof(line), f)) {
00607 pos = strchr(line, '=');
00608 if (!pos)
00609 continue;
00610 *pos++ = '\0';
00611 val = strtoul(pos, NULL, 10);
00612 if (strcmp(line, "rx_packets") == 0)
00613 data->rx_packets = val;
00614 else if (strcmp(line, "tx_packets") == 0)
00615 data->tx_packets = val;
00616 else if (strcmp(line, "rx_bytes") == 0)
00617 data->rx_bytes = val;
00618 else if (strcmp(line, "tx_bytes") == 0)
00619 data->tx_bytes = val;
00620 }
00621
00622 fclose(f);
00623
00624 return 0;
00625 #endif
00626 }
00627
00628
00629 static int
00630 madwifi_sta_clear_stats(void *priv, const u8 *addr)
00631 {
00632 #if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)
00633 struct madwifi_driver_data *drv = priv;
00634 struct ieee80211req_mlme mlme;
00635 int ret;
00636
00637 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));
00638
00639 mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
00640 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00641 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
00642 sizeof(mlme));
00643 if (ret < 0) {
00644 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
00645 MACSTR ")", __func__, MAC2STR(addr));
00646 }
00647
00648 return ret;
00649 #else
00650 return 0;
00651 #endif
00652 }
00653
00654
00655 static int
00656 madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
00657 {
00658
00659
00660
00661
00662 return 0;
00663 }
00664
00665 static int
00666 madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
00667 int reason_code)
00668 {
00669 struct madwifi_driver_data *drv = priv;
00670 struct ieee80211req_mlme mlme;
00671 int ret;
00672
00673 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
00674 __func__, ether_sprintf(addr), reason_code);
00675
00676 mlme.im_op = IEEE80211_MLME_DEAUTH;
00677 mlme.im_reason = reason_code;
00678 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00679 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00680 if (ret < 0) {
00681 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
00682 " reason %d)",
00683 __func__, MAC2STR(addr), reason_code);
00684 }
00685
00686 return ret;
00687 }
00688
00689 static int
00690 madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
00691 int reason_code)
00692 {
00693 struct madwifi_driver_data *drv = priv;
00694 struct ieee80211req_mlme mlme;
00695 int ret;
00696
00697 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
00698 __func__, ether_sprintf(addr), reason_code);
00699
00700 mlme.im_op = IEEE80211_MLME_DISASSOC;
00701 mlme.im_reason = reason_code;
00702 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00703 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00704 if (ret < 0) {
00705 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
00706 MACSTR " reason %d)",
00707 __func__, MAC2STR(addr), reason_code);
00708 }
00709
00710 return ret;
00711 }
00712
00713 #ifdef CONFIG_WPS
00714 #ifdef IEEE80211_IOCTL_FILTERFRAME
00715 static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
00716 size_t len)
00717 {
00718 struct madwifi_driver_data *drv = ctx;
00719 const struct ieee80211_mgmt *mgmt;
00720 u16 fc;
00721 union wpa_event_data event;
00722
00723
00724
00725 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
00726 return;
00727 mgmt = (const struct ieee80211_mgmt *) buf;
00728
00729 fc = le_to_host16(mgmt->frame_control);
00730 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
00731 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
00732 return;
00733
00734 os_memset(&event, 0, sizeof(event));
00735 event.rx_probe_req.sa = mgmt->sa;
00736 event.rx_probe_req.ie = mgmt->u.probe_req.variable;
00737 event.rx_probe_req.ie_len =
00738 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
00739 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
00740 }
00741 #endif
00742 #endif
00743
00744 static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
00745 {
00746 int ret = 0;
00747 #ifdef CONFIG_WPS
00748 #ifdef IEEE80211_IOCTL_FILTERFRAME
00749 struct ieee80211req_set_filter filt;
00750
00751 wpa_printf(MSG_DEBUG, "%s Enter", __func__);
00752 filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
00753
00754 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
00755 sizeof(struct ieee80211req_set_filter));
00756 if (ret)
00757 return ret;
00758
00759 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
00760 madwifi_raw_receive, drv, 1);
00761 if (drv->sock_raw == NULL)
00762 return -1;
00763 #endif
00764 #endif
00765 return ret;
00766 }
00767
00768 #ifdef CONFIG_WPS
00769 static int
00770 madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
00771 {
00772 struct madwifi_driver_data *drv = priv;
00773 u8 buf[256];
00774 struct ieee80211req_getset_appiebuf *beac_ie;
00775
00776 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
00777 (unsigned long) len);
00778
00779 beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
00780 beac_ie->app_frmtype = frametype;
00781 beac_ie->app_buflen = len;
00782 memcpy(&(beac_ie->app_buf[0]), ie, len);
00783
00784 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
00785 sizeof(struct ieee80211req_getset_appiebuf) + len);
00786 }
00787
00788 static int
00789 madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
00790 const struct wpabuf *proberesp)
00791 {
00792 if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
00793 beacon ? wpabuf_len(beacon) : 0,
00794 IEEE80211_APPIE_FRAME_BEACON) < 0)
00795 return -1;
00796 return madwifi_set_wps_ie(priv,
00797 proberesp ? wpabuf_head(proberesp) : NULL,
00798 proberesp ? wpabuf_len(proberesp) : 0,
00799 IEEE80211_APPIE_FRAME_PROBE_RESP);
00800 }
00801 #else
00802 #define madwifi_set_ap_wps_ie NULL
00803 #endif
00804
00805 static void
00806 madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
00807 {
00808 struct hostapd_data *hapd = drv->hapd;
00809 struct ieee80211req_wpaie ie;
00810 int ielen = 0;
00811 u8 *iebuf = NULL;
00812
00813
00814
00815
00816 memset(&ie, 0, sizeof(ie));
00817 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
00818 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
00819 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE",
00820 __func__);
00821 goto no_ie;
00822 }
00823 wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
00824 ie.wpa_ie, IEEE80211_MAX_OPT_IE);
00825 iebuf = ie.wpa_ie;
00826
00827
00828 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
00829 iebuf[1] = 0;
00830 #ifdef MADWIFI_NG
00831 wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
00832 ie.rsn_ie, IEEE80211_MAX_OPT_IE);
00833 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
00834
00835
00836 iebuf = ie.rsn_ie;
00837 if (iebuf[0] != WLAN_EID_RSN)
00838 iebuf[1] = 0;
00839 }
00840 #endif
00841
00842 ielen = iebuf[1];
00843 if (ielen == 0)
00844 iebuf = NULL;
00845 else
00846 ielen += 2;
00847
00848 no_ie:
00849 drv_event_assoc(hapd, addr, iebuf, ielen);
00850
00851 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
00852
00853 memset(drv->acct_mac, 0, ETH_ALEN);
00854 memset(&drv->acct_data, 0, sizeof(drv->acct_data));
00855 }
00856 }
00857
00858 static void
00859 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
00860 char *custom)
00861 {
00862 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
00863
00864 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
00865 char *pos;
00866 u8 addr[ETH_ALEN];
00867 pos = strstr(custom, "addr=");
00868 if (pos == NULL) {
00869 wpa_printf(MSG_DEBUG,
00870 "MLME-MICHAELMICFAILURE.indication "
00871 "without sender address ignored");
00872 return;
00873 }
00874 pos += 5;
00875 if (hwaddr_aton(pos, addr) == 0) {
00876 union wpa_event_data data;
00877 os_memset(&data, 0, sizeof(data));
00878 data.michael_mic_failure.unicast = 1;
00879 data.michael_mic_failure.src = addr;
00880 wpa_supplicant_event(drv->hapd,
00881 EVENT_MICHAEL_MIC_FAILURE, &data);
00882 } else {
00883 wpa_printf(MSG_DEBUG,
00884 "MLME-MICHAELMICFAILURE.indication "
00885 "with invalid MAC address");
00886 }
00887 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
00888 char *key, *value;
00889 u32 val;
00890 key = custom;
00891 while ((key = strchr(key, '\n')) != NULL) {
00892 key++;
00893 value = strchr(key, '=');
00894 if (value == NULL)
00895 continue;
00896 *value++ = '\0';
00897 val = strtoul(value, NULL, 10);
00898 if (strcmp(key, "mac") == 0)
00899 hwaddr_aton(value, drv->acct_mac);
00900 else if (strcmp(key, "rx_packets") == 0)
00901 drv->acct_data.rx_packets = val;
00902 else if (strcmp(key, "tx_packets") == 0)
00903 drv->acct_data.tx_packets = val;
00904 else if (strcmp(key, "rx_bytes") == 0)
00905 drv->acct_data.rx_bytes = val;
00906 else if (strcmp(key, "tx_bytes") == 0)
00907 drv->acct_data.tx_bytes = val;
00908 key = value;
00909 }
00910 }
00911 }
00912
00913 static void
00914 madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
00915 char *data, int len)
00916 {
00917 struct iw_event iwe_buf, *iwe = &iwe_buf;
00918 char *pos, *end, *custom, *buf;
00919
00920 pos = data;
00921 end = data + len;
00922
00923 while (pos + IW_EV_LCP_LEN <= end) {
00924
00925
00926 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
00927 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
00928 iwe->cmd, iwe->len);
00929 if (iwe->len <= IW_EV_LCP_LEN)
00930 return;
00931
00932 custom = pos + IW_EV_POINT_LEN;
00933 if (drv->we_version > 18 &&
00934 (iwe->cmd == IWEVMICHAELMICFAILURE ||
00935 iwe->cmd == IWEVCUSTOM)) {
00936
00937 char *dpos = (char *) &iwe_buf.u.data.length;
00938 int dlen = dpos - (char *) &iwe_buf;
00939 memcpy(dpos, pos + IW_EV_LCP_LEN,
00940 sizeof(struct iw_event) - dlen);
00941 } else {
00942 memcpy(&iwe_buf, pos, sizeof(struct iw_event));
00943 custom += IW_EV_POINT_OFF;
00944 }
00945
00946 switch (iwe->cmd) {
00947 case IWEVEXPIRED:
00948 drv_event_disassoc(drv->hapd,
00949 (u8 *) iwe->u.addr.sa_data);
00950 break;
00951 case IWEVREGISTERED:
00952 madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
00953 break;
00954 case IWEVCUSTOM:
00955 if (custom + iwe->u.data.length > end)
00956 return;
00957 buf = malloc(iwe->u.data.length + 1);
00958 if (buf == NULL)
00959 return;
00960 memcpy(buf, custom, iwe->u.data.length);
00961 buf[iwe->u.data.length] = '\0';
00962 madwifi_wireless_event_wireless_custom(drv, buf);
00963 free(buf);
00964 break;
00965 }
00966
00967 pos += iwe->len;
00968 }
00969 }
00970
00971
00972 static void
00973 madwifi_wireless_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi,
00974 u8 *buf, size_t len)
00975 {
00976 struct madwifi_driver_data *drv = ctx;
00977 int attrlen, rta_len;
00978 struct rtattr *attr;
00979
00980 if (ifi->ifi_index != drv->ifindex)
00981 return;
00982
00983 attrlen = len;
00984 attr = (struct rtattr *) buf;
00985
00986 rta_len = RTA_ALIGN(sizeof(struct rtattr));
00987 while (RTA_OK(attr, attrlen)) {
00988 if (attr->rta_type == IFLA_WIRELESS) {
00989 madwifi_wireless_event_wireless(
00990 drv, ((char *) attr) + rta_len,
00991 attr->rta_len - rta_len);
00992 }
00993 attr = RTA_NEXT(attr, attrlen);
00994 }
00995 }
00996
00997
00998 static int
00999 madwifi_get_we_version(struct madwifi_driver_data *drv)
01000 {
01001 struct iw_range *range;
01002 struct iwreq iwr;
01003 int minlen;
01004 size_t buflen;
01005
01006 drv->we_version = 0;
01007
01008
01009
01010
01011
01012 buflen = sizeof(struct iw_range) + 500;
01013 range = os_zalloc(buflen);
01014 if (range == NULL)
01015 return -1;
01016
01017 memset(&iwr, 0, sizeof(iwr));
01018 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01019 iwr.u.data.pointer = (caddr_t) range;
01020 iwr.u.data.length = buflen;
01021
01022 minlen = ((char *) &range->enc_capa) - (char *) range +
01023 sizeof(range->enc_capa);
01024
01025 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
01026 perror("ioctl[SIOCGIWRANGE]");
01027 free(range);
01028 return -1;
01029 } else if (iwr.u.data.length >= minlen &&
01030 range->we_version_compiled >= 18) {
01031 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
01032 "WE(source)=%d enc_capa=0x%x",
01033 range->we_version_compiled,
01034 range->we_version_source,
01035 range->enc_capa);
01036 drv->we_version = range->we_version_compiled;
01037 }
01038
01039 free(range);
01040 return 0;
01041 }
01042
01043
01044 static int
01045 madwifi_wireless_event_init(struct madwifi_driver_data *drv)
01046 {
01047 struct netlink_config *cfg;
01048
01049 madwifi_get_we_version(drv);
01050
01051 cfg = os_zalloc(sizeof(*cfg));
01052 if (cfg == NULL)
01053 return -1;
01054 cfg->ctx = drv;
01055 cfg->newlink_cb = madwifi_wireless_event_rtm_newlink;
01056 drv->netlink = netlink_init(cfg);
01057 if (drv->netlink == NULL) {
01058 os_free(cfg);
01059 return -1;
01060 }
01061
01062 return 0;
01063 }
01064
01065
01066 static int
01067 madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
01068 int encrypt, const u8 *own_addr)
01069 {
01070 struct madwifi_driver_data *drv = priv;
01071 unsigned char buf[3000];
01072 unsigned char *bp = buf;
01073 struct l2_ethhdr *eth;
01074 size_t len;
01075 int status;
01076
01077
01078
01079
01080
01081
01082
01083 len = data_len + sizeof(struct l2_ethhdr);
01084 if (len > sizeof(buf)) {
01085 bp = malloc(len);
01086 if (bp == NULL) {
01087 printf("EAPOL frame discarded, cannot malloc temp "
01088 "buffer of size %lu!\n", (unsigned long) len);
01089 return -1;
01090 }
01091 }
01092 eth = (struct l2_ethhdr *) bp;
01093 memcpy(eth->h_dest, addr, ETH_ALEN);
01094 memcpy(eth->h_source, own_addr, ETH_ALEN);
01095 eth->h_proto = host_to_be16(ETH_P_EAPOL);
01096 memcpy(eth+1, data, data_len);
01097
01098 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
01099
01100 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
01101
01102 if (bp != buf)
01103 free(bp);
01104 return status;
01105 }
01106
01107 static void
01108 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
01109 {
01110 struct madwifi_driver_data *drv = ctx;
01111 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
01112 len - sizeof(struct l2_ethhdr));
01113 }
01114
01115 static void *
01116 madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
01117 {
01118 struct madwifi_driver_data *drv;
01119 struct ifreq ifr;
01120 struct iwreq iwr;
01121 char brname[IFNAMSIZ];
01122
01123 drv = os_zalloc(sizeof(struct madwifi_driver_data));
01124 if (drv == NULL) {
01125 printf("Could not allocate memory for madwifi driver data\n");
01126 return NULL;
01127 }
01128
01129 drv->hapd = hapd;
01130 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
01131 if (drv->ioctl_sock < 0) {
01132 perror("socket[PF_INET,SOCK_DGRAM]");
01133 goto bad;
01134 }
01135 memcpy(drv->iface, params->ifname, sizeof(drv->iface));
01136
01137 memset(&ifr, 0, sizeof(ifr));
01138 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
01139 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
01140 perror("ioctl(SIOCGIFINDEX)");
01141 goto bad;
01142 }
01143 drv->ifindex = ifr.ifr_ifindex;
01144
01145 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
01146 handle_read, drv, 1);
01147 if (drv->sock_xmit == NULL)
01148 goto bad;
01149 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
01150 goto bad;
01151 if (params->bridge[0]) {
01152 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
01153 params->bridge[0]);
01154 drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
01155 ETH_P_EAPOL, handle_read, drv,
01156 1);
01157 if (drv->sock_recv == NULL)
01158 goto bad;
01159 } else if (linux_br_get(brname, drv->iface) == 0) {
01160 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
01161 "EAPOL receive", brname);
01162 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
01163 handle_read, drv, 1);
01164 if (drv->sock_recv == NULL)
01165 goto bad;
01166 } else
01167 drv->sock_recv = drv->sock_xmit;
01168
01169 memset(&iwr, 0, sizeof(iwr));
01170 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01171
01172 iwr.u.mode = IW_MODE_MASTER;
01173
01174 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
01175 perror("ioctl[SIOCSIWMODE]");
01176 printf("Could not set interface to master mode!\n");
01177 goto bad;
01178 }
01179
01180
01181 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
01182 madwifi_set_privacy(drv, 0);
01183
01184 madwifi_receive_probe_req(drv);
01185
01186 if (madwifi_wireless_event_init(drv))
01187 goto bad;
01188
01189 return drv;
01190 bad:
01191 if (drv->sock_xmit != NULL)
01192 l2_packet_deinit(drv->sock_xmit);
01193 if (drv->ioctl_sock >= 0)
01194 close(drv->ioctl_sock);
01195 if (drv != NULL)
01196 free(drv);
01197 return NULL;
01198 }
01199
01200
01201 static void
01202 madwifi_deinit(void *priv)
01203 {
01204 struct madwifi_driver_data *drv = priv;
01205
01206 netlink_deinit(drv->netlink);
01207 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
01208 if (drv->ioctl_sock >= 0)
01209 close(drv->ioctl_sock);
01210 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
01211 l2_packet_deinit(drv->sock_recv);
01212 if (drv->sock_xmit != NULL)
01213 l2_packet_deinit(drv->sock_xmit);
01214 if (drv->sock_raw)
01215 l2_packet_deinit(drv->sock_raw);
01216 free(drv);
01217 }
01218
01219 static int
01220 madwifi_set_ssid(void *priv, const u8 *buf, int len)
01221 {
01222 struct madwifi_driver_data *drv = priv;
01223 struct iwreq iwr;
01224
01225 memset(&iwr, 0, sizeof(iwr));
01226 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01227 iwr.u.essid.flags = 1;
01228 iwr.u.essid.pointer = (caddr_t) buf;
01229 iwr.u.essid.length = len + 1;
01230
01231 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
01232 perror("ioctl[SIOCSIWESSID]");
01233 printf("len=%d\n", len);
01234 return -1;
01235 }
01236 return 0;
01237 }
01238
01239 static int
01240 madwifi_get_ssid(void *priv, u8 *buf, int len)
01241 {
01242 struct madwifi_driver_data *drv = priv;
01243 struct iwreq iwr;
01244 int ret = 0;
01245
01246 memset(&iwr, 0, sizeof(iwr));
01247 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01248 iwr.u.essid.pointer = (caddr_t) buf;
01249 iwr.u.essid.length = len;
01250
01251 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
01252 perror("ioctl[SIOCGIWESSID]");
01253 ret = -1;
01254 } else
01255 ret = iwr.u.essid.length;
01256
01257 return ret;
01258 }
01259
01260 static int
01261 madwifi_set_countermeasures(void *priv, int enabled)
01262 {
01263 struct madwifi_driver_data *drv = priv;
01264 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
01265 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
01266 }
01267
01268 static int
01269 madwifi_commit(void *priv)
01270 {
01271 struct madwifi_driver_data *drv = priv;
01272 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
01273 }
01274
01275 #else
01276
01277 struct wpa_driver_madwifi_data {
01278 void *wext;
01279 void *ctx;
01280 char ifname[IFNAMSIZ + 1];
01281 int sock;
01282 };
01283
01284 static int wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg);
01285 static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies,
01286 size_t ies_len);
01287
01288
01289 static int
01290 set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len,
01291 int show_err)
01292 {
01293 struct iwreq iwr;
01294
01295 os_memset(&iwr, 0, sizeof(iwr));
01296 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
01297 if (len < IFNAMSIZ &&
01298 op != IEEE80211_IOCTL_SET_APPIEBUF) {
01299
01300
01301
01302 os_memcpy(iwr.u.name, data, len);
01303 } else {
01304
01305
01306
01307
01308
01309 iwr.u.data.pointer = data;
01310 iwr.u.data.length = len;
01311 }
01312
01313 if (ioctl(drv->sock, op, &iwr) < 0) {
01314 if (show_err) {
01315 #ifdef MADWIFI_NG
01316 int first = IEEE80211_IOCTL_SETPARAM;
01317 int last = IEEE80211_IOCTL_KICKMAC;
01318 static const char *opnames[] = {
01319 "ioctl[IEEE80211_IOCTL_SETPARAM]",
01320 "ioctl[IEEE80211_IOCTL_GETPARAM]",
01321 "ioctl[IEEE80211_IOCTL_SETMODE]",
01322 "ioctl[IEEE80211_IOCTL_GETMODE]",
01323 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
01324 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
01325 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
01326 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
01327 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
01328 NULL,
01329 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
01330 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
01331 NULL,
01332 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
01333 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
01334 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
01335 "ioctl[IEEE80211_IOCTL_SETMLME]",
01336 NULL,
01337 "ioctl[IEEE80211_IOCTL_SETKEY]",
01338 NULL,
01339 "ioctl[IEEE80211_IOCTL_DELKEY]",
01340 NULL,
01341 "ioctl[IEEE80211_IOCTL_ADDMAC]",
01342 NULL,
01343 "ioctl[IEEE80211_IOCTL_DELMAC]",
01344 NULL,
01345 "ioctl[IEEE80211_IOCTL_WDSMAC]",
01346 NULL,
01347 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
01348 NULL,
01349 "ioctl[IEEE80211_IOCTL_KICKMAC]",
01350 };
01351 #else
01352 int first = IEEE80211_IOCTL_SETPARAM;
01353 int last = IEEE80211_IOCTL_CHANLIST;
01354 static const char *opnames[] = {
01355 "ioctl[IEEE80211_IOCTL_SETPARAM]",
01356 "ioctl[IEEE80211_IOCTL_GETPARAM]",
01357 "ioctl[IEEE80211_IOCTL_SETKEY]",
01358 "ioctl[IEEE80211_IOCTL_GETKEY]",
01359 "ioctl[IEEE80211_IOCTL_DELKEY]",
01360 NULL,
01361 "ioctl[IEEE80211_IOCTL_SETMLME]",
01362 NULL,
01363 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
01364 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
01365 "ioctl[IEEE80211_IOCTL_ADDMAC]",
01366 NULL,
01367 "ioctl[IEEE80211_IOCTL_DELMAC]",
01368 NULL,
01369 "ioctl[IEEE80211_IOCTL_CHANLIST]",
01370 };
01371 #endif
01372 int idx = op - first;
01373 if (first <= op && op <= last &&
01374 idx < (int) (sizeof(opnames) / sizeof(opnames[0]))
01375 && opnames[idx])
01376 perror(opnames[idx]);
01377 else
01378 perror("ioctl[unknown???]");
01379 }
01380 return -1;
01381 }
01382 return 0;
01383 }
01384
01385 static int
01386 set80211param(struct wpa_driver_madwifi_data *drv, int op, int arg,
01387 int show_err)
01388 {
01389 struct iwreq iwr;
01390
01391 os_memset(&iwr, 0, sizeof(iwr));
01392 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
01393 iwr.u.mode = op;
01394 os_memcpy(iwr.u.name+sizeof(u32), &arg, sizeof(arg));
01395
01396 if (ioctl(drv->sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
01397 if (show_err)
01398 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
01399 return -1;
01400 }
01401 return 0;
01402 }
01403
01404 static int
01405 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data *drv,
01406 const u8 *wpa_ie, size_t wpa_ie_len)
01407 {
01408 struct iwreq iwr;
01409
01410 os_memset(&iwr, 0, sizeof(iwr));
01411 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
01412
01413 iwr.u.data.pointer = (void *) wpa_ie;
01414 iwr.u.data.length = wpa_ie_len;
01415
01416 if (ioctl(drv->sock, IEEE80211_IOCTL_SETOPTIE, &iwr) < 0) {
01417 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
01418 return -1;
01419 }
01420 return 0;
01421 }
01422
01423 static int
01424 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data *drv, int key_idx,
01425 const u8 *addr)
01426 {
01427 struct ieee80211req_del_key wk;
01428
01429 wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx);
01430 os_memset(&wk, 0, sizeof(wk));
01431 wk.idk_keyix = key_idx;
01432 if (addr != NULL)
01433 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
01434
01435 return set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk), 1);
01436 }
01437
01438 static int
01439 wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
01440 const u8 *addr, int key_idx, int set_tx,
01441 const u8 *seq, size_t seq_len,
01442 const u8 *key, size_t key_len)
01443 {
01444 struct wpa_driver_madwifi_data *drv = priv;
01445 struct ieee80211req_key wk;
01446 char *alg_name;
01447 u_int8_t cipher;
01448
01449 if (alg == WPA_ALG_NONE)
01450 return wpa_driver_madwifi_del_key(drv, key_idx, addr);
01451
01452 switch (alg) {
01453 case WPA_ALG_WEP:
01454 if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
01455 ETH_ALEN) == 0) {
01456
01457
01458
01459
01460
01461 return wpa_driver_wext_set_key(ifname, drv->wext, alg,
01462 addr, key_idx, set_tx,
01463 seq, seq_len,
01464 key, key_len);
01465 }
01466 alg_name = "WEP";
01467 cipher = IEEE80211_CIPHER_WEP;
01468 break;
01469 case WPA_ALG_TKIP:
01470 alg_name = "TKIP";
01471 cipher = IEEE80211_CIPHER_TKIP;
01472 break;
01473 case WPA_ALG_CCMP:
01474 alg_name = "CCMP";
01475 cipher = IEEE80211_CIPHER_AES_CCM;
01476 break;
01477 default:
01478 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
01479 __FUNCTION__, alg);
01480 return -1;
01481 }
01482
01483 wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
01484 "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
01485 (unsigned long) seq_len, (unsigned long) key_len);
01486
01487 if (seq_len > sizeof(u_int64_t)) {
01488 wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big",
01489 __FUNCTION__, (unsigned long) seq_len);
01490 return -2;
01491 }
01492 if (key_len > sizeof(wk.ik_keydata)) {
01493 wpa_printf(MSG_DEBUG, "%s: key length %lu too big",
01494 __FUNCTION__, (unsigned long) key_len);
01495 return -3;
01496 }
01497
01498 os_memset(&wk, 0, sizeof(wk));
01499 wk.ik_type = cipher;
01500 wk.ik_flags = IEEE80211_KEY_RECV;
01501 if (addr == NULL ||
01502 os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
01503 wk.ik_flags |= IEEE80211_KEY_GROUP;
01504 if (set_tx) {
01505 wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
01506 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
01507 } else
01508 os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
01509 wk.ik_keyix = key_idx;
01510 wk.ik_keylen = key_len;
01511 #ifdef WORDS_BIGENDIAN
01512 #define WPA_KEY_RSC_LEN 8
01513 {
01514 size_t i;
01515 u8 tmp[WPA_KEY_RSC_LEN];
01516 os_memset(tmp, 0, sizeof(tmp));
01517 for (i = 0; i < seq_len; i++)
01518 tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i];
01519 os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN);
01520 }
01521 #else
01522 os_memcpy(&wk.ik_keyrsc, seq, seq_len);
01523 #endif
01524 os_memcpy(wk.ik_keydata, key, key_len);
01525
01526 return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1);
01527 }
01528
01529 static int
01530 wpa_driver_madwifi_set_countermeasures(void *priv, int enabled)
01531 {
01532 struct wpa_driver_madwifi_data *drv = priv;
01533 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
01534 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled, 1);
01535 }
01536
01537 static int
01538 wpa_driver_madwifi_deauthenticate(void *priv, const u8 *addr, int reason_code)
01539 {
01540 struct wpa_driver_madwifi_data *drv = priv;
01541 struct ieee80211req_mlme mlme;
01542
01543 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01544 mlme.im_op = IEEE80211_MLME_DEAUTH;
01545 mlme.im_reason = reason_code;
01546 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
01547 return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
01548 }
01549
01550 static int
01551 wpa_driver_madwifi_disassociate(void *priv, const u8 *addr, int reason_code)
01552 {
01553 struct wpa_driver_madwifi_data *drv = priv;
01554 struct ieee80211req_mlme mlme;
01555
01556 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01557 mlme.im_op = IEEE80211_MLME_DISASSOC;
01558 mlme.im_reason = reason_code;
01559 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
01560 return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
01561 }
01562
01563 static int
01564 wpa_driver_madwifi_associate(void *priv,
01565 struct wpa_driver_associate_params *params)
01566 {
01567 struct wpa_driver_madwifi_data *drv = priv;
01568 struct ieee80211req_mlme mlme;
01569 int ret = 0, privacy = 1;
01570
01571 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
01572
01573 if (set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED,
01574 params->drop_unencrypted, 1) < 0)
01575 ret = -1;
01576 if (wpa_driver_madwifi_set_auth_alg(drv, params->auth_alg) < 0)
01577 ret = -1;
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587 if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie,
01588 params->wpa_ie_len) < 0)
01589 ret = -1;
01590
01591 if (params->pairwise_suite == CIPHER_NONE &&
01592 params->group_suite == CIPHER_NONE &&
01593 params->key_mgmt_suite == KEY_MGMT_NONE &&
01594 params->wpa_ie_len == 0)
01595 privacy = 0;
01596
01597 if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0)
01598 ret = -1;
01599
01600 if (params->wpa_ie_len &&
01601 set80211param(drv, IEEE80211_PARAM_WPA,
01602 params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1, 1) < 0)
01603 ret = -1;
01604
01605 if (params->bssid == NULL) {
01606
01607
01608
01609
01610 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0)
01611 ret = -1;
01612
01613 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
01614 params->ssid_len) < 0)
01615 ret = -1;
01616 } else {
01617 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0)
01618 ret = -1;
01619 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
01620 params->ssid_len) < 0)
01621 ret = -1;
01622 os_memset(&mlme, 0, sizeof(mlme));
01623 mlme.im_op = IEEE80211_MLME_ASSOC;
01624 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
01625 if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
01626 sizeof(mlme), 1) < 0) {
01627 wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed",
01628 __func__);
01629 ret = -1;
01630 }
01631 }
01632
01633 return ret;
01634 }
01635
01636 static int
01637 wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg)
01638 {
01639 struct wpa_driver_madwifi_data *drv = priv;
01640 int authmode;
01641
01642 if ((auth_alg & WPA_AUTH_ALG_OPEN) &&
01643 (auth_alg & WPA_AUTH_ALG_SHARED))
01644 authmode = IEEE80211_AUTH_AUTO;
01645 else if (auth_alg & WPA_AUTH_ALG_SHARED)
01646 authmode = IEEE80211_AUTH_SHARED;
01647 else
01648 authmode = IEEE80211_AUTH_OPEN;
01649
01650 return set80211param(drv, IEEE80211_PARAM_AUTHMODE, authmode, 1);
01651 }
01652
01653 static int
01654 wpa_driver_madwifi_scan(void *priv, struct wpa_driver_scan_params *params)
01655 {
01656 struct wpa_driver_madwifi_data *drv = priv;
01657 struct iwreq iwr;
01658 int ret = 0;
01659 const u8 *ssid = params->ssids[0].ssid;
01660 size_t ssid_len = params->ssids[0].ssid_len;
01661
01662 wpa_driver_madwifi_set_probe_req_ie(drv, params->extra_ies,
01663 params->extra_ies_len);
01664
01665 os_memset(&iwr, 0, sizeof(iwr));
01666 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
01667
01668
01669
01670
01671 if (wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len) < 0)
01672 ret = -1;
01673
01674 if (ioctl(drv->sock, SIOCSIWSCAN, &iwr) < 0) {
01675 perror("ioctl[SIOCSIWSCAN]");
01676 ret = -1;
01677 }
01678
01679
01680
01681
01682
01683
01684
01685
01686 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext,
01687 drv->ctx);
01688 eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext,
01689 drv->ctx);
01690
01691 return ret;
01692 }
01693
01694 static int wpa_driver_madwifi_get_bssid(void *priv, u8 *bssid)
01695 {
01696 struct wpa_driver_madwifi_data *drv = priv;
01697 return wpa_driver_wext_get_bssid(drv->wext, bssid);
01698 }
01699
01700
01701 static int wpa_driver_madwifi_get_ssid(void *priv, u8 *ssid)
01702 {
01703 struct wpa_driver_madwifi_data *drv = priv;
01704 return wpa_driver_wext_get_ssid(drv->wext, ssid);
01705 }
01706
01707
01708 static struct wpa_scan_results *
01709 wpa_driver_madwifi_get_scan_results(void *priv)
01710 {
01711 struct wpa_driver_madwifi_data *drv = priv;
01712 return wpa_driver_wext_get_scan_results(drv->wext);
01713 }
01714
01715
01716 static int wpa_driver_madwifi_set_operstate(void *priv, int state)
01717 {
01718 struct wpa_driver_madwifi_data *drv = priv;
01719 return wpa_driver_wext_set_operstate(drv->wext, state);
01720 }
01721
01722
01723 static int wpa_driver_madwifi_set_probe_req_ie(void *priv, const u8 *ies,
01724 size_t ies_len)
01725 {
01726 struct ieee80211req_getset_appiebuf *probe_req_ie;
01727 int ret;
01728
01729 probe_req_ie = os_malloc(sizeof(*probe_req_ie) + ies_len);
01730 if (probe_req_ie == NULL)
01731 return -1;
01732
01733 probe_req_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_REQ;
01734 probe_req_ie->app_buflen = ies_len;
01735 os_memcpy(probe_req_ie->app_buf, ies, ies_len);
01736
01737 ret = set80211priv(priv, IEEE80211_IOCTL_SET_APPIEBUF, probe_req_ie,
01738 sizeof(struct ieee80211req_getset_appiebuf) +
01739 ies_len, 1);
01740
01741 os_free(probe_req_ie);
01742
01743 return ret;
01744 }
01745
01746
01747 static void * wpa_driver_madwifi_init(void *ctx, const char *ifname)
01748 {
01749 struct wpa_driver_madwifi_data *drv;
01750
01751 drv = os_zalloc(sizeof(*drv));
01752 if (drv == NULL)
01753 return NULL;
01754 drv->wext = wpa_driver_wext_init(ctx, ifname);
01755 if (drv->wext == NULL)
01756 goto fail;
01757
01758 drv->ctx = ctx;
01759 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
01760 drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
01761 if (drv->sock < 0)
01762 goto fail2;
01763
01764 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) {
01765 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
01766 "roaming", __FUNCTION__);
01767 goto fail3;
01768 }
01769
01770 if (set80211param(drv, IEEE80211_PARAM_WPA, 3, 1) < 0) {
01771 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support",
01772 __FUNCTION__);
01773 goto fail3;
01774 }
01775
01776 return drv;
01777
01778 fail3:
01779 close(drv->sock);
01780 fail2:
01781 wpa_driver_wext_deinit(drv->wext);
01782 fail:
01783 os_free(drv);
01784 return NULL;
01785 }
01786
01787
01788 static void wpa_driver_madwifi_deinit(void *priv)
01789 {
01790 struct wpa_driver_madwifi_data *drv = priv;
01791
01792 if (wpa_driver_madwifi_set_wpa_ie(drv, NULL, 0) < 0) {
01793 wpa_printf(MSG_DEBUG, "%s: failed to clear WPA IE",
01794 __FUNCTION__);
01795 }
01796 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) {
01797 wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based "
01798 "roaming", __FUNCTION__);
01799 }
01800 if (set80211param(drv, IEEE80211_PARAM_PRIVACY, 0, 1) < 0) {
01801 wpa_printf(MSG_DEBUG, "%s: failed to disable forced Privacy "
01802 "flag", __FUNCTION__);
01803 }
01804 if (set80211param(drv, IEEE80211_PARAM_WPA, 0, 1) < 0) {
01805 wpa_printf(MSG_DEBUG, "%s: failed to disable WPA",
01806 __FUNCTION__);
01807 }
01808
01809 wpa_driver_wext_deinit(drv->wext);
01810
01811 close(drv->sock);
01812 os_free(drv);
01813 }
01814
01815 #endif
01816
01817
01818 const struct wpa_driver_ops wpa_driver_madwifi_ops = {
01819 .name = "madwifi",
01820 .desc = "MADWIFI 802.11 support (Atheros, etc.)",
01821 .set_key = wpa_driver_madwifi_set_key,
01822 #ifdef HOSTAPD
01823 .hapd_init = madwifi_init,
01824 .hapd_deinit = madwifi_deinit,
01825 .set_ieee8021x = madwifi_set_ieee8021x,
01826 .set_privacy = madwifi_set_privacy,
01827 .get_seqnum = madwifi_get_seqnum,
01828 .flush = madwifi_flush,
01829 .set_generic_elem = madwifi_set_opt_ie,
01830 .sta_set_flags = madwifi_sta_set_flags,
01831 .read_sta_data = madwifi_read_sta_driver_data,
01832 .hapd_send_eapol = madwifi_send_eapol,
01833 .sta_disassoc = madwifi_sta_disassoc,
01834 .sta_deauth = madwifi_sta_deauth,
01835 .hapd_set_ssid = madwifi_set_ssid,
01836 .hapd_get_ssid = madwifi_get_ssid,
01837 .hapd_set_countermeasures = madwifi_set_countermeasures,
01838 .sta_clear_stats = madwifi_sta_clear_stats,
01839 .commit = madwifi_commit,
01840 .set_ap_wps_ie = madwifi_set_ap_wps_ie,
01841 #else
01842 .get_bssid = wpa_driver_madwifi_get_bssid,
01843 .get_ssid = wpa_driver_madwifi_get_ssid,
01844 .init = wpa_driver_madwifi_init,
01845 .deinit = wpa_driver_madwifi_deinit,
01846 .set_countermeasures = wpa_driver_madwifi_set_countermeasures,
01847 .scan2 = wpa_driver_madwifi_scan,
01848 .get_scan_results2 = wpa_driver_madwifi_get_scan_results,
01849 .deauthenticate = wpa_driver_madwifi_deauthenticate,
01850 .disassociate = wpa_driver_madwifi_disassociate,
01851 .associate = wpa_driver_madwifi_associate,
01852 .set_operstate = wpa_driver_madwifi_set_operstate,
01853 #endif
01854 };