00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "includes.h"
00019 #include <net/if.h>
00020 #include <sys/ioctl.h>
00021
00022 #include "common.h"
00023 #ifndef _BYTE_ORDER
00024 #ifdef WORDS_BIGENDIAN
00025 #define _BYTE_ORDER _BIG_ENDIAN
00026 #else
00027 #define _BYTE_ORDER _LITTLE_ENDIAN
00028 #endif
00029 #endif
00030
00031
00032
00033
00034
00035 #define ATH_WPS_IE
00036
00037 #include "os/linux/include/ieee80211_external.h"
00038
00039
00040 #ifdef CONFIG_WPS
00041 #include <netpacket/packet.h>
00042
00043 #ifndef ETH_P_80211_RAW
00044 #define ETH_P_80211_RAW 0x0019
00045 #endif
00046 #endif
00047
00048 #include "wireless_copy.h"
00049
00050 #include "driver.h"
00051 #include "eloop.h"
00052 #include "priv_netlink.h"
00053 #include "l2_packet/l2_packet.h"
00054 #include "common/ieee802_11_defs.h"
00055 #include "netlink.h"
00056 #include "linux_ioctl.h"
00057
00058
00059 struct madwifi_driver_data {
00060 struct hostapd_data *hapd;
00061
00062 char iface[IFNAMSIZ + 1];
00063 int ifindex;
00064 struct l2_packet_data *sock_xmit;
00065 struct l2_packet_data *sock_recv;
00066 int ioctl_sock;
00067 struct netlink_data *netlink;
00068 int we_version;
00069 u8 acct_mac[ETH_ALEN];
00070 struct hostap_sta_driver_data acct_data;
00071
00072 struct l2_packet_data *sock_raw;
00073 };
00074
00075 static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
00076 int reason_code);
00077
00078 static const char * athr_get_ioctl_name(int op)
00079 {
00080 switch (op) {
00081 case IEEE80211_IOCTL_SETPARAM:
00082 return "SETPARAM";
00083 case IEEE80211_IOCTL_GETPARAM:
00084 return "GETPARAM";
00085 case IEEE80211_IOCTL_SETKEY:
00086 return "SETKEY";
00087 case IEEE80211_IOCTL_SETWMMPARAMS:
00088 return "SETWMMPARAMS";
00089 case IEEE80211_IOCTL_DELKEY:
00090 return "DELKEY";
00091 case IEEE80211_IOCTL_GETWMMPARAMS:
00092 return "GETWMMPARAMS";
00093 case IEEE80211_IOCTL_SETMLME:
00094 return "SETMLME";
00095 case IEEE80211_IOCTL_GETCHANINFO:
00096 return "GETCHANINFO";
00097 case IEEE80211_IOCTL_SETOPTIE:
00098 return "SETOPTIE";
00099 case IEEE80211_IOCTL_GETOPTIE:
00100 return "GETOPTIE";
00101 case IEEE80211_IOCTL_ADDMAC:
00102 return "ADDMAC";
00103 case IEEE80211_IOCTL_DELMAC:
00104 return "DELMAC";
00105 case IEEE80211_IOCTL_GETCHANLIST:
00106 return "GETCHANLIST";
00107 case IEEE80211_IOCTL_SETCHANLIST:
00108 return "SETCHANLIST";
00109 case IEEE80211_IOCTL_KICKMAC:
00110 return "KICKMAC";
00111 case IEEE80211_IOCTL_CHANSWITCH:
00112 return "CHANSWITCH";
00113 case IEEE80211_IOCTL_GETMODE:
00114 return "GETMODE";
00115 case IEEE80211_IOCTL_SETMODE:
00116 return "SETMODE";
00117 case IEEE80211_IOCTL_GET_APPIEBUF:
00118 return "GET_APPIEBUF";
00119 case IEEE80211_IOCTL_SET_APPIEBUF:
00120 return "SET_APPIEBUF";
00121 case IEEE80211_IOCTL_SET_ACPARAMS:
00122 return "SET_ACPARAMS";
00123 case IEEE80211_IOCTL_FILTERFRAME:
00124 return "FILTERFRAME";
00125 case IEEE80211_IOCTL_SET_RTPARAMS:
00126 return "SET_RTPARAMS";
00127 case IEEE80211_IOCTL_SENDADDBA:
00128 return "SENDADDBA";
00129 case IEEE80211_IOCTL_GETADDBASTATUS:
00130 return "GETADDBASTATUS";
00131 case IEEE80211_IOCTL_SENDDELBA:
00132 return "SENDDELBA";
00133 case IEEE80211_IOCTL_SET_MEDENYENTRY:
00134 return "SET_MEDENYENTRY";
00135 case IEEE80211_IOCTL_SET_ADDBARESP:
00136 return "SET_ADDBARESP";
00137 case IEEE80211_IOCTL_GET_MACADDR:
00138 return "GET_MACADDR";
00139 case IEEE80211_IOCTL_SET_HBRPARAMS:
00140 return "SET_HBRPARAMS";
00141 case IEEE80211_IOCTL_SET_RXTIMEOUT:
00142 return "SET_RXTIMEOUT";
00143 case IEEE80211_IOCTL_STA_STATS:
00144 return "STA_STATS";
00145 case IEEE80211_IOCTL_GETWPAIE:
00146 return "GETWPAIE";
00147 default:
00148 return "??";
00149 }
00150 }
00151
00152
00153 static const char * athr_get_param_name(int op)
00154 {
00155 switch (op) {
00156 case IEEE80211_IOC_MCASTCIPHER:
00157 return "MCASTCIPHER";
00158 case IEEE80211_PARAM_MCASTKEYLEN:
00159 return "MCASTKEYLEN";
00160 case IEEE80211_PARAM_UCASTCIPHERS:
00161 return "UCASTCIPHERS";
00162 case IEEE80211_PARAM_KEYMGTALGS:
00163 return "KEYMGTALGS";
00164 case IEEE80211_PARAM_RSNCAPS:
00165 return "RSNCAPS";
00166 case IEEE80211_PARAM_WPA:
00167 return "WPA";
00168 case IEEE80211_PARAM_AUTHMODE:
00169 return "AUTHMODE";
00170 case IEEE80211_PARAM_PRIVACY:
00171 return "PRIVACY";
00172 case IEEE80211_PARAM_COUNTERMEASURES:
00173 return "COUNTERMEASURES";
00174 default:
00175 return "??";
00176 }
00177 }
00178
00179
00180 static int
00181 set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
00182 {
00183 struct iwreq iwr;
00184 int do_inline = len < IFNAMSIZ;
00185
00186
00187 if (op == IEEE80211_IOCTL_SET_APPIEBUF ||
00188 op == IEEE80211_IOCTL_FILTERFRAME)
00189 do_inline = 0;
00190
00191 memset(&iwr, 0, sizeof(iwr));
00192 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
00193 if (do_inline) {
00194
00195
00196
00197 memcpy(iwr.u.name, data, len);
00198 } else {
00199
00200
00201
00202
00203
00204 iwr.u.data.pointer = data;
00205 iwr.u.data.length = len;
00206 }
00207
00208 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
00209 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x "
00210 "(%s) len=%d failed: %d (%s)",
00211 __func__, drv->iface, op,
00212 athr_get_ioctl_name(op),
00213 len, errno, strerror(errno));
00214 return -1;
00215 }
00216 return 0;
00217 }
00218
00219 static int
00220 set80211param(struct madwifi_driver_data *drv, int op, int arg)
00221 {
00222 struct iwreq iwr;
00223
00224 memset(&iwr, 0, sizeof(iwr));
00225 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
00226 iwr.u.mode = op;
00227 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
00228
00229 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
00230 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
00231 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d "
00232 "(%s) arg %d)", __func__, drv->iface, op,
00233 athr_get_param_name(op), arg);
00234 return -1;
00235 }
00236 return 0;
00237 }
00238
00239 #ifndef CONFIG_NO_STDOUT_DEBUG
00240 static const char *
00241 ether_sprintf(const u8 *addr)
00242 {
00243 static char buf[sizeof(MACSTR)];
00244
00245 if (addr != NULL)
00246 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
00247 else
00248 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
00249 return buf;
00250 }
00251 #endif
00252
00253
00254
00255
00256 static int
00257 madwifi_configure_wpa(struct madwifi_driver_data *drv,
00258 struct wpa_bss_params *params)
00259 {
00260 int v;
00261
00262 switch (params->wpa_group) {
00263 case WPA_CIPHER_CCMP:
00264 v = IEEE80211_CIPHER_AES_CCM;
00265 break;
00266 case WPA_CIPHER_TKIP:
00267 v = IEEE80211_CIPHER_TKIP;
00268 break;
00269 case WPA_CIPHER_WEP104:
00270 v = IEEE80211_CIPHER_WEP;
00271 break;
00272 case WPA_CIPHER_WEP40:
00273 v = IEEE80211_CIPHER_WEP;
00274 break;
00275 case WPA_CIPHER_NONE:
00276 v = IEEE80211_CIPHER_NONE;
00277 break;
00278 default:
00279 wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
00280 params->wpa_group);
00281 return -1;
00282 }
00283 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
00284 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) {
00285 printf("Unable to set group key cipher to %u\n", v);
00286 return -1;
00287 }
00288 if (v == IEEE80211_CIPHER_WEP) {
00289
00290 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
00291 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
00292 printf("Unable to set group key length to %u\n", v);
00293 return -1;
00294 }
00295 }
00296
00297 v = 0;
00298 if (params->wpa_pairwise & WPA_CIPHER_CCMP)
00299 v |= 1<<IEEE80211_CIPHER_AES_CCM;
00300 if (params->wpa_pairwise & WPA_CIPHER_TKIP)
00301 v |= 1<<IEEE80211_CIPHER_TKIP;
00302 if (params->wpa_pairwise & WPA_CIPHER_NONE)
00303 v |= 1<<IEEE80211_CIPHER_NONE;
00304 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
00305 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
00306 printf("Unable to set pairwise key ciphers to 0x%x\n", v);
00307 return -1;
00308 }
00309
00310 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
00311 __func__, params->wpa_key_mgmt);
00312 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
00313 params->wpa_key_mgmt)) {
00314 printf("Unable to set key management algorithms to 0x%x\n",
00315 params->wpa_key_mgmt);
00316 return -1;
00317 }
00318
00319 v = 0;
00320 if (params->rsn_preauth)
00321 v |= BIT(0);
00322 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
00323 __func__, params->rsn_preauth);
00324 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
00325 printf("Unable to set RSN capabilities to 0x%x\n", v);
00326 return -1;
00327 }
00328
00329 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
00330 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
00331 printf("Unable to set WPA to %u\n", params->wpa);
00332 return -1;
00333 }
00334 return 0;
00335 }
00336
00337 static int
00338 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
00339 {
00340 struct madwifi_driver_data *drv = priv;
00341
00342 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
00343
00344 if (!params->enabled) {
00345
00346 return set80211param(priv, IEEE80211_PARAM_AUTHMODE,
00347 IEEE80211_AUTH_AUTO);
00348 }
00349 if (!params->wpa && !params->ieee802_1x) {
00350 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00351 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
00352 return -1;
00353 }
00354 if (params->wpa && madwifi_configure_wpa(drv, params) != 0) {
00355 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00356 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
00357 return -1;
00358 }
00359 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
00360 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
00361 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
00362 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
00363 return -1;
00364 }
00365
00366 return 0;
00367 }
00368
00369 static int
00370 madwifi_set_privacy(void *priv, int enabled)
00371 {
00372 struct madwifi_driver_data *drv = priv;
00373
00374 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
00375
00376 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
00377 }
00378
00379 static int
00380 madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized)
00381 {
00382 struct madwifi_driver_data *drv = priv;
00383 struct ieee80211req_mlme mlme;
00384 int ret;
00385
00386 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
00387 __func__, ether_sprintf(addr), authorized);
00388
00389 if (authorized)
00390 mlme.im_op = IEEE80211_MLME_AUTHORIZE;
00391 else
00392 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
00393 mlme.im_reason = 0;
00394 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00395 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00396 if (ret < 0) {
00397 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
00398 __func__, authorized ? "" : "un", MAC2STR(addr));
00399 }
00400
00401 return ret;
00402 }
00403
00404 static int
00405 madwifi_sta_set_flags(void *priv, const u8 *addr,
00406 int total_flags, int flags_or, int flags_and)
00407 {
00408
00409 if (flags_or & WPA_STA_AUTHORIZED)
00410 return madwifi_set_sta_authorized(priv, addr, 1);
00411 if (!(flags_and & WPA_STA_AUTHORIZED))
00412 return madwifi_set_sta_authorized(priv, addr, 0);
00413 return 0;
00414 }
00415
00416 static int
00417 madwifi_del_key(void *priv, const u8 *addr, int key_idx)
00418 {
00419 struct madwifi_driver_data *drv = priv;
00420 struct ieee80211req_del_key wk;
00421 int ret;
00422
00423 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
00424 __func__, ether_sprintf(addr), key_idx);
00425
00426 memset(&wk, 0, sizeof(wk));
00427 if (addr != NULL) {
00428 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
00429 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE;
00430 } else {
00431 wk.idk_keyix = key_idx;
00432 }
00433
00434 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
00435 if (ret < 0) {
00436 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
00437 " key_idx %d)", __func__, ether_sprintf(addr),
00438 key_idx);
00439 }
00440
00441 return ret;
00442 }
00443
00444 static int
00445 madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
00446 const u8 *addr, int key_idx, int set_tx, const u8 *seq,
00447 size_t seq_len, const u8 *key, size_t key_len)
00448 {
00449 struct madwifi_driver_data *drv = priv;
00450 struct ieee80211req_key wk;
00451 u_int8_t cipher;
00452 int ret;
00453
00454 if (alg == WPA_ALG_NONE)
00455 return madwifi_del_key(drv, addr, key_idx);
00456
00457 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
00458 __func__, alg, ether_sprintf(addr), key_idx);
00459
00460 switch (alg) {
00461 case WPA_ALG_WEP:
00462 cipher = IEEE80211_CIPHER_WEP;
00463 break;
00464 case WPA_ALG_TKIP:
00465 cipher = IEEE80211_CIPHER_TKIP;
00466 break;
00467 case WPA_ALG_CCMP:
00468 cipher = IEEE80211_CIPHER_AES_CCM;
00469 break;
00470 default:
00471 printf("%s: unknown/unsupported algorithm %d\n",
00472 __func__, alg);
00473 return -1;
00474 }
00475
00476 if (key_len > sizeof(wk.ik_keydata)) {
00477 printf("%s: key length %lu too big\n", __func__,
00478 (unsigned long) key_len);
00479 return -3;
00480 }
00481
00482 memset(&wk, 0, sizeof(wk));
00483 wk.ik_type = cipher;
00484 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
00485 if (addr == NULL) {
00486 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
00487 wk.ik_keyix = key_idx;
00488 wk.ik_flags |= IEEE80211_KEY_DEFAULT;
00489 } else {
00490 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
00491 wk.ik_keyix = IEEE80211_KEYIX_NONE;
00492 }
00493 wk.ik_keylen = key_len;
00494 memcpy(wk.ik_keydata, key, key_len);
00495
00496 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
00497 if (ret < 0) {
00498 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
00499 " key_idx %d alg %d key_len %lu set_tx %d)",
00500 __func__, ether_sprintf(wk.ik_macaddr), key_idx,
00501 alg, (unsigned long) key_len, set_tx);
00502 }
00503
00504 return ret;
00505 }
00506
00507
00508 static int
00509 madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
00510 u8 *seq)
00511 {
00512 struct madwifi_driver_data *drv = priv;
00513 struct ieee80211req_key wk;
00514
00515 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
00516 __func__, ether_sprintf(addr), idx);
00517
00518 memset(&wk, 0, sizeof(wk));
00519 if (addr == NULL)
00520 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
00521 else
00522 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
00523 wk.ik_keyix = idx;
00524
00525 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
00526 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
00527 "(addr " MACSTR " key_idx %d)",
00528 __func__, MAC2STR(wk.ik_macaddr), idx);
00529 return -1;
00530 }
00531
00532 #ifdef WORDS_BIGENDIAN
00533 {
00534
00535
00536
00537
00538 int i;
00539 #ifndef WPA_KEY_RSC_LEN
00540 #define WPA_KEY_RSC_LEN 8
00541 #endif
00542 u8 tmp[WPA_KEY_RSC_LEN];
00543 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
00544 for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
00545 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
00546 }
00547 }
00548 #else
00549 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
00550 #endif
00551 return 0;
00552 }
00553
00554
00555 static int
00556 madwifi_flush(void *priv)
00557 {
00558 u8 allsta[IEEE80211_ADDR_LEN];
00559 memset(allsta, 0xff, IEEE80211_ADDR_LEN);
00560 return madwifi_sta_deauth(priv, NULL, allsta,
00561 IEEE80211_REASON_AUTH_LEAVE);
00562 }
00563
00564
00565 static int
00566 madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
00567 const u8 *addr)
00568 {
00569 struct madwifi_driver_data *drv = priv;
00570 struct ieee80211req_sta_stats stats;
00571
00572 memset(data, 0, sizeof(*data));
00573
00574
00575
00576
00577 memset(&stats, 0, sizeof(stats));
00578 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
00579 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS,
00580 &stats, sizeof(stats))) {
00581 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
00582 MACSTR ")", __func__, MAC2STR(addr));
00583 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
00584 memcpy(data, &drv->acct_data, sizeof(*data));
00585 return 0;
00586 }
00587
00588 printf("Failed to get station stats information element.\n");
00589 return -1;
00590 }
00591
00592 data->rx_packets = stats.is_stats.ns_rx_data;
00593 data->rx_bytes = stats.is_stats.ns_rx_bytes;
00594 data->tx_packets = stats.is_stats.ns_tx_data;
00595 data->tx_bytes = stats.is_stats.ns_tx_bytes;
00596 return 0;
00597 }
00598
00599
00600 static int
00601 madwifi_sta_clear_stats(void *priv, const u8 *addr)
00602 {
00603 struct madwifi_driver_data *drv = priv;
00604 struct ieee80211req_mlme mlme;
00605 int ret;
00606
00607 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));
00608
00609 mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
00610 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00611 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
00612 sizeof(mlme));
00613 if (ret < 0) {
00614 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
00615 MACSTR ")", __func__, MAC2STR(addr));
00616 }
00617
00618 return ret;
00619 }
00620
00621
00622 static int
00623 madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
00624 {
00625
00626
00627
00628
00629 return 0;
00630 }
00631
00632 static int
00633 madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
00634 int reason_code)
00635 {
00636 struct madwifi_driver_data *drv = priv;
00637 struct ieee80211req_mlme mlme;
00638 int ret;
00639
00640 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
00641 __func__, ether_sprintf(addr), reason_code);
00642
00643 mlme.im_op = IEEE80211_MLME_DEAUTH;
00644 mlme.im_reason = reason_code;
00645 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00646 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00647 if (ret < 0) {
00648 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
00649 " reason %d)",
00650 __func__, MAC2STR(addr), reason_code);
00651 }
00652
00653 return ret;
00654 }
00655
00656 static int
00657 madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
00658 int reason_code)
00659 {
00660 struct madwifi_driver_data *drv = priv;
00661 struct ieee80211req_mlme mlme;
00662 int ret;
00663
00664 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
00665 __func__, ether_sprintf(addr), reason_code);
00666
00667 mlme.im_op = IEEE80211_MLME_DISASSOC;
00668 mlme.im_reason = reason_code;
00669 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00670 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
00671 if (ret < 0) {
00672 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
00673 MACSTR " reason %d)",
00674 __func__, MAC2STR(addr), reason_code);
00675 }
00676
00677 return ret;
00678 }
00679
00680 #ifdef CONFIG_WPS
00681 static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
00682 size_t len)
00683 {
00684 struct madwifi_driver_data *drv = ctx;
00685 const struct ieee80211_mgmt *mgmt;
00686 u16 fc;
00687 union wpa_event_data event;
00688
00689
00690
00691 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
00692 return;
00693 mgmt = (const struct ieee80211_mgmt *) buf;
00694
00695 fc = le_to_host16(mgmt->frame_control);
00696 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
00697 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
00698 return;
00699
00700 os_memset(&event, 0, sizeof(event));
00701 event.rx_probe_req.sa = mgmt->sa;
00702 event.rx_probe_req.ie = mgmt->u.probe_req.variable;
00703 event.rx_probe_req.ie_len =
00704 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
00705 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
00706 }
00707 #endif
00708
00709 static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
00710 {
00711 int ret = 0;
00712 #ifdef CONFIG_WPS
00713 struct ieee80211req_set_filter filt;
00714
00715 wpa_printf(MSG_DEBUG, "%s Enter", __func__);
00716 filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
00717
00718 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
00719 sizeof(struct ieee80211req_set_filter));
00720 if (ret)
00721 return ret;
00722
00723 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
00724 madwifi_raw_receive, drv, 1);
00725 if (drv->sock_raw == NULL)
00726 return -1;
00727 #endif
00728 return ret;
00729 }
00730
00731 #ifdef CONFIG_WPS
00732 static int
00733 madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
00734 {
00735 struct madwifi_driver_data *drv = priv;
00736 u8 buf[256];
00737 struct ieee80211req_getset_appiebuf *beac_ie;
00738
00739 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
00740 (unsigned long) len);
00741
00742 beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
00743 beac_ie->app_frmtype = frametype;
00744 beac_ie->app_buflen = len;
00745 memcpy(&(beac_ie->app_buf[0]), ie, len);
00746
00747 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
00748 sizeof(struct ieee80211req_getset_appiebuf) + len);
00749 }
00750
00751 static int
00752 madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
00753 const struct wpabuf *proberesp)
00754 {
00755 if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
00756 beacon ? wpabuf_len(beacon) : 0,
00757 IEEE80211_APPIE_FRAME_BEACON))
00758 return -1;
00759 return madwifi_set_wps_ie(priv,
00760 proberesp ? wpabuf_head(proberesp) : NULL,
00761 proberesp ? wpabuf_len(proberesp): 0,
00762 IEEE80211_APPIE_FRAME_PROBE_RESP);
00763 }
00764 #else
00765 #define madwifi_set_ap_wps_ie NULL
00766 #endif
00767
00768 static void
00769 madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
00770 {
00771 struct hostapd_data *hapd = drv->hapd;
00772 struct ieee80211req_wpaie ie;
00773 int ielen = 0;
00774 u8 *iebuf = NULL;
00775
00776
00777
00778
00779 memset(&ie, 0, sizeof(ie));
00780 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
00781 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
00782
00783
00784
00785
00786 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s",
00787 __func__, strerror(errno));
00788 goto no_ie;
00789 }
00790 wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
00791 ie.wpa_ie, IEEE80211_MAX_OPT_IE);
00792 wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
00793 ie.rsn_ie, IEEE80211_MAX_OPT_IE);
00794 iebuf = ie.wpa_ie;
00795
00796
00797 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
00798 iebuf[1] = 0;
00799 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
00800
00801
00802 iebuf = ie.rsn_ie;
00803 if (iebuf[0] != WLAN_EID_RSN)
00804 iebuf[1] = 0;
00805 }
00806
00807 ielen = iebuf[1];
00808 if (ielen == 0)
00809 iebuf = NULL;
00810 else
00811 ielen += 2;
00812
00813 no_ie:
00814 drv_event_assoc(hapd, addr, iebuf, ielen);
00815
00816 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
00817
00818 memset(drv->acct_mac, 0, ETH_ALEN);
00819 memset(&drv->acct_data, 0, sizeof(drv->acct_data));
00820 }
00821 }
00822
00823 static void
00824 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
00825 char *custom, char *end)
00826 {
00827 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
00828
00829 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
00830 char *pos;
00831 u8 addr[ETH_ALEN];
00832 pos = strstr(custom, "addr=");
00833 if (pos == NULL) {
00834 wpa_printf(MSG_DEBUG,
00835 "MLME-MICHAELMICFAILURE.indication "
00836 "without sender address ignored");
00837 return;
00838 }
00839 pos += 5;
00840 if (hwaddr_aton(pos, addr) == 0) {
00841 union wpa_event_data data;
00842 os_memset(&data, 0, sizeof(data));
00843 data.michael_mic_failure.unicast = 1;
00844 data.michael_mic_failure.src = addr;
00845 wpa_supplicant_event(drv->hapd,
00846 EVENT_MICHAEL_MIC_FAILURE, &data);
00847 } else {
00848 wpa_printf(MSG_DEBUG,
00849 "MLME-MICHAELMICFAILURE.indication "
00850 "with invalid MAC address");
00851 }
00852 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
00853 char *key, *value;
00854 u32 val;
00855 key = custom;
00856 while ((key = strchr(key, '\n')) != NULL) {
00857 key++;
00858 value = strchr(key, '=');
00859 if (value == NULL)
00860 continue;
00861 *value++ = '\0';
00862 val = strtoul(value, NULL, 10);
00863 if (strcmp(key, "mac") == 0)
00864 hwaddr_aton(value, drv->acct_mac);
00865 else if (strcmp(key, "rx_packets") == 0)
00866 drv->acct_data.rx_packets = val;
00867 else if (strcmp(key, "tx_packets") == 0)
00868 drv->acct_data.tx_packets = val;
00869 else if (strcmp(key, "rx_bytes") == 0)
00870 drv->acct_data.rx_bytes = val;
00871 else if (strcmp(key, "tx_bytes") == 0)
00872 drv->acct_data.tx_bytes = val;
00873 key = value;
00874 }
00875 #ifdef CONFIG_WPS
00876 } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) {
00877
00878
00879
00880
00881 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL);
00882 } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {
00883
00884
00885
00886
00887
00888
00889 #define WPS_FRAM_TAG_SIZE 30
00890 int len = atoi(custom + 16);
00891 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) {
00892 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event "
00893 "length %d", len);
00894 return;
00895 }
00896 madwifi_raw_receive(drv, NULL,
00897 (u8 *) custom + WPS_FRAM_TAG_SIZE, len);
00898 #endif
00899 }
00900 }
00901
00902 static void
00903 madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
00904 char *data, int len)
00905 {
00906 struct iw_event iwe_buf, *iwe = &iwe_buf;
00907 char *pos, *end, *custom, *buf;
00908
00909 pos = data;
00910 end = data + len;
00911
00912 while (pos + IW_EV_LCP_LEN <= end) {
00913
00914
00915 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
00916 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
00917 iwe->cmd, iwe->len);
00918 if (iwe->len <= IW_EV_LCP_LEN)
00919 return;
00920
00921 custom = pos + IW_EV_POINT_LEN;
00922 if (drv->we_version > 18 &&
00923 (iwe->cmd == IWEVMICHAELMICFAILURE ||
00924 iwe->cmd == IWEVASSOCREQIE ||
00925 iwe->cmd == IWEVCUSTOM)) {
00926
00927 char *dpos = (char *) &iwe_buf.u.data.length;
00928 int dlen = dpos - (char *) &iwe_buf;
00929 memcpy(dpos, pos + IW_EV_LCP_LEN,
00930 sizeof(struct iw_event) - dlen);
00931 } else {
00932 memcpy(&iwe_buf, pos, sizeof(struct iw_event));
00933 custom += IW_EV_POINT_OFF;
00934 }
00935
00936 switch (iwe->cmd) {
00937 case IWEVEXPIRED:
00938 drv_event_disassoc(drv->hapd,
00939 (u8 *) iwe->u.addr.sa_data);
00940 break;
00941 case IWEVREGISTERED:
00942 madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
00943 break;
00944 case IWEVASSOCREQIE:
00945
00946
00947
00948
00949 case IWEVCUSTOM:
00950 if (custom + iwe->u.data.length > end)
00951 return;
00952 buf = malloc(iwe->u.data.length + 1);
00953 if (buf == NULL)
00954 return;
00955 memcpy(buf, custom, iwe->u.data.length);
00956 buf[iwe->u.data.length] = '\0';
00957 madwifi_wireless_event_wireless_custom(
00958 drv, buf, buf + iwe->u.data.length);
00959 free(buf);
00960 break;
00961 }
00962
00963 pos += iwe->len;
00964 }
00965 }
00966
00967
00968 static void
00969 madwifi_wireless_event_rtm_newlink(void *ctx,
00970 struct ifinfomsg *ifi, u8 *buf, size_t len)
00971 {
00972 struct madwifi_driver_data *drv = ctx;
00973 int attrlen, rta_len;
00974 struct rtattr *attr;
00975
00976 if (ifi->ifi_index != drv->ifindex)
00977 return;
00978
00979 attrlen = len;
00980 attr = (struct rtattr *) buf;
00981
00982 rta_len = RTA_ALIGN(sizeof(struct rtattr));
00983 while (RTA_OK(attr, attrlen)) {
00984 if (attr->rta_type == IFLA_WIRELESS) {
00985 madwifi_wireless_event_wireless(
00986 drv, ((char *) attr) + rta_len,
00987 attr->rta_len - rta_len);
00988 }
00989 attr = RTA_NEXT(attr, attrlen);
00990 }
00991 }
00992
00993
00994 static int
00995 madwifi_get_we_version(struct madwifi_driver_data *drv)
00996 {
00997 struct iw_range *range;
00998 struct iwreq iwr;
00999 int minlen;
01000 size_t buflen;
01001
01002 drv->we_version = 0;
01003
01004
01005
01006
01007
01008 buflen = sizeof(struct iw_range) + 500;
01009 range = os_zalloc(buflen);
01010 if (range == NULL)
01011 return -1;
01012
01013 memset(&iwr, 0, sizeof(iwr));
01014 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01015 iwr.u.data.pointer = (caddr_t) range;
01016 iwr.u.data.length = buflen;
01017
01018 minlen = ((char *) &range->enc_capa) - (char *) range +
01019 sizeof(range->enc_capa);
01020
01021 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
01022 perror("ioctl[SIOCGIWRANGE]");
01023 free(range);
01024 return -1;
01025 } else if (iwr.u.data.length >= minlen &&
01026 range->we_version_compiled >= 18) {
01027 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
01028 "WE(source)=%d enc_capa=0x%x",
01029 range->we_version_compiled,
01030 range->we_version_source,
01031 range->enc_capa);
01032 drv->we_version = range->we_version_compiled;
01033 }
01034
01035 free(range);
01036 return 0;
01037 }
01038
01039
01040 static int
01041 madwifi_wireless_event_init(struct madwifi_driver_data *drv)
01042 {
01043 struct netlink_config *cfg;
01044
01045 madwifi_get_we_version(drv);
01046
01047 cfg = os_zalloc(sizeof(*cfg));
01048 if (cfg == NULL)
01049 return -1;
01050 cfg->ctx = drv;
01051 cfg->newlink_cb = madwifi_wireless_event_rtm_newlink;
01052 drv->netlink = netlink_init(cfg);
01053 if (drv->netlink == NULL) {
01054 os_free(cfg);
01055 return -1;
01056 }
01057
01058 return 0;
01059 }
01060
01061
01062 static int
01063 madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
01064 int encrypt, const u8 *own_addr)
01065 {
01066 struct madwifi_driver_data *drv = priv;
01067 unsigned char buf[3000];
01068 unsigned char *bp = buf;
01069 struct l2_ethhdr *eth;
01070 size_t len;
01071 int status;
01072
01073
01074
01075
01076
01077
01078
01079 len = data_len + sizeof(struct l2_ethhdr);
01080 if (len > sizeof(buf)) {
01081 bp = malloc(len);
01082 if (bp == NULL) {
01083 printf("EAPOL frame discarded, cannot malloc temp "
01084 "buffer of size %lu!\n", (unsigned long) len);
01085 return -1;
01086 }
01087 }
01088 eth = (struct l2_ethhdr *) bp;
01089 memcpy(eth->h_dest, addr, ETH_ALEN);
01090 memcpy(eth->h_source, own_addr, ETH_ALEN);
01091 eth->h_proto = host_to_be16(ETH_P_EAPOL);
01092 memcpy(eth+1, data, data_len);
01093
01094 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
01095
01096 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
01097
01098 if (bp != buf)
01099 free(bp);
01100 return status;
01101 }
01102
01103 static void
01104 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
01105 {
01106 struct madwifi_driver_data *drv = ctx;
01107 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
01108 len - sizeof(struct l2_ethhdr));
01109 }
01110
01111 static void *
01112 madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
01113 {
01114 struct madwifi_driver_data *drv;
01115 struct ifreq ifr;
01116 struct iwreq iwr;
01117 char brname[IFNAMSIZ];
01118
01119 drv = os_zalloc(sizeof(struct madwifi_driver_data));
01120 if (drv == NULL) {
01121 printf("Could not allocate memory for madwifi driver data\n");
01122 return NULL;
01123 }
01124
01125 drv->hapd = hapd;
01126 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
01127 if (drv->ioctl_sock < 0) {
01128 perror("socket[PF_INET,SOCK_DGRAM]");
01129 goto bad;
01130 }
01131 memcpy(drv->iface, params->ifname, sizeof(drv->iface));
01132
01133 memset(&ifr, 0, sizeof(ifr));
01134 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
01135 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
01136 perror("ioctl(SIOCGIFINDEX)");
01137 goto bad;
01138 }
01139 drv->ifindex = ifr.ifr_ifindex;
01140
01141 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
01142 handle_read, drv, 1);
01143 if (drv->sock_xmit == NULL)
01144 goto bad;
01145 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
01146 goto bad;
01147 if (params->bridge[0]) {
01148 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
01149 params->bridge[0]);
01150 drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
01151 ETH_P_EAPOL, handle_read, drv,
01152 1);
01153 if (drv->sock_recv == NULL)
01154 goto bad;
01155 } else if (linux_br_get(brname, drv->iface) == 0) {
01156 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
01157 "EAPOL receive", brname);
01158 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
01159 handle_read, drv, 1);
01160 if (drv->sock_recv == NULL)
01161 goto bad;
01162 } else
01163 drv->sock_recv = drv->sock_xmit;
01164
01165 memset(&iwr, 0, sizeof(iwr));
01166 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01167
01168 iwr.u.mode = IW_MODE_MASTER;
01169
01170 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
01171 perror("ioctl[SIOCSIWMODE]");
01172 printf("Could not set interface to master mode!\n");
01173 goto bad;
01174 }
01175
01176
01177 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
01178 madwifi_set_privacy(drv, 0);
01179
01180 madwifi_receive_probe_req(drv);
01181
01182 if (madwifi_wireless_event_init(drv))
01183 goto bad;
01184
01185 return drv;
01186 bad:
01187 if (drv->sock_xmit != NULL)
01188 l2_packet_deinit(drv->sock_xmit);
01189 if (drv->ioctl_sock >= 0)
01190 close(drv->ioctl_sock);
01191 if (drv != NULL)
01192 free(drv);
01193 return NULL;
01194 }
01195
01196
01197 static void
01198 madwifi_deinit(void *priv)
01199 {
01200 struct madwifi_driver_data *drv = priv;
01201
01202 netlink_deinit(drv->netlink);
01203 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
01204 if (drv->ioctl_sock >= 0)
01205 close(drv->ioctl_sock);
01206 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
01207 l2_packet_deinit(drv->sock_recv);
01208 if (drv->sock_xmit != NULL)
01209 l2_packet_deinit(drv->sock_xmit);
01210 if (drv->sock_raw)
01211 l2_packet_deinit(drv->sock_raw);
01212 free(drv);
01213 }
01214
01215 static int
01216 madwifi_set_ssid(void *priv, const u8 *buf, int len)
01217 {
01218 struct madwifi_driver_data *drv = priv;
01219 struct iwreq iwr;
01220
01221 memset(&iwr, 0, sizeof(iwr));
01222 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01223 iwr.u.essid.flags = 1;
01224 iwr.u.essid.pointer = (caddr_t) buf;
01225 iwr.u.essid.length = len + 1;
01226
01227 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
01228 perror("ioctl[SIOCSIWESSID]");
01229 printf("len=%d\n", len);
01230 return -1;
01231 }
01232 return 0;
01233 }
01234
01235 static int
01236 madwifi_get_ssid(void *priv, u8 *buf, int len)
01237 {
01238 struct madwifi_driver_data *drv = priv;
01239 struct iwreq iwr;
01240 int ret = 0;
01241
01242 memset(&iwr, 0, sizeof(iwr));
01243 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
01244 iwr.u.essid.pointer = (caddr_t) buf;
01245 iwr.u.essid.length = len;
01246
01247 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
01248 perror("ioctl[SIOCGIWESSID]");
01249 ret = -1;
01250 } else
01251 ret = iwr.u.essid.length;
01252
01253 return ret;
01254 }
01255
01256 static int
01257 madwifi_set_countermeasures(void *priv, int enabled)
01258 {
01259 struct madwifi_driver_data *drv = priv;
01260 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
01261 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
01262 }
01263
01264 static int
01265 madwifi_commit(void *priv)
01266 {
01267 struct madwifi_driver_data *drv = priv;
01268 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
01269 }
01270
01271 const struct wpa_driver_ops wpa_driver_atheros_ops = {
01272 .name = "atheros",
01273 .hapd_init = madwifi_init,
01274 .deinit = madwifi_deinit,
01275 .set_ieee8021x = madwifi_set_ieee8021x,
01276 .set_privacy = madwifi_set_privacy,
01277 .set_key = madwifi_set_key,
01278 .get_seqnum = madwifi_get_seqnum,
01279 .flush = madwifi_flush,
01280 .set_generic_elem = madwifi_set_opt_ie,
01281 .sta_set_flags = madwifi_sta_set_flags,
01282 .read_sta_data = madwifi_read_sta_driver_data,
01283 .hapd_send_eapol = madwifi_send_eapol,
01284 .sta_disassoc = madwifi_sta_disassoc,
01285 .sta_deauth = madwifi_sta_deauth,
01286 .hapd_set_ssid = madwifi_set_ssid,
01287 .hapd_get_ssid = madwifi_get_ssid,
01288 .set_countermeasures = madwifi_set_countermeasures,
01289 .sta_clear_stats = madwifi_sta_clear_stats,
01290 .commit = madwifi_commit,
01291 .set_ap_wps_ie = madwifi_set_ap_wps_ie,
01292 };