$search
00001 /* 00002 * WPA Supplicant - Driver interaction with Atmel Wireless LAN drivers 00003 * Copyright (c) 2000-2005, ATMEL Corporation 00004 * Copyright (c) 2004-2007, 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 00016 /****************************************************************************** 00017 Copyright 2000-2001 ATMEL Corporation. 00018 00019 WPA Supplicant - driver interaction with Atmel Wireless lan drivers. 00020 00021 This is free software; you can redistribute it and/or modify 00022 it under the terms of the GNU General Public License as published by 00023 the Free Software Foundation; either version 2 of the License, or 00024 (at your option) any later version. 00025 00026 This program is distributed in the hope that it will be useful, 00027 but WITHOUT ANY WARRANTY; without even the implied warranty of 00028 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00029 GNU General Public License for more details. 00030 00031 You should have received a copy of the GNU General Public License 00032 along with Atmel wireless lan drivers; if not, write to the Free Software 00033 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00034 00035 ******************************************************************************/ 00036 00037 /* 00038 * Alternatively, this software may be distributed under the terms of BSD 00039 * license. 00040 */ 00041 00042 #include "includes.h" 00043 #include <sys/ioctl.h> 00044 00045 #include "wireless_copy.h" 00046 #include "common.h" 00047 #include "driver.h" 00048 #include "driver_wext.h" 00049 00050 struct wpa_driver_atmel_data { 00051 void *wext; /* private data for driver_wext */ 00052 void *ctx; 00053 char ifname[IFNAMSIZ + 1]; 00054 int sock; 00055 }; 00056 00057 00058 #define ATMEL_WPA_IOCTL (SIOCIWFIRSTPRIV + 2) 00059 #define ATMEL_WPA_IOCTL_PARAM (SIOCIWFIRSTPRIV + 3) 00060 #define ATMEL_WPA_IOCTL_GET_PARAM (SIOCIWFIRSTPRIV + 4) 00061 00062 00063 /* ATMEL_WPA_IOCTL ioctl() cmd: */ 00064 enum { 00065 SET_WPA_ENCRYPTION = 1, 00066 SET_CIPHER_SUITES = 2, 00067 MLME_STA_DEAUTH = 3, 00068 MLME_STA_DISASSOC = 4 00069 }; 00070 00071 /* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */ 00072 enum { 00073 ATMEL_PARAM_WPA = 1, 00074 ATMEL_PARAM_PRIVACY_INVOKED = 2, 00075 ATMEL_PARAM_WPA_TYPE = 3 00076 }; 00077 00078 #define MAX_KEY_LENGTH 40 00079 00080 struct atmel_param{ 00081 unsigned char sta_addr[6]; 00082 int cmd; 00083 u8 alg; 00084 u8 key_idx; 00085 u8 set_tx; 00086 u8 seq[8]; 00087 u8 seq_len; 00088 u16 key_len; 00089 u8 key[MAX_KEY_LENGTH]; 00090 struct{ 00091 int reason_code; 00092 u8 state; 00093 }mlme; 00094 u8 pairwise_suite; 00095 u8 group_suite; 00096 u8 key_mgmt_suite; 00097 }; 00098 00099 00100 00101 static int atmel_ioctl(struct wpa_driver_atmel_data *drv, 00102 struct atmel_param *param, 00103 int len, int show_err) 00104 { 00105 struct iwreq iwr; 00106 00107 os_memset(&iwr, 0, sizeof(iwr)); 00108 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 00109 iwr.u.data.pointer = (caddr_t) param; 00110 iwr.u.data.length = len; 00111 00112 if (ioctl(drv->sock, ATMEL_WPA_IOCTL, &iwr) < 0) { 00113 int ret; 00114 ret = errno; 00115 if (show_err) 00116 perror("ioctl[ATMEL_WPA_IOCTL]"); 00117 return ret; 00118 } 00119 00120 return 0; 00121 } 00122 00123 00124 static int atmel2param(struct wpa_driver_atmel_data *drv, int param, int value) 00125 { 00126 struct iwreq iwr; 00127 int *i, ret = 0; 00128 00129 os_memset(&iwr, 0, sizeof(iwr)); 00130 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); 00131 i = (int *) iwr.u.name; 00132 *i++ = param; 00133 *i++ = value; 00134 00135 if (ioctl(drv->sock, ATMEL_WPA_IOCTL_PARAM, &iwr) < 0) { 00136 perror("ioctl[ATMEL_WPA_IOCTL_PARAM]"); 00137 ret = -1; 00138 } 00139 return ret; 00140 } 00141 00142 00143 #if 0 00144 static int wpa_driver_atmel_set_wpa_ie(struct wpa_driver_atmel_data *drv, 00145 const char *wpa_ie, size_t wpa_ie_len) 00146 { 00147 struct atmel_param *param; 00148 int res; 00149 size_t blen = ATMEL_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; 00150 if (blen < sizeof(*param)) 00151 blen = sizeof(*param); 00152 00153 param = os_zalloc(blen); 00154 if (param == NULL) 00155 return -1; 00156 00157 param->cmd = ATMEL_SET_GENERIC_ELEMENT; 00158 param->u.generic_elem.len = wpa_ie_len; 00159 os_memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); 00160 res = atmel_ioctl(drv, param, blen, 1); 00161 00162 os_free(param); 00163 00164 return res; 00165 } 00166 #endif 00167 00168 00169 static int wpa_driver_atmel_set_wpa(void *priv, int enabled) 00170 { 00171 struct wpa_driver_atmel_data *drv = priv; 00172 int ret = 0; 00173 00174 printf("wpa_driver_atmel_set_wpa %s\n", drv->ifname); 00175 00176 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 00177 00178 #if 0 00179 if (!enabled && wpa_driver_atmel_set_wpa_ie(drv, NULL, 0) < 0) 00180 ret = -1; 00181 #endif 00182 if (atmel2param(drv, ATMEL_PARAM_PRIVACY_INVOKED, enabled) < 0) 00183 ret = -1; 00184 if (atmel2param(drv, ATMEL_PARAM_WPA, enabled) < 0) 00185 ret = -1; 00186 00187 return ret; 00188 } 00189 00190 00191 static int wpa_driver_atmel_set_key(const char *ifname, void *priv, 00192 enum wpa_alg alg, const u8 *addr, 00193 int key_idx, int set_tx, 00194 const u8 *seq, size_t seq_len, 00195 const u8 *key, size_t key_len) 00196 { 00197 struct wpa_driver_atmel_data *drv = priv; 00198 int ret = 0; 00199 struct atmel_param *param; 00200 u8 *buf; 00201 u8 alg_type; 00202 00203 size_t blen; 00204 char *alg_name; 00205 00206 switch (alg) { 00207 case WPA_ALG_NONE: 00208 alg_name = "none"; 00209 alg_type = 0; 00210 break; 00211 case WPA_ALG_WEP: 00212 alg_name = "WEP"; 00213 alg_type = 1; 00214 break; 00215 case WPA_ALG_TKIP: 00216 alg_name = "TKIP"; 00217 alg_type = 2; 00218 break; 00219 case WPA_ALG_CCMP: 00220 alg_name = "CCMP"; 00221 alg_type = 3; 00222 break; 00223 default: 00224 return -1; 00225 } 00226 00227 wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " 00228 "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, 00229 (unsigned long) seq_len, (unsigned long) key_len); 00230 00231 if (seq_len > 8) 00232 return -2; 00233 00234 blen = sizeof(*param) + key_len; 00235 buf = os_zalloc(blen); 00236 if (buf == NULL) 00237 return -1; 00238 00239 param = (struct atmel_param *) buf; 00240 00241 param->cmd = SET_WPA_ENCRYPTION; 00242 00243 if (addr == NULL) 00244 os_memset(param->sta_addr, 0xff, ETH_ALEN); 00245 else 00246 os_memcpy(param->sta_addr, addr, ETH_ALEN); 00247 00248 param->alg = alg_type; 00249 param->key_idx = key_idx; 00250 param->set_tx = set_tx; 00251 os_memcpy(param->seq, seq, seq_len); 00252 param->seq_len = seq_len; 00253 param->key_len = key_len; 00254 os_memcpy((u8 *)param->key, key, key_len); 00255 00256 if (atmel_ioctl(drv, param, blen, 1)) { 00257 wpa_printf(MSG_WARNING, "Failed to set encryption."); 00258 /* TODO: show key error*/ 00259 ret = -1; 00260 } 00261 os_free(buf); 00262 00263 return ret; 00264 } 00265 00266 00267 static int wpa_driver_atmel_set_countermeasures(void *priv, 00268 int enabled) 00269 { 00270 /* FIX */ 00271 printf("wpa_driver_atmel_set_countermeasures - not yet " 00272 "implemented\n"); 00273 return 0; 00274 } 00275 00276 00277 static int wpa_driver_atmel_mlme(void *priv, const u8 *addr, int cmd, 00278 int reason_code) 00279 { 00280 struct wpa_driver_atmel_data *drv = priv; 00281 struct atmel_param param; 00282 int ret; 00283 int mgmt_error = 0xaa; 00284 00285 os_memset(¶m, 0, sizeof(param)); 00286 os_memcpy(param.sta_addr, addr, ETH_ALEN); 00287 param.cmd = cmd; 00288 param.mlme.reason_code = reason_code; 00289 param.mlme.state = mgmt_error; 00290 ret = atmel_ioctl(drv, ¶m, sizeof(param), 1); 00291 return ret; 00292 } 00293 00294 00295 #if 0 00296 static int wpa_driver_atmel_set_suites(struct wpa_driver_atmel_data *drv, 00297 u8 pairwise_suite, u8 group_suite, 00298 u8 key_mgmt_suite) 00299 { 00300 struct atmel_param param; 00301 int ret; 00302 00303 os_memset(¶m, 0, sizeof(param)); 00304 param.cmd = SET_CIPHER_SUITES; 00305 param.pairwise_suite = pairwise_suite; 00306 param.group_suite = group_suite; 00307 param.key_mgmt_suite = key_mgmt_suite; 00308 00309 ret = atmel_ioctl(drv, ¶m, sizeof(param), 1); 00310 return ret; 00311 } 00312 #endif 00313 00314 00315 static int wpa_driver_atmel_deauthenticate(void *priv, const u8 *addr, 00316 int reason_code) 00317 { 00318 struct wpa_driver_atmel_data *drv = priv; 00319 printf("wpa_driver_atmel_deauthenticate\n"); 00320 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 00321 return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DEAUTH, 00322 reason_code); 00323 00324 } 00325 00326 00327 static int wpa_driver_atmel_disassociate(void *priv, const u8 *addr, 00328 int reason_code) 00329 { 00330 struct wpa_driver_atmel_data *drv = priv; 00331 printf("wpa_driver_atmel_disassociate\n"); 00332 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); 00333 return wpa_driver_atmel_mlme(drv, addr, MLME_STA_DISASSOC, 00334 reason_code); 00335 00336 } 00337 00338 00339 #if 0 00340 /* Atmel driver uses specific values for each cipher suite */ 00341 static int convertSuiteToDriver(enum wpa_cipher suite) 00342 { 00343 u8 suite_type; 00344 00345 switch(suite) { 00346 case CIPHER_NONE: 00347 suite_type = 0; 00348 break; 00349 case CIPHER_WEP40: 00350 suite_type = 1; 00351 break; 00352 case CIPHER_TKIP: 00353 suite_type = 2; 00354 break; 00355 case CIPHER_WEP104: 00356 suite_type = 5; 00357 break; 00358 case CIPHER_CCMP: 00359 suite_type = 3; 00360 break; 00361 default: 00362 suite_type = 2; 00363 } 00364 00365 return suite_type; 00366 00367 } 00368 #endif 00369 00370 static int 00371 wpa_driver_atmel_associate(void *priv, 00372 struct wpa_driver_associate_params *params) 00373 { 00374 struct wpa_driver_atmel_data *drv = priv; 00375 int ret = 0; 00376 #if 0 00377 u8 pairwise_suite_driver; 00378 u8 group_suite_driver; 00379 u8 key_mgmt_suite_driver; 00380 00381 pairwise_suite_driver = convertSuiteToDriver(params->pairwise_suite); 00382 group_suite_driver = convertSuiteToDriver(params->group_suite); 00383 key_mgmt_suite_driver = convertSuiteToDriver(params->key_mgmt_suite); 00384 00385 if (wpa_driver_atmel_set_suites(drv, pairwise_suite_driver, 00386 group_suite_driver, 00387 key_mgmt_suite_driver) < 0){ 00388 printf("wpa_driver_atmel_set_suites.\n"); 00389 ret = -1; 00390 } 00391 if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0) { 00392 printf("wpa_driver_atmel_set_freq.\n"); 00393 ret = -1; 00394 } 00395 #endif 00396 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) 00397 < 0) { 00398 printf("FAILED : wpa_driver_atmel_set_ssid.\n"); 00399 ret = -1; 00400 } 00401 if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0) { 00402 printf("FAILED : wpa_driver_atmel_set_bssid.\n"); 00403 ret = -1; 00404 } 00405 00406 return ret; 00407 } 00408 00409 00410 static int wpa_driver_atmel_get_bssid(void *priv, u8 *bssid) 00411 { 00412 struct wpa_driver_atmel_data *drv = priv; 00413 return wpa_driver_wext_get_bssid(drv->wext, bssid); 00414 } 00415 00416 00417 static int wpa_driver_atmel_get_ssid(void *priv, u8 *ssid) 00418 { 00419 struct wpa_driver_atmel_data *drv = priv; 00420 return wpa_driver_wext_get_ssid(drv->wext, ssid); 00421 } 00422 00423 00424 static int wpa_driver_atmel_scan(void *priv, 00425 struct wpa_driver_scan_params *params) 00426 { 00427 struct wpa_driver_atmel_data *drv = priv; 00428 return wpa_driver_wext_scan(drv->wext, params); 00429 } 00430 00431 00432 static struct wpa_scan_results * wpa_driver_atmel_get_scan_results(void *priv) 00433 { 00434 struct wpa_driver_atmel_data *drv = priv; 00435 return wpa_driver_wext_get_scan_results(drv->wext); 00436 } 00437 00438 00439 static int wpa_driver_atmel_set_operstate(void *priv, int state) 00440 { 00441 struct wpa_driver_atmel_data *drv = priv; 00442 return wpa_driver_wext_set_operstate(drv->wext, state); 00443 } 00444 00445 00446 static void * wpa_driver_atmel_init(void *ctx, const char *ifname) 00447 { 00448 struct wpa_driver_atmel_data *drv; 00449 00450 drv = os_zalloc(sizeof(*drv)); 00451 if (drv == NULL) 00452 return NULL; 00453 drv->wext = wpa_driver_wext_init(ctx, ifname); 00454 if (drv->wext == NULL) { 00455 os_free(drv); 00456 return NULL; 00457 } 00458 00459 drv->ctx = ctx; 00460 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 00461 drv->sock = socket(PF_INET, SOCK_DGRAM, 0); 00462 if (drv->sock < 0) { 00463 wpa_driver_wext_deinit(drv->wext); 00464 os_free(drv); 00465 return NULL; 00466 } 00467 00468 wpa_driver_atmel_set_wpa(drv, 1); 00469 00470 return drv; 00471 } 00472 00473 00474 static void wpa_driver_atmel_deinit(void *priv) 00475 { 00476 struct wpa_driver_atmel_data *drv = priv; 00477 wpa_driver_atmel_set_wpa(drv, 0); 00478 wpa_driver_wext_deinit(drv->wext); 00479 close(drv->sock); 00480 os_free(drv); 00481 } 00482 00483 00484 const struct wpa_driver_ops wpa_driver_atmel_ops = { 00485 .name = "atmel", 00486 .desc = "ATMEL AT76C5XXx (USB, PCMCIA)", 00487 .get_bssid = wpa_driver_atmel_get_bssid, 00488 .get_ssid = wpa_driver_atmel_get_ssid, 00489 .set_key = wpa_driver_atmel_set_key, 00490 .init = wpa_driver_atmel_init, 00491 .deinit = wpa_driver_atmel_deinit, 00492 .set_countermeasures = wpa_driver_atmel_set_countermeasures, 00493 .scan2 = wpa_driver_atmel_scan, 00494 .get_scan_results2 = wpa_driver_atmel_get_scan_results, 00495 .deauthenticate = wpa_driver_atmel_deauthenticate, 00496 .disassociate = wpa_driver_atmel_disassociate, 00497 .associate = wpa_driver_atmel_associate, 00498 .set_operstate = wpa_driver_atmel_set_operstate, 00499 };