driver_madwifi.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - driver interaction with MADWIFI 802.11 driver
00003  * Copyright (c) 2004, Sam Leffler <sam@errno.com>
00004  * Copyright (c) 2004, Video54 Technologies
00005  * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation.
00010  *
00011  * Alternatively, this software may be distributed under the terms of BSD
00012  * license.
00013  *
00014  * See README and COPYING for more details.
00015  *
00016  * While this driver wrapper supports both AP (hostapd) and station
00017  * (wpa_supplicant) operations, the station side is deprecated and
00018  * driver_wext.c should be used instead. This driver wrapper should only be
00019  * used with hostapd for AP mode functionality.
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  * Avoid conflicts with wpa_supplicant definitions by undefining a definition.
00034  */
00035 #undef WME_OUI_TYPE
00036 
00037 #include <include/compat.h>
00038 #include <net80211/ieee80211.h>
00039 #ifdef WME_NUM_AC
00040 /* Assume this is built against BSD branch of madwifi driver. */
00041 #define MADWIFI_BSD
00042 #include <net80211/_ieee80211.h>
00043 #endif /* WME_NUM_AC */
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 /* IEEE80211_IOCTL_FILTERFRAME */
00055 #endif /* CONFIG_WPS */
00056 
00057 /*
00058  * Avoid conflicts with hostapd definitions by undefining couple of defines
00059  * from madwifi header files.
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 /* Assume this is built against madwifi-ng */
00069 #define MADWIFI_NG
00070 #endif /* IEEE80211_IOCTL_SETWMMPARAMS */
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;              /* back pointer */
00083 
00084         char    iface[IFNAMSIZ + 1];
00085         int     ifindex;
00086         struct l2_packet_data *sock_xmit;       /* raw packet xmit socket */
00087         struct l2_packet_data *sock_recv;       /* raw packet recv socket */
00088         int     ioctl_sock;                     /* socket for ioctl() use */
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; /* raw 802.11 management frames */
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         /* FILTERFRAME must be NOT inline, regardless of size. */
00110         if (op == IEEE80211_IOCTL_FILTERFRAME)
00111                 do_inline = 0;
00112 #endif /* IEEE80211_IOCTL_FILTERFRAME */
00113         if (op == IEEE80211_IOCTL_SET_APPIEBUF)
00114                 do_inline = 0;
00115         if (do_inline) {
00116                 /*
00117                  * Argument data fits inline; put it there.
00118                  */
00119                 memcpy(iwr.u.name, data, len);
00120         } else {
00121                 /*
00122                  * Argument data too big for inline transfer; setup a
00123                  * parameter block instead; the kernel will transfer
00124                  * the data for the driver.
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 /* MADWIFI_NG */
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 /* MADWIFI_NG */
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 /* CONFIG_NO_STDOUT_DEBUG */
00234 
00235 /*
00236  * Configure WPA parameters.
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                 /* key length is done only for specific ciphers */
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                 /* XXX restore state */
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         /* For now, only support setting Authorized flag */
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                  * wk.ik_keytsc is in host byte order (big endian), need to
00515                  * swap it to match with the byte order used in WPA.
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 /* WORDS_BIGENDIAN */
00525         memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
00526 #endif /* WORDS_BIGENDIAN */
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 /* MADWIFI_BSD */
00540         return 0;               /* XXX */
00541 #endif /* MADWIFI_BSD */
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          * Fetch statistics for station from the system.
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 /* MADWIFI_NG */
00565                          IEEE80211_IOCTL_GETSTASTATS,
00566 #endif /* MADWIFI_NG */
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 /* MADWIFI_BSD */
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         /* Need to read proc file with in one piece, so use large enough
00603          * buffer. */
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 /* MADWIFI_BSD */
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 /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
00650         return 0; /* FIX */
00651 #endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
00652 }
00653 
00654 
00655 static int
00656 madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
00657 {
00658         /*
00659          * Do nothing; we setup parameters at startup that define the
00660          * contents of the beacon information element.
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         /* Send Probe Request information to WPS processing */
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 /* IEEE80211_IOCTL_FILTERFRAME */
00742 #endif /* CONFIG_WPS */
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 /* IEEE80211_IOCTL_FILTERFRAME */
00764 #endif /* CONFIG_WPS */
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 /* CONFIG_WPS */
00802 #define madwifi_set_ap_wps_ie NULL
00803 #endif /* CONFIG_WPS */
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          * Fetch negotiated WPA/RSN parameters from the system.
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         /* madwifi seems to return some random data if WPA/RSN IE is not set.
00827          * Assume the IE was not included if the IE type is unknown. */
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                 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
00835                  * set. This is needed for WPA2. */
00836                 iebuf = ie.rsn_ie;
00837                 if (iebuf[0] != WLAN_EID_RSN)
00838                         iebuf[1] = 0;
00839         }
00840 #endif /* MADWIFI_NG */
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                 /* Cached accounting data is not valid anymore. */
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                 /* Event data may be unaligned, so make a local, aligned copy
00925                  * before processing. */
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                         /* WE-19 removed the pointer from struct iw_point */
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;         /* XXX */
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          * Use larger buffer than struct iw_range in order to allow the
01010          * structure to grow in the future.
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          * Prepend the Ethernet header.  If the caller left us
01079          * space at the front we could just insert it but since
01080          * we don't know we copy to a local buffer.  Given the frequency
01081          * and size of frames this probably doesn't matter.
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         /* mark down during setup */
01181         linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
01182         madwifi_set_privacy(drv, 0); /* default to no privacy */
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; /* SSID active */
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 /* HOSTAPD */
01276 
01277 struct wpa_driver_madwifi_data {
01278         void *wext; /* private data for driver_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                  * Argument data fits inline; put it there.
01301                  */
01302                 os_memcpy(iwr.u.name, data, len);
01303         } else {
01304                 /*
01305                  * Argument data too big for inline transfer; setup a
01306                  * parameter block instead; the kernel will transfer
01307                  * the data for the driver.
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 /* MADWIFI_NG */
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 /* MADWIFI_NG */
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         /* NB: SETOPTIE is not fixed-size so must not be inlined */
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                          * madwifi did not seem to like static WEP key
01458                          * configuration with IEEE80211_IOCTL_SETKEY, so use
01459                          * Linux wireless extensions ioctl for this.
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 /* WORDS_BIGENDIAN */
01522         os_memcpy(&wk.ik_keyrsc, seq, seq_len);
01523 #endif /* WORDS_BIGENDIAN */
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          * NB: Don't need to set the freq or cipher-related state as
01581          *     this is implied by the bssid which is used to locate
01582          *     the scanned node state which holds it.  The ssid is
01583          *     needed to disambiguate an AP that broadcasts multiple
01584          *     ssid's but uses the same bssid.
01585          */
01586         /* XXX error handling is wrong but unclear what to do... */
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                 /* ap_scan=2 mode - driver takes care of AP selection and
01607                  * roaming */
01608                 /* FIX: this does not seem to work; would probably need to
01609                  * change something in the driver */
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         /* set desired ssid before scan */
01669         /* FIX: scan should not break the current association, so using
01670          * set_ssid may not be the best way of doing this.. */
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          * madwifi delivers a scan complete event so no need to poll, but
01681          * register a backup timeout anyway to make sure that we recover even
01682          * if the driver does not send this event for any reason. This timeout
01683          * will only be used if the event is not delivered (event handler will
01684          * cancel the timeout).
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 /* HOSTAPD */
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 /* HOSTAPD */
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 /* HOSTAPD */
01854 };


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:36