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