driver_madwifi.c

Go to the documentation of this file.
00001 
00017 #include "includes.h"
00018 #include <sys/ioctl.h>
00019 
00020 #include "common.h"
00021 #include "driver.h"
00022 #include "driver_wext.h"
00023 #include "eloop.h"
00024 #include "wpa_supplicant.h"
00025 #include "wpa.h"
00026 #include "wireless_copy.h"
00027 
00028 #include <include/compat.h>
00029 #include <net80211/ieee80211.h>
00030 #ifdef WME_NUM_AC
00031 /* Assume this is built against BSD branch of madwifi driver. */
00032 #define MADWIFI_BSD
00033 #include <net80211/_ieee80211.h>
00034 #endif /* WME_NUM_AC */
00035 #include <net80211/ieee80211_crypto.h>
00036 #include <net80211/ieee80211_ioctl.h>
00037 
00038 #ifdef IEEE80211_IOCTL_SETWMMPARAMS
00039 /* Assume this is built against madwifi-ng */
00040 #define MADWIFI_NG
00041 #endif /* IEEE80211_IOCTL_SETWMMPARAMS */
00042 
00043 struct wpa_driver_madwifi_data {
00044         void *wext; /* private data for driver_wext */
00045         void *ctx;
00046         char ifname[IFNAMSIZ + 1];
00047         int sock;
00048 };
00049 
00050 static int
00051 set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len,
00052              int show_err)
00053 {
00054         struct iwreq iwr;
00055 
00056         os_memset(&iwr, 0, sizeof(iwr));
00057         os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00058         if (len < IFNAMSIZ) {
00059                 /*
00060                  * Argument data fits inline; put it there.
00061                  */
00062                 os_memcpy(iwr.u.name, data, len);
00063         } else {
00064                 /*
00065                  * Argument data too big for inline transfer; setup a
00066                  * parameter block instead; the kernel will transfer
00067                  * the data for the driver.
00068                  */
00069                 iwr.u.data.pointer = data;
00070                 iwr.u.data.length = len;
00071         }
00072 
00073         if (ioctl(drv->sock, op, &iwr) < 0) {
00074                 if (show_err) {
00075 #ifdef MADWIFI_NG
00076                         int first = IEEE80211_IOCTL_SETPARAM;
00077                         int last = IEEE80211_IOCTL_KICKMAC;
00078                         static const char *opnames[] = {
00079                                 "ioctl[IEEE80211_IOCTL_SETPARAM]",
00080                                 "ioctl[IEEE80211_IOCTL_GETPARAM]",
00081                                 "ioctl[IEEE80211_IOCTL_SETMODE]",
00082                                 "ioctl[IEEE80211_IOCTL_GETMODE]",
00083                                 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
00084                                 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
00085                                 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
00086                                 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
00087                                 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
00088                                 NULL,
00089                                 NULL,
00090                                 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
00091                                 NULL,
00092                                 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
00093                                 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
00094                                 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
00095                                 "ioctl[IEEE80211_IOCTL_SETMLME]",
00096                                 NULL,
00097                                 "ioctl[IEEE80211_IOCTL_SETKEY]",
00098                                 NULL,
00099                                 "ioctl[IEEE80211_IOCTL_DELKEY]",
00100                                 NULL,
00101                                 "ioctl[IEEE80211_IOCTL_ADDMAC]",
00102                                 NULL,
00103                                 "ioctl[IEEE80211_IOCTL_DELMAC]",
00104                                 NULL,
00105                                 "ioctl[IEEE80211_IOCTL_WDSMAC]",
00106                                 NULL,
00107                                 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
00108                                 NULL,
00109                                 "ioctl[IEEE80211_IOCTL_KICKMAC]",
00110                         };
00111 #else /* MADWIFI_NG */
00112                         int first = IEEE80211_IOCTL_SETPARAM;
00113                         int last = IEEE80211_IOCTL_CHANLIST;
00114                         static const char *opnames[] = {
00115                                 "ioctl[IEEE80211_IOCTL_SETPARAM]",
00116                                 "ioctl[IEEE80211_IOCTL_GETPARAM]",
00117                                 "ioctl[IEEE80211_IOCTL_SETKEY]",
00118                                 "ioctl[IEEE80211_IOCTL_GETKEY]",
00119                                 "ioctl[IEEE80211_IOCTL_DELKEY]",
00120                                 NULL,
00121                                 "ioctl[IEEE80211_IOCTL_SETMLME]",
00122                                 NULL,
00123                                 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
00124                                 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
00125                                 "ioctl[IEEE80211_IOCTL_ADDMAC]",
00126                                 NULL,
00127                                 "ioctl[IEEE80211_IOCTL_DELMAC]",
00128                                 NULL,
00129                                 "ioctl[IEEE80211_IOCTL_CHANLIST]",
00130                         };
00131 #endif /* MADWIFI_NG */
00132                         int idx = op - first;
00133                         if (first <= op && op <= last &&
00134                             idx < (int) (sizeof(opnames) / sizeof(opnames[0]))
00135                             && opnames[idx])
00136                                 perror(opnames[idx]);
00137                         else
00138                                 perror("ioctl[unknown???]");
00139                 }
00140                 return -1;
00141         }
00142         return 0;
00143 }
00144 
00145 static int
00146 set80211param(struct wpa_driver_madwifi_data *drv, int op, int arg,
00147               int show_err)
00148 {
00149         struct iwreq iwr;
00150 
00151         os_memset(&iwr, 0, sizeof(iwr));
00152         os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00153         iwr.u.mode = op;
00154         os_memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
00155 
00156         if (ioctl(drv->sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
00157                 if (show_err) 
00158                         perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
00159                 return -1;
00160         }
00161         return 0;
00162 }
00163 
00164 static int
00165 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data *drv,
00166                               const u8 *wpa_ie, size_t wpa_ie_len)
00167 {
00168         struct iwreq iwr;
00169 
00170         os_memset(&iwr, 0, sizeof(iwr));
00171         os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00172         /* NB: SETOPTIE is not fixed-size so must not be inlined */
00173         iwr.u.data.pointer = (void *) wpa_ie;
00174         iwr.u.data.length = wpa_ie_len;
00175 
00176         if (ioctl(drv->sock, IEEE80211_IOCTL_SETOPTIE, &iwr) < 0) {
00177                 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
00178                 return -1;
00179         }
00180         return 0;
00181 }
00182 
00183 static int
00184 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data *drv, int key_idx,
00185                            const u8 *addr)
00186 {
00187         struct ieee80211req_del_key wk;
00188 
00189         wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __FUNCTION__, key_idx);
00190         os_memset(&wk, 0, sizeof(wk));
00191         wk.idk_keyix = key_idx;
00192         if (addr != NULL)
00193                 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
00194 
00195         return set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk), 1);
00196 }
00197 
00198 static int
00199 wpa_driver_madwifi_set_key(void *priv, wpa_alg alg,
00200                            const u8 *addr, int key_idx, int set_tx,
00201                            const u8 *seq, size_t seq_len,
00202                            const u8 *key, size_t key_len)
00203 {
00204         struct wpa_driver_madwifi_data *drv = priv;
00205         struct ieee80211req_key wk;
00206         char *alg_name;
00207         u_int8_t cipher;
00208 
00209         if (alg == WPA_ALG_NONE)
00210                 return wpa_driver_madwifi_del_key(drv, key_idx, addr);
00211 
00212         switch (alg) {
00213         case WPA_ALG_WEP:
00214                 if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
00215                                               ETH_ALEN) == 0) {
00216                         /*
00217                          * madwifi did not seem to like static WEP key
00218                          * configuration with IEEE80211_IOCTL_SETKEY, so use
00219                          * Linux wireless extensions ioctl for this.
00220                          */
00221                         return wpa_driver_wext_set_key(drv->wext, alg, addr,
00222                                                        key_idx, set_tx,
00223                                                        seq, seq_len,
00224                                                        key, key_len);
00225                 }
00226                 alg_name = "WEP";
00227                 cipher = IEEE80211_CIPHER_WEP;
00228                 break;
00229         case WPA_ALG_TKIP:
00230                 alg_name = "TKIP";
00231                 cipher = IEEE80211_CIPHER_TKIP;
00232                 break;
00233         case WPA_ALG_CCMP:
00234                 alg_name = "CCMP";
00235                 cipher = IEEE80211_CIPHER_AES_CCM;
00236                 break;
00237         default:
00238                 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
00239                         __FUNCTION__, alg);
00240                 return -1;
00241         }
00242 
00243         wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
00244                    "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
00245                    (unsigned long) seq_len, (unsigned long) key_len);
00246 
00247         if (seq_len > sizeof(u_int64_t)) {
00248                 wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big",
00249                            __FUNCTION__, (unsigned long) seq_len);
00250                 return -2;
00251         }
00252         if (key_len > sizeof(wk.ik_keydata)) {
00253                 wpa_printf(MSG_DEBUG, "%s: key length %lu too big",
00254                            __FUNCTION__, (unsigned long) key_len);
00255                 return -3;
00256         }
00257 
00258         os_memset(&wk, 0, sizeof(wk));
00259         wk.ik_type = cipher;
00260         wk.ik_flags = IEEE80211_KEY_RECV;
00261         if (addr == NULL ||
00262             os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
00263                 wk.ik_flags |= IEEE80211_KEY_GROUP;
00264         if (set_tx) {
00265                 wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
00266                 os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
00267         } else
00268                 os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
00269         wk.ik_keyix = key_idx;
00270         wk.ik_keylen = key_len;
00271 #ifdef WORDS_BIGENDIAN
00272 #define WPA_KEY_RSC_LEN 8
00273         {
00274                 size_t i;
00275                 u8 tmp[WPA_KEY_RSC_LEN];
00276                 os_memset(tmp, 0, sizeof(tmp));
00277                 for (i = 0; i < seq_len; i++)
00278                         tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i];
00279                 os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN);
00280         }
00281 #else /* WORDS_BIGENDIAN */
00282         os_memcpy(&wk.ik_keyrsc, seq, seq_len);
00283 #endif /* WORDS_BIGENDIAN */
00284         os_memcpy(wk.ik_keydata, key, key_len);
00285 
00286         return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1);
00287 }
00288 
00289 static int
00290 wpa_driver_madwifi_set_countermeasures(void *priv, int enabled)
00291 {
00292         struct wpa_driver_madwifi_data *drv = priv;
00293         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00294         return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled, 1);
00295 }
00296 
00297 
00298 static int
00299 wpa_driver_madwifi_set_drop_unencrypted(void *priv, int enabled)
00300 {
00301         struct wpa_driver_madwifi_data *drv = priv;
00302         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00303         return set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED, enabled, 1);
00304 }
00305 
00306 static int
00307 wpa_driver_madwifi_deauthenticate(void *priv, const u8 *addr, int reason_code)
00308 {
00309         struct wpa_driver_madwifi_data *drv = priv;
00310         struct ieee80211req_mlme mlme;
00311 
00312         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00313         mlme.im_op = IEEE80211_MLME_DEAUTH;
00314         mlme.im_reason = reason_code;
00315         os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00316         return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
00317 }
00318 
00319 static int
00320 wpa_driver_madwifi_disassociate(void *priv, const u8 *addr, int reason_code)
00321 {
00322         struct wpa_driver_madwifi_data *drv = priv;
00323         struct ieee80211req_mlme mlme;
00324 
00325         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00326         mlme.im_op = IEEE80211_MLME_DISASSOC;
00327         mlme.im_reason = reason_code;
00328         os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
00329         return set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1);
00330 }
00331 
00332 static int
00333 wpa_driver_madwifi_associate(void *priv,
00334                              struct wpa_driver_associate_params *params)
00335 {
00336         struct wpa_driver_madwifi_data *drv = priv;
00337         struct ieee80211req_mlme mlme;
00338         int ret = 0, privacy = 1;
00339 
00340         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00341 
00342         /*
00343          * NB: Don't need to set the freq or cipher-related state as
00344          *     this is implied by the bssid which is used to locate
00345          *     the scanned node state which holds it.  The ssid is
00346          *     needed to disambiguate an AP that broadcasts multiple
00347          *     ssid's but uses the same bssid.
00348          */
00349         /* XXX error handling is wrong but unclear what to do... */
00350         if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie,
00351                                           params->wpa_ie_len) < 0)
00352                 ret = -1;
00353 
00354         if (params->pairwise_suite == CIPHER_NONE &&
00355             params->group_suite == CIPHER_NONE &&
00356             params->key_mgmt_suite == KEY_MGMT_NONE &&
00357             params->wpa_ie_len == 0)
00358                 privacy = 0;
00359 
00360         if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0)
00361                 ret = -1;
00362 
00363         if (params->wpa_ie_len &&
00364             set80211param(drv, IEEE80211_PARAM_WPA,
00365                           params->wpa_ie[0] == RSN_INFO_ELEM ? 2 : 1, 1) < 0)
00366                 ret = -1;
00367 
00368         if (params->bssid == NULL) {
00369                 /* ap_scan=2 mode - driver takes care of AP selection and
00370                  * roaming */
00371                 /* FIX: this does not seem to work; would probably need to
00372                  * change something in the driver */
00373                 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0)
00374                         ret = -1;
00375 
00376                 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
00377                                              params->ssid_len) < 0)
00378                         ret = -1;
00379         } else {
00380                 if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0)
00381                         ret = -1;
00382                 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
00383                                              params->ssid_len) < 0)
00384                         ret = -1;
00385                 os_memset(&mlme, 0, sizeof(mlme));
00386                 mlme.im_op = IEEE80211_MLME_ASSOC;
00387                 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
00388                 if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
00389                                  sizeof(mlme), 1) < 0) {
00390                         wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed",
00391                                    __func__);
00392                         ret = -1;
00393                 }
00394         }
00395 
00396         return ret;
00397 }
00398 
00399 static int
00400 wpa_driver_madwifi_set_auth_alg(void *priv, int auth_alg)
00401 {
00402         struct wpa_driver_madwifi_data *drv = priv;
00403         int authmode;
00404 
00405         if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) &&
00406             (auth_alg & AUTH_ALG_SHARED_KEY))
00407                 authmode = IEEE80211_AUTH_AUTO;
00408         else if (auth_alg & AUTH_ALG_SHARED_KEY)
00409                 authmode = IEEE80211_AUTH_SHARED;
00410         else
00411                 authmode = IEEE80211_AUTH_OPEN;
00412 
00413         return set80211param(drv, IEEE80211_PARAM_AUTHMODE, authmode, 1);
00414 }
00415 
00416 static int
00417 wpa_driver_madwifi_scan(void *priv, const u8 *ssid, size_t ssid_len)
00418 {
00419         struct wpa_driver_madwifi_data *drv = priv;
00420         struct iwreq iwr;
00421         int ret = 0;
00422 
00423         os_memset(&iwr, 0, sizeof(iwr));
00424         os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00425 
00426         /* set desired ssid before scan */
00427         /* FIX: scan should not break the current association, so using
00428          * set_ssid may not be the best way of doing this.. */
00429         if (wpa_driver_wext_set_ssid(drv->wext, ssid, ssid_len) < 0)
00430                 ret = -1;
00431 
00432         if (ioctl(drv->sock, SIOCSIWSCAN, &iwr) < 0) {
00433                 perror("ioctl[SIOCSIWSCAN]");
00434                 ret = -1;
00435         }
00436 
00437         /*
00438          * madwifi delivers a scan complete event so no need to poll, but
00439          * register a backup timeout anyway to make sure that we recover even
00440          * if the driver does not send this event for any reason. This timeout
00441          * will only be used if the event is not delivered (event handler will
00442          * cancel the timeout).
00443          */
00444         eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext,
00445                                drv->ctx);
00446 
00447         return ret;
00448 }
00449 
00450 static int wpa_driver_madwifi_get_bssid(void *priv, u8 *bssid)
00451 {
00452         struct wpa_driver_madwifi_data *drv = priv;
00453         return wpa_driver_wext_get_bssid(drv->wext, bssid);
00454 }
00455 
00456 
00457 static int wpa_driver_madwifi_get_ssid(void *priv, u8 *ssid)
00458 {
00459         struct wpa_driver_madwifi_data *drv = priv;
00460         return wpa_driver_wext_get_ssid(drv->wext, ssid);
00461 }
00462 
00463 
00464 static int wpa_driver_madwifi_get_scan_results(void *priv,
00465                                             struct wpa_scan_result *results,
00466                                             size_t max_size)
00467 {
00468         struct wpa_driver_madwifi_data *drv = priv;
00469         return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
00470 }
00471 
00472 
00473 static int wpa_driver_madwifi_set_operstate(void *priv, int state)
00474 {
00475         struct wpa_driver_madwifi_data *drv = priv;
00476         return wpa_driver_wext_set_operstate(drv->wext, state);
00477 }
00478 
00479 
00480 static void * wpa_driver_madwifi_init(void *ctx, const char *ifname)
00481 {
00482         struct wpa_driver_madwifi_data *drv;
00483 
00484         drv = os_zalloc(sizeof(*drv));
00485         if (drv == NULL)
00486                 return NULL;
00487         drv->wext = wpa_driver_wext_init(ctx, ifname);
00488         if (drv->wext == NULL)
00489                 goto fail;
00490 
00491         drv->ctx = ctx;
00492         os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));
00493         drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
00494         if (drv->sock < 0)
00495                 goto fail2;
00496 
00497         if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) {
00498                 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
00499                            "roaming", __FUNCTION__);
00500                 goto fail3;
00501         }
00502 
00503         if (set80211param(drv, IEEE80211_PARAM_WPA, 3, 1) < 0) {
00504                 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support",
00505                            __FUNCTION__);
00506                 goto fail3;
00507         }
00508 
00509         return drv;
00510 
00511 fail3:
00512         close(drv->sock);
00513 fail2:
00514         wpa_driver_wext_deinit(drv->wext);
00515 fail:
00516         os_free(drv);
00517         return NULL;
00518 }
00519 
00520 
00521 static void wpa_driver_madwifi_deinit(void *priv)
00522 {
00523         struct wpa_driver_madwifi_data *drv = priv;
00524 
00525         if (wpa_driver_madwifi_set_wpa_ie(drv, NULL, 0) < 0) {
00526                 wpa_printf(MSG_DEBUG, "%s: failed to clear WPA IE",
00527                            __FUNCTION__);
00528         }
00529         if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) {
00530                 wpa_printf(MSG_DEBUG, "%s: failed to enable driver-based "
00531                            "roaming", __FUNCTION__);
00532         }
00533         if (set80211param(drv, IEEE80211_PARAM_PRIVACY, 0, 1) < 0) {
00534                 wpa_printf(MSG_DEBUG, "%s: failed to disable forced Privacy "
00535                            "flag", __FUNCTION__);
00536         }
00537         if (set80211param(drv, IEEE80211_PARAM_WPA, 0, 1) < 0) {
00538                 wpa_printf(MSG_DEBUG, "%s: failed to disable WPA",
00539                            __FUNCTION__);
00540         }
00541 
00542         wpa_driver_wext_deinit(drv->wext);
00543 
00544         close(drv->sock);
00545         os_free(drv);
00546 }
00547 
00548 
00549 const struct wpa_driver_ops wpa_driver_madwifi_ops = {
00550         .name                   = "madwifi",
00551         .desc                   = "MADWIFI 802.11 support (Atheros, etc.)",
00552         .get_bssid              = wpa_driver_madwifi_get_bssid,
00553         .get_ssid               = wpa_driver_madwifi_get_ssid,
00554         .set_key                = wpa_driver_madwifi_set_key,
00555         .init                   = wpa_driver_madwifi_init,
00556         .deinit                 = wpa_driver_madwifi_deinit,
00557         .set_countermeasures    = wpa_driver_madwifi_set_countermeasures,
00558         .set_drop_unencrypted   = wpa_driver_madwifi_set_drop_unencrypted,
00559         .scan                   = wpa_driver_madwifi_scan,
00560         .get_scan_results       = wpa_driver_madwifi_get_scan_results,
00561         .deauthenticate         = wpa_driver_madwifi_deauthenticate,
00562         .disassociate           = wpa_driver_madwifi_disassociate,
00563         .associate              = wpa_driver_madwifi_associate,
00564         .set_auth_alg           = wpa_driver_madwifi_set_auth_alg,
00565         .set_operstate          = wpa_driver_madwifi_set_operstate,
00566 };
00567 

Generated on Sun Dec 31 13:48:52 2006 for wpa_supplicant by  doxygen 1.4.2