$search
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 };