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