driver_ndiswrapper.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - driver interaction with Linux ndiswrapper
00003  * Copyright (c) 2004-2006, Giridhar Pemmasani <giri@lmc.cs.sunysb.edu>
00004  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License version 2 as
00008  * published by the Free Software Foundation.
00009  *
00010  * Alternatively, this software may be distributed under the terms of BSD
00011  * license.
00012  *
00013  * See README and COPYING for more details.
00014  *
00015  * Please note that ndiswrapper supports WPA configuration via Linux wireless
00016  * extensions and if the kernel includes support for this, driver_wext.c should
00017  * be used instead of this driver wrapper.
00018  */
00019 
00020 #include "includes.h"
00021 #include <sys/ioctl.h>
00022 
00023 #include "wireless_copy.h"
00024 #include "common.h"
00025 #include "driver.h"
00026 #include "driver_wext.h"
00027 
00028 struct wpa_driver_ndiswrapper_data {
00029         void *wext; /* private data for driver_wext */
00030         void *ctx;
00031         char ifname[IFNAMSIZ + 1];
00032         int sock;
00033 };
00034 
00035 
00036 struct wpa_key {
00037         enum wpa_alg alg;
00038         const u8 *addr;
00039         int key_index;
00040         int set_tx;
00041         const u8 *seq;
00042         size_t seq_len;
00043         const u8 *key;
00044         size_t key_len;
00045 };
00046 
00047 struct wpa_assoc_info {
00048         const u8 *bssid;
00049         const u8 *ssid;
00050         size_t ssid_len;
00051         int freq;
00052         const u8 *wpa_ie;
00053         size_t wpa_ie_len;
00054         enum wpa_cipher pairwise_suite;
00055         enum wpa_cipher group_suite;
00056         enum wpa_key_mgmt key_mgmt_suite;
00057         int auth_alg;
00058         int mode;
00059 };
00060 
00061 #define PRIV_RESET                      SIOCIWFIRSTPRIV+0
00062 #define WPA_SET_WPA                     SIOCIWFIRSTPRIV+1
00063 #define WPA_SET_KEY                     SIOCIWFIRSTPRIV+2
00064 #define WPA_ASSOCIATE                   SIOCIWFIRSTPRIV+3
00065 #define WPA_DISASSOCIATE                SIOCIWFIRSTPRIV+4
00066 #define WPA_DROP_UNENCRYPTED            SIOCIWFIRSTPRIV+5
00067 #define WPA_SET_COUNTERMEASURES         SIOCIWFIRSTPRIV+6
00068 #define WPA_DEAUTHENTICATE              SIOCIWFIRSTPRIV+7
00069 #define WPA_SET_AUTH_ALG                SIOCIWFIRSTPRIV+8
00070 #define WPA_INIT                        SIOCIWFIRSTPRIV+9
00071 #define WPA_DEINIT                      SIOCIWFIRSTPRIV+10
00072 #define WPA_GET_CAPA                    SIOCIWFIRSTPRIV+11
00073 
00074 static int wpa_ndiswrapper_set_auth_alg(void *priv, int auth_alg);
00075 
00076 static int get_socket(void)
00077 {
00078         static const int families[] = {
00079                 AF_INET, AF_IPX, AF_AX25, AF_APPLETALK
00080         };
00081         unsigned int i;
00082         int sock;
00083 
00084         for (i = 0; i < sizeof(families) / sizeof(int); ++i) {
00085                 sock = socket(families[i], SOCK_DGRAM, 0);
00086                 if (sock >= 0)
00087                         return sock;
00088         }
00089 
00090         return -1;
00091 }
00092 
00093 static int iw_set_ext(struct wpa_driver_ndiswrapper_data *drv, int request,
00094                       struct iwreq *pwrq)
00095 {
00096         os_strlcpy(pwrq->ifr_name, drv->ifname, IFNAMSIZ);
00097         return ioctl(drv->sock, request, pwrq);
00098 }
00099 
00100 static int wpa_ndiswrapper_set_wpa(void *priv, int enabled)
00101 {
00102         struct wpa_driver_ndiswrapper_data *drv = priv;
00103         struct iwreq priv_req;
00104         int ret = 0;
00105 
00106         os_memset(&priv_req, 0, sizeof(priv_req));
00107 
00108         priv_req.u.data.flags = enabled;
00109         if (iw_set_ext(drv, WPA_SET_WPA, &priv_req) < 0)
00110                 ret = -1;
00111         return ret;
00112 }
00113 
00114 static int wpa_ndiswrapper_set_key(const char *ifname, void *priv,
00115                                    enum wpa_alg alg, const u8 *addr,
00116                                    int key_idx, int set_tx,
00117                                    const u8 *seq, size_t seq_len,
00118                                    const u8 *key, size_t key_len)
00119 {
00120         struct wpa_driver_ndiswrapper_data *drv = priv;
00121         struct wpa_key wpa_key;
00122         int ret = 0;
00123         struct iwreq priv_req;
00124 
00125         os_memset(&priv_req, 0, sizeof(priv_req));
00126 
00127         wpa_key.alg = alg;
00128         wpa_key.addr = addr;
00129         wpa_key.key_index = key_idx;
00130         wpa_key.set_tx = set_tx;
00131         wpa_key.seq = seq;
00132         wpa_key.seq_len = seq_len;
00133         wpa_key.key = key;
00134         wpa_key.key_len = key_len;
00135 
00136         priv_req.u.data.pointer = (void *)&wpa_key;
00137         priv_req.u.data.length = sizeof(wpa_key);
00138 
00139         if (iw_set_ext(drv, WPA_SET_KEY, &priv_req) < 0)
00140                 ret = -1;
00141 
00142         if (alg == WPA_ALG_NONE) {
00143                 /*
00144                  * ndiswrapper did not seem to be clearing keys properly in
00145                  * some cases with WPA_SET_KEY. For example, roaming from WPA
00146                  * enabled AP to plaintext one seemed to fail since the driver
00147                  * did not associate. Try to make sure the keys are cleared so
00148                  * that plaintext APs can be used in all cases.
00149                  */
00150                 wpa_driver_wext_set_key(ifname, drv->wext, alg, addr, key_idx,
00151                                         set_tx, seq, seq_len, key, key_len);
00152         }
00153 
00154         return ret;
00155 }
00156 
00157 static int wpa_ndiswrapper_set_countermeasures(void *priv, int enabled)
00158 {
00159         struct wpa_driver_ndiswrapper_data *drv = priv;
00160         int ret = 0;
00161         struct iwreq priv_req;
00162 
00163         os_memset(&priv_req, 0, sizeof(priv_req));
00164 
00165         priv_req.u.param.value = enabled;
00166         if (iw_set_ext(drv, WPA_SET_COUNTERMEASURES, &priv_req) < 0)
00167                 ret = -1;
00168 
00169         return ret;
00170 }
00171 
00172 static int wpa_ndiswrapper_set_drop_unencrypted(void *priv,
00173                                                 int enabled)
00174 {
00175         struct wpa_driver_ndiswrapper_data *drv = priv;
00176         int ret = 0;
00177         struct iwreq priv_req;
00178 
00179         os_memset(&priv_req, 0, sizeof(priv_req));
00180 
00181         priv_req.u.param.value = enabled;
00182         if (iw_set_ext(drv, WPA_DROP_UNENCRYPTED, &priv_req) < 0)
00183                 ret = -1;
00184         return ret;
00185 }
00186 
00187 static int wpa_ndiswrapper_deauthenticate(void *priv, const u8 *addr,
00188                                           int reason_code)
00189 {
00190         struct wpa_driver_ndiswrapper_data *drv = priv;
00191         int ret = 0;
00192         struct iwreq priv_req;
00193 
00194         os_memset(&priv_req, 0, sizeof(priv_req));
00195 
00196         priv_req.u.param.value = reason_code;
00197         os_memcpy(&priv_req.u.ap_addr.sa_data, addr, ETH_ALEN);
00198         if (iw_set_ext(drv, WPA_DEAUTHENTICATE, &priv_req) < 0)
00199                 ret = -1;
00200         return ret;
00201 }
00202 
00203 static int wpa_ndiswrapper_disassociate(void *priv, const u8 *addr,
00204                                         int reason_code)
00205 {
00206         struct wpa_driver_ndiswrapper_data *drv = priv;
00207         int ret = 0;
00208         struct iwreq priv_req;
00209 
00210         os_memset(&priv_req, 0, sizeof(priv_req));
00211 
00212         os_memcpy(&priv_req.u.ap_addr.sa_data, addr, ETH_ALEN);
00213         if (iw_set_ext(drv, WPA_DISASSOCIATE, &priv_req) < 0)
00214                 ret = -1;
00215         return ret;
00216 }
00217 
00218 static int
00219 wpa_ndiswrapper_associate(void *priv,
00220                           struct wpa_driver_associate_params *params)
00221 {
00222         struct wpa_driver_ndiswrapper_data *drv = priv;
00223         int ret = 0;
00224         struct wpa_assoc_info wpa_assoc_info;
00225         struct iwreq priv_req;
00226 
00227         if (wpa_ndiswrapper_set_drop_unencrypted(drv,
00228                                                  params->drop_unencrypted) < 0)
00229                 ret = -1;
00230         if (wpa_ndiswrapper_set_auth_alg(drv, params->auth_alg) < 0)
00231                 ret = -1;
00232 
00233         os_memset(&priv_req, 0, sizeof(priv_req));
00234         os_memset(&wpa_assoc_info, 0, sizeof(wpa_assoc_info));
00235 
00236         wpa_assoc_info.bssid = params->bssid;
00237         wpa_assoc_info.ssid = params->ssid;
00238         wpa_assoc_info.ssid_len = params->ssid_len;
00239         wpa_assoc_info.freq = params->freq;
00240         wpa_assoc_info.wpa_ie = params->wpa_ie;
00241         wpa_assoc_info.wpa_ie_len = params->wpa_ie_len;
00242         wpa_assoc_info.pairwise_suite = params->pairwise_suite;
00243         wpa_assoc_info.group_suite = params->group_suite;
00244         wpa_assoc_info.key_mgmt_suite = params->key_mgmt_suite;
00245         wpa_assoc_info.auth_alg = params->auth_alg;
00246         wpa_assoc_info.mode = params->mode;
00247 
00248         priv_req.u.data.pointer = (void *)&wpa_assoc_info;
00249         priv_req.u.data.length = sizeof(wpa_assoc_info);
00250 
00251         if (iw_set_ext(drv, WPA_ASSOCIATE, &priv_req) < 0)
00252                 ret = -1;
00253         return ret;
00254 }
00255 
00256 static int wpa_ndiswrapper_set_auth_alg(void *priv, int auth_alg)
00257 {
00258         struct wpa_driver_ndiswrapper_data *drv = priv;
00259         int ret = 0;
00260         struct iwreq priv_req;
00261 
00262         os_memset(&priv_req, 0, sizeof(priv_req));
00263 
00264         priv_req.u.param.value = auth_alg;
00265         if (iw_set_ext(drv, WPA_SET_AUTH_ALG, &priv_req) < 0)
00266                 ret = -1;
00267         return ret;
00268 }
00269 
00270 static int wpa_ndiswrapper_get_bssid(void *priv, u8 *bssid)
00271 {
00272         struct wpa_driver_ndiswrapper_data *drv = priv;
00273         return wpa_driver_wext_get_bssid(drv->wext, bssid);
00274 }
00275 
00276 
00277 static int wpa_ndiswrapper_get_ssid(void *priv, u8 *ssid)
00278 {
00279         struct wpa_driver_ndiswrapper_data *drv = priv;
00280         return wpa_driver_wext_get_ssid(drv->wext, ssid);
00281 }
00282 
00283 
00284 static int wpa_ndiswrapper_scan(void *priv,
00285                                 struct wpa_driver_scan_params *params)
00286 {
00287         struct wpa_driver_ndiswrapper_data *drv = priv;
00288         return wpa_driver_wext_scan(drv->wext, params);
00289 }
00290 
00291 
00292 static struct wpa_scan_results * wpa_ndiswrapper_get_scan_results(void *priv)
00293 {
00294         struct wpa_driver_ndiswrapper_data *drv = priv;
00295         return wpa_driver_wext_get_scan_results(drv->wext);
00296 }
00297 
00298 
00299 static int wpa_ndiswrapper_get_capa(void *priv, struct wpa_driver_capa *capa)
00300 {
00301         struct wpa_driver_ndiswrapper_data *drv = priv;
00302         int ret = 0;
00303         struct iwreq priv_req;
00304 
00305         os_memset(&priv_req, 0, sizeof(priv_req));
00306 
00307         priv_req.u.data.pointer = (void *) capa;
00308         priv_req.u.data.length = sizeof(*capa);
00309         if (iw_set_ext(drv, WPA_GET_CAPA, &priv_req) < 0)
00310                 ret = -1;
00311         return ret;
00312         
00313 }
00314 
00315 
00316 static int wpa_ndiswrapper_set_operstate(void *priv, int state)
00317 {
00318         struct wpa_driver_ndiswrapper_data *drv = priv;
00319         return wpa_driver_wext_set_operstate(drv->wext, state);
00320 }
00321 
00322 
00323 static void * wpa_ndiswrapper_init(void *ctx, const char *ifname)
00324 {
00325         struct wpa_driver_ndiswrapper_data *drv;
00326 
00327         drv = os_zalloc(sizeof(*drv));
00328         if (drv == NULL)
00329                 return NULL;
00330         drv->wext = wpa_driver_wext_init(ctx, ifname);
00331         if (drv->wext == NULL) {
00332                 os_free(drv);
00333                 return NULL;
00334         }
00335 
00336         drv->ctx = ctx;
00337         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
00338         drv->sock = get_socket();
00339         if (drv->sock < 0) {
00340                 wpa_driver_wext_deinit(drv->wext);
00341                 os_free(drv);
00342                 return NULL;
00343         }
00344 
00345         wpa_ndiswrapper_set_wpa(drv, 1);
00346 
00347         return drv;
00348 }
00349 
00350 
00351 static void wpa_ndiswrapper_deinit(void *priv)
00352 {
00353         struct wpa_driver_ndiswrapper_data *drv = priv;
00354         wpa_ndiswrapper_set_wpa(drv, 0);
00355         wpa_driver_wext_deinit(drv->wext);
00356         close(drv->sock);
00357         os_free(drv);
00358 }
00359 
00360 
00361 const struct wpa_driver_ops wpa_driver_ndiswrapper_ops = {
00362         .name = "ndiswrapper",
00363         .desc = "Linux ndiswrapper (deprecated; use wext)",
00364         .set_key = wpa_ndiswrapper_set_key,
00365         .set_countermeasures = wpa_ndiswrapper_set_countermeasures,
00366         .deauthenticate = wpa_ndiswrapper_deauthenticate,
00367         .disassociate = wpa_ndiswrapper_disassociate,
00368         .associate = wpa_ndiswrapper_associate,
00369 
00370         .get_bssid = wpa_ndiswrapper_get_bssid,
00371         .get_ssid = wpa_ndiswrapper_get_ssid,
00372         .scan2 = wpa_ndiswrapper_scan,
00373         .get_scan_results2 = wpa_ndiswrapper_get_scan_results,
00374         .init = wpa_ndiswrapper_init,
00375         .deinit = wpa_ndiswrapper_deinit,
00376         .get_capa = wpa_ndiswrapper_get_capa,
00377         .set_operstate = wpa_ndiswrapper_set_operstate,
00378 };


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34