$search
00001 /* 00002 * hostapd / Driver interaction with Atheros driver 00003 * Copyright (c) 2004, Sam Leffler <sam@errno.com> 00004 * Copyright (c) 2004, Video54 Technologies 00005 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi> 00006 * Copyright (c) 2009, Atheros Communications 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License version 2 as 00010 * published by the Free Software Foundation. 00011 * 00012 * Alternatively, this software may be distributed under the terms of BSD 00013 * license. 00014 * 00015 * See README and COPYING for more details. 00016 */ 00017 00018 #include "includes.h" 00019 #include <net/if.h> 00020 #include <sys/ioctl.h> 00021 00022 #include "common.h" 00023 #ifndef _BYTE_ORDER 00024 #ifdef WORDS_BIGENDIAN 00025 #define _BYTE_ORDER _BIG_ENDIAN 00026 #else 00027 #define _BYTE_ORDER _LITTLE_ENDIAN 00028 #endif 00029 #endif /* _BYTE_ORDER */ 00030 00031 /* 00032 * Note, the ATH_WPS_IE setting must match with the driver build.. If the 00033 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail. 00034 */ 00035 #define ATH_WPS_IE 00036 00037 #include "os/linux/include/ieee80211_external.h" 00038 00039 00040 #ifdef CONFIG_WPS 00041 #include <netpacket/packet.h> 00042 00043 #ifndef ETH_P_80211_RAW 00044 #define ETH_P_80211_RAW 0x0019 00045 #endif 00046 #endif /* CONFIG_WPS */ 00047 00048 #include "wireless_copy.h" 00049 00050 #include "driver.h" 00051 #include "eloop.h" 00052 #include "priv_netlink.h" 00053 #include "l2_packet/l2_packet.h" 00054 #include "common/ieee802_11_defs.h" 00055 #include "netlink.h" 00056 #include "linux_ioctl.h" 00057 00058 00059 struct madwifi_driver_data { 00060 struct hostapd_data *hapd; /* back pointer */ 00061 00062 char iface[IFNAMSIZ + 1]; 00063 int ifindex; 00064 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 00065 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 00066 int ioctl_sock; /* socket for ioctl() use */ 00067 struct netlink_data *netlink; 00068 int we_version; 00069 u8 acct_mac[ETH_ALEN]; 00070 struct hostap_sta_driver_data acct_data; 00071 00072 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 00073 }; 00074 00075 static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 00076 int reason_code); 00077 00078 static const char * athr_get_ioctl_name(int op) 00079 { 00080 switch (op) { 00081 case IEEE80211_IOCTL_SETPARAM: 00082 return "SETPARAM"; 00083 case IEEE80211_IOCTL_GETPARAM: 00084 return "GETPARAM"; 00085 case IEEE80211_IOCTL_SETKEY: 00086 return "SETKEY"; 00087 case IEEE80211_IOCTL_SETWMMPARAMS: 00088 return "SETWMMPARAMS"; 00089 case IEEE80211_IOCTL_DELKEY: 00090 return "DELKEY"; 00091 case IEEE80211_IOCTL_GETWMMPARAMS: 00092 return "GETWMMPARAMS"; 00093 case IEEE80211_IOCTL_SETMLME: 00094 return "SETMLME"; 00095 case IEEE80211_IOCTL_GETCHANINFO: 00096 return "GETCHANINFO"; 00097 case IEEE80211_IOCTL_SETOPTIE: 00098 return "SETOPTIE"; 00099 case IEEE80211_IOCTL_GETOPTIE: 00100 return "GETOPTIE"; 00101 case IEEE80211_IOCTL_ADDMAC: 00102 return "ADDMAC"; 00103 case IEEE80211_IOCTL_DELMAC: 00104 return "DELMAC"; 00105 case IEEE80211_IOCTL_GETCHANLIST: 00106 return "GETCHANLIST"; 00107 case IEEE80211_IOCTL_SETCHANLIST: 00108 return "SETCHANLIST"; 00109 case IEEE80211_IOCTL_KICKMAC: 00110 return "KICKMAC"; 00111 case IEEE80211_IOCTL_CHANSWITCH: 00112 return "CHANSWITCH"; 00113 case IEEE80211_IOCTL_GETMODE: 00114 return "GETMODE"; 00115 case IEEE80211_IOCTL_SETMODE: 00116 return "SETMODE"; 00117 case IEEE80211_IOCTL_GET_APPIEBUF: 00118 return "GET_APPIEBUF"; 00119 case IEEE80211_IOCTL_SET_APPIEBUF: 00120 return "SET_APPIEBUF"; 00121 case IEEE80211_IOCTL_SET_ACPARAMS: 00122 return "SET_ACPARAMS"; 00123 case IEEE80211_IOCTL_FILTERFRAME: 00124 return "FILTERFRAME"; 00125 case IEEE80211_IOCTL_SET_RTPARAMS: 00126 return "SET_RTPARAMS"; 00127 case IEEE80211_IOCTL_SENDADDBA: 00128 return "SENDADDBA"; 00129 case IEEE80211_IOCTL_GETADDBASTATUS: 00130 return "GETADDBASTATUS"; 00131 case IEEE80211_IOCTL_SENDDELBA: 00132 return "SENDDELBA"; 00133 case IEEE80211_IOCTL_SET_MEDENYENTRY: 00134 return "SET_MEDENYENTRY"; 00135 case IEEE80211_IOCTL_SET_ADDBARESP: 00136 return "SET_ADDBARESP"; 00137 case IEEE80211_IOCTL_GET_MACADDR: 00138 return "GET_MACADDR"; 00139 case IEEE80211_IOCTL_SET_HBRPARAMS: 00140 return "SET_HBRPARAMS"; 00141 case IEEE80211_IOCTL_SET_RXTIMEOUT: 00142 return "SET_RXTIMEOUT"; 00143 case IEEE80211_IOCTL_STA_STATS: 00144 return "STA_STATS"; 00145 case IEEE80211_IOCTL_GETWPAIE: 00146 return "GETWPAIE"; 00147 default: 00148 return "??"; 00149 } 00150 } 00151 00152 00153 static const char * athr_get_param_name(int op) 00154 { 00155 switch (op) { 00156 case IEEE80211_IOC_MCASTCIPHER: 00157 return "MCASTCIPHER"; 00158 case IEEE80211_PARAM_MCASTKEYLEN: 00159 return "MCASTKEYLEN"; 00160 case IEEE80211_PARAM_UCASTCIPHERS: 00161 return "UCASTCIPHERS"; 00162 case IEEE80211_PARAM_KEYMGTALGS: 00163 return "KEYMGTALGS"; 00164 case IEEE80211_PARAM_RSNCAPS: 00165 return "RSNCAPS"; 00166 case IEEE80211_PARAM_WPA: 00167 return "WPA"; 00168 case IEEE80211_PARAM_AUTHMODE: 00169 return "AUTHMODE"; 00170 case IEEE80211_PARAM_PRIVACY: 00171 return "PRIVACY"; 00172 case IEEE80211_PARAM_COUNTERMEASURES: 00173 return "COUNTERMEASURES"; 00174 default: 00175 return "??"; 00176 } 00177 } 00178 00179 00180 static int 00181 set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len) 00182 { 00183 struct iwreq iwr; 00184 int do_inline = len < IFNAMSIZ; 00185 00186 /* Certain ioctls must use the non-inlined method */ 00187 if (op == IEEE80211_IOCTL_SET_APPIEBUF || 00188 op == IEEE80211_IOCTL_FILTERFRAME) 00189 do_inline = 0; 00190 00191 memset(&iwr, 0, sizeof(iwr)); 00192 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 00193 if (do_inline) { 00194 /* 00195 * Argument data fits inline; put it there. 00196 */ 00197 memcpy(iwr.u.name, data, len); 00198 } else { 00199 /* 00200 * Argument data too big for inline transfer; setup a 00201 * parameter block instead; the kernel will transfer 00202 * the data for the driver. 00203 */ 00204 iwr.u.data.pointer = data; 00205 iwr.u.data.length = len; 00206 } 00207 00208 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 00209 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " 00210 "(%s) len=%d failed: %d (%s)", 00211 __func__, drv->iface, op, 00212 athr_get_ioctl_name(op), 00213 len, errno, strerror(errno)); 00214 return -1; 00215 } 00216 return 0; 00217 } 00218 00219 static int 00220 set80211param(struct madwifi_driver_data *drv, int op, int arg) 00221 { 00222 struct iwreq iwr; 00223 00224 memset(&iwr, 0, sizeof(iwr)); 00225 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 00226 iwr.u.mode = op; 00227 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); 00228 00229 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 00230 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 00231 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d " 00232 "(%s) arg %d)", __func__, drv->iface, op, 00233 athr_get_param_name(op), arg); 00234 return -1; 00235 } 00236 return 0; 00237 } 00238 00239 #ifndef CONFIG_NO_STDOUT_DEBUG 00240 static const char * 00241 ether_sprintf(const u8 *addr) 00242 { 00243 static char buf[sizeof(MACSTR)]; 00244 00245 if (addr != NULL) 00246 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 00247 else 00248 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 00249 return buf; 00250 } 00251 #endif /* CONFIG_NO_STDOUT_DEBUG */ 00252 00253 /* 00254 * Configure WPA parameters. 00255 */ 00256 static int 00257 madwifi_configure_wpa(struct madwifi_driver_data *drv, 00258 struct wpa_bss_params *params) 00259 { 00260 int v; 00261 00262 switch (params->wpa_group) { 00263 case WPA_CIPHER_CCMP: 00264 v = IEEE80211_CIPHER_AES_CCM; 00265 break; 00266 case WPA_CIPHER_TKIP: 00267 v = IEEE80211_CIPHER_TKIP; 00268 break; 00269 case WPA_CIPHER_WEP104: 00270 v = IEEE80211_CIPHER_WEP; 00271 break; 00272 case WPA_CIPHER_WEP40: 00273 v = IEEE80211_CIPHER_WEP; 00274 break; 00275 case WPA_CIPHER_NONE: 00276 v = IEEE80211_CIPHER_NONE; 00277 break; 00278 default: 00279 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 00280 params->wpa_group); 00281 return -1; 00282 } 00283 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 00284 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 00285 printf("Unable to set group key cipher to %u\n", v); 00286 return -1; 00287 } 00288 if (v == IEEE80211_CIPHER_WEP) { 00289 /* key length is done only for specific ciphers */ 00290 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 00291 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 00292 printf("Unable to set group key length to %u\n", v); 00293 return -1; 00294 } 00295 } 00296 00297 v = 0; 00298 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 00299 v |= 1<<IEEE80211_CIPHER_AES_CCM; 00300 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 00301 v |= 1<<IEEE80211_CIPHER_TKIP; 00302 if (params->wpa_pairwise & WPA_CIPHER_NONE) 00303 v |= 1<<IEEE80211_CIPHER_NONE; 00304 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 00305 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 00306 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 00307 return -1; 00308 } 00309 00310 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 00311 __func__, params->wpa_key_mgmt); 00312 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 00313 params->wpa_key_mgmt)) { 00314 printf("Unable to set key management algorithms to 0x%x\n", 00315 params->wpa_key_mgmt); 00316 return -1; 00317 } 00318 00319 v = 0; 00320 if (params->rsn_preauth) 00321 v |= BIT(0); 00322 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", 00323 __func__, params->rsn_preauth); 00324 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 00325 printf("Unable to set RSN capabilities to 0x%x\n", v); 00326 return -1; 00327 } 00328 00329 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 00330 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 00331 printf("Unable to set WPA to %u\n", params->wpa); 00332 return -1; 00333 } 00334 return 0; 00335 } 00336 00337 static int 00338 madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params) 00339 { 00340 struct madwifi_driver_data *drv = priv; 00341 00342 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 00343 00344 if (!params->enabled) { 00345 /* XXX restore state */ 00346 return set80211param(priv, IEEE80211_PARAM_AUTHMODE, 00347 IEEE80211_AUTH_AUTO); 00348 } 00349 if (!params->wpa && !params->ieee802_1x) { 00350 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 00351 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); 00352 return -1; 00353 } 00354 if (params->wpa && madwifi_configure_wpa(drv, params) != 0) { 00355 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 00356 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); 00357 return -1; 00358 } 00359 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 00360 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 00361 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 00362 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); 00363 return -1; 00364 } 00365 00366 return 0; 00367 } 00368 00369 static int 00370 madwifi_set_privacy(void *priv, int enabled) 00371 { 00372 struct madwifi_driver_data *drv = priv; 00373 00374 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 00375 00376 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 00377 } 00378 00379 static int 00380 madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized) 00381 { 00382 struct madwifi_driver_data *drv = priv; 00383 struct ieee80211req_mlme mlme; 00384 int ret; 00385 00386 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 00387 __func__, ether_sprintf(addr), authorized); 00388 00389 if (authorized) 00390 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 00391 else 00392 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 00393 mlme.im_reason = 0; 00394 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 00395 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 00396 if (ret < 0) { 00397 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 00398 __func__, authorized ? "" : "un", MAC2STR(addr)); 00399 } 00400 00401 return ret; 00402 } 00403 00404 static int 00405 madwifi_sta_set_flags(void *priv, const u8 *addr, 00406 int total_flags, int flags_or, int flags_and) 00407 { 00408 /* For now, only support setting Authorized flag */ 00409 if (flags_or & WPA_STA_AUTHORIZED) 00410 return madwifi_set_sta_authorized(priv, addr, 1); 00411 if (!(flags_and & WPA_STA_AUTHORIZED)) 00412 return madwifi_set_sta_authorized(priv, addr, 0); 00413 return 0; 00414 } 00415 00416 static int 00417 madwifi_del_key(void *priv, const u8 *addr, int key_idx) 00418 { 00419 struct madwifi_driver_data *drv = priv; 00420 struct ieee80211req_del_key wk; 00421 int ret; 00422 00423 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 00424 __func__, ether_sprintf(addr), key_idx); 00425 00426 memset(&wk, 0, sizeof(wk)); 00427 if (addr != NULL) { 00428 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 00429 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 00430 } else { 00431 wk.idk_keyix = key_idx; 00432 } 00433 00434 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 00435 if (ret < 0) { 00436 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 00437 " key_idx %d)", __func__, ether_sprintf(addr), 00438 key_idx); 00439 } 00440 00441 return ret; 00442 } 00443 00444 static int 00445 madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, 00446 const u8 *addr, int key_idx, int set_tx, const u8 *seq, 00447 size_t seq_len, const u8 *key, size_t key_len) 00448 { 00449 struct madwifi_driver_data *drv = priv; 00450 struct ieee80211req_key wk; 00451 u_int8_t cipher; 00452 int ret; 00453 00454 if (alg == WPA_ALG_NONE) 00455 return madwifi_del_key(drv, addr, key_idx); 00456 00457 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 00458 __func__, alg, ether_sprintf(addr), key_idx); 00459 00460 switch (alg) { 00461 case WPA_ALG_WEP: 00462 cipher = IEEE80211_CIPHER_WEP; 00463 break; 00464 case WPA_ALG_TKIP: 00465 cipher = IEEE80211_CIPHER_TKIP; 00466 break; 00467 case WPA_ALG_CCMP: 00468 cipher = IEEE80211_CIPHER_AES_CCM; 00469 break; 00470 default: 00471 printf("%s: unknown/unsupported algorithm %d\n", 00472 __func__, alg); 00473 return -1; 00474 } 00475 00476 if (key_len > sizeof(wk.ik_keydata)) { 00477 printf("%s: key length %lu too big\n", __func__, 00478 (unsigned long) key_len); 00479 return -3; 00480 } 00481 00482 memset(&wk, 0, sizeof(wk)); 00483 wk.ik_type = cipher; 00484 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 00485 if (addr == NULL) { 00486 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 00487 wk.ik_keyix = key_idx; 00488 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 00489 } else { 00490 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 00491 wk.ik_keyix = IEEE80211_KEYIX_NONE; 00492 } 00493 wk.ik_keylen = key_len; 00494 memcpy(wk.ik_keydata, key, key_len); 00495 00496 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 00497 if (ret < 0) { 00498 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 00499 " key_idx %d alg %d key_len %lu set_tx %d)", 00500 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 00501 alg, (unsigned long) key_len, set_tx); 00502 } 00503 00504 return ret; 00505 } 00506 00507 00508 static int 00509 madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 00510 u8 *seq) 00511 { 00512 struct madwifi_driver_data *drv = priv; 00513 struct ieee80211req_key wk; 00514 00515 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 00516 __func__, ether_sprintf(addr), idx); 00517 00518 memset(&wk, 0, sizeof(wk)); 00519 if (addr == NULL) 00520 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 00521 else 00522 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 00523 wk.ik_keyix = idx; 00524 00525 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 00526 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 00527 "(addr " MACSTR " key_idx %d)", 00528 __func__, MAC2STR(wk.ik_macaddr), idx); 00529 return -1; 00530 } 00531 00532 #ifdef WORDS_BIGENDIAN 00533 { 00534 /* 00535 * wk.ik_keytsc is in host byte order (big endian), need to 00536 * swap it to match with the byte order used in WPA. 00537 */ 00538 int i; 00539 #ifndef WPA_KEY_RSC_LEN 00540 #define WPA_KEY_RSC_LEN 8 00541 #endif 00542 u8 tmp[WPA_KEY_RSC_LEN]; 00543 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 00544 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 00545 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 00546 } 00547 } 00548 #else /* WORDS_BIGENDIAN */ 00549 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 00550 #endif /* WORDS_BIGENDIAN */ 00551 return 0; 00552 } 00553 00554 00555 static int 00556 madwifi_flush(void *priv) 00557 { 00558 u8 allsta[IEEE80211_ADDR_LEN]; 00559 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 00560 return madwifi_sta_deauth(priv, NULL, allsta, 00561 IEEE80211_REASON_AUTH_LEAVE); 00562 } 00563 00564 00565 static int 00566 madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 00567 const u8 *addr) 00568 { 00569 struct madwifi_driver_data *drv = priv; 00570 struct ieee80211req_sta_stats stats; 00571 00572 memset(data, 0, sizeof(*data)); 00573 00574 /* 00575 * Fetch statistics for station from the system. 00576 */ 00577 memset(&stats, 0, sizeof(stats)); 00578 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 00579 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS, 00580 &stats, sizeof(stats))) { 00581 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 00582 MACSTR ")", __func__, MAC2STR(addr)); 00583 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 00584 memcpy(data, &drv->acct_data, sizeof(*data)); 00585 return 0; 00586 } 00587 00588 printf("Failed to get station stats information element.\n"); 00589 return -1; 00590 } 00591 00592 data->rx_packets = stats.is_stats.ns_rx_data; 00593 data->rx_bytes = stats.is_stats.ns_rx_bytes; 00594 data->tx_packets = stats.is_stats.ns_tx_data; 00595 data->tx_bytes = stats.is_stats.ns_tx_bytes; 00596 return 0; 00597 } 00598 00599 00600 static int 00601 madwifi_sta_clear_stats(void *priv, const u8 *addr) 00602 { 00603 struct madwifi_driver_data *drv = priv; 00604 struct ieee80211req_mlme mlme; 00605 int ret; 00606 00607 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 00608 00609 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 00610 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 00611 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 00612 sizeof(mlme)); 00613 if (ret < 0) { 00614 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 00615 MACSTR ")", __func__, MAC2STR(addr)); 00616 } 00617 00618 return ret; 00619 } 00620 00621 00622 static int 00623 madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 00624 { 00625 /* 00626 * Do nothing; we setup parameters at startup that define the 00627 * contents of the beacon information element. 00628 */ 00629 return 0; 00630 } 00631 00632 static int 00633 madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 00634 int reason_code) 00635 { 00636 struct madwifi_driver_data *drv = priv; 00637 struct ieee80211req_mlme mlme; 00638 int ret; 00639 00640 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 00641 __func__, ether_sprintf(addr), reason_code); 00642 00643 mlme.im_op = IEEE80211_MLME_DEAUTH; 00644 mlme.im_reason = reason_code; 00645 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 00646 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 00647 if (ret < 0) { 00648 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 00649 " reason %d)", 00650 __func__, MAC2STR(addr), reason_code); 00651 } 00652 00653 return ret; 00654 } 00655 00656 static int 00657 madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 00658 int reason_code) 00659 { 00660 struct madwifi_driver_data *drv = priv; 00661 struct ieee80211req_mlme mlme; 00662 int ret; 00663 00664 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 00665 __func__, ether_sprintf(addr), reason_code); 00666 00667 mlme.im_op = IEEE80211_MLME_DISASSOC; 00668 mlme.im_reason = reason_code; 00669 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 00670 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 00671 if (ret < 0) { 00672 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 00673 MACSTR " reason %d)", 00674 __func__, MAC2STR(addr), reason_code); 00675 } 00676 00677 return ret; 00678 } 00679 00680 #ifdef CONFIG_WPS 00681 static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 00682 size_t len) 00683 { 00684 struct madwifi_driver_data *drv = ctx; 00685 const struct ieee80211_mgmt *mgmt; 00686 u16 fc; 00687 union wpa_event_data event; 00688 00689 /* Send Probe Request information to WPS processing */ 00690 00691 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 00692 return; 00693 mgmt = (const struct ieee80211_mgmt *) buf; 00694 00695 fc = le_to_host16(mgmt->frame_control); 00696 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 00697 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) 00698 return; 00699 00700 os_memset(&event, 0, sizeof(event)); 00701 event.rx_probe_req.sa = mgmt->sa; 00702 event.rx_probe_req.ie = mgmt->u.probe_req.variable; 00703 event.rx_probe_req.ie_len = 00704 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 00705 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 00706 } 00707 #endif /* CONFIG_WPS */ 00708 00709 static int madwifi_receive_probe_req(struct madwifi_driver_data *drv) 00710 { 00711 int ret = 0; 00712 #ifdef CONFIG_WPS 00713 struct ieee80211req_set_filter filt; 00714 00715 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 00716 filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ; 00717 00718 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 00719 sizeof(struct ieee80211req_set_filter)); 00720 if (ret) 00721 return ret; 00722 00723 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 00724 madwifi_raw_receive, drv, 1); 00725 if (drv->sock_raw == NULL) 00726 return -1; 00727 #endif /* CONFIG_WPS */ 00728 return ret; 00729 } 00730 00731 #ifdef CONFIG_WPS 00732 static int 00733 madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 00734 { 00735 struct madwifi_driver_data *drv = priv; 00736 u8 buf[256]; 00737 struct ieee80211req_getset_appiebuf *beac_ie; 00738 00739 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 00740 (unsigned long) len); 00741 00742 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 00743 beac_ie->app_frmtype = frametype; 00744 beac_ie->app_buflen = len; 00745 memcpy(&(beac_ie->app_buf[0]), ie, len); 00746 00747 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 00748 sizeof(struct ieee80211req_getset_appiebuf) + len); 00749 } 00750 00751 static int 00752 madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 00753 const struct wpabuf *proberesp) 00754 { 00755 if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 00756 beacon ? wpabuf_len(beacon) : 0, 00757 IEEE80211_APPIE_FRAME_BEACON)) 00758 return -1; 00759 return madwifi_set_wps_ie(priv, 00760 proberesp ? wpabuf_head(proberesp) : NULL, 00761 proberesp ? wpabuf_len(proberesp): 0, 00762 IEEE80211_APPIE_FRAME_PROBE_RESP); 00763 } 00764 #else /* CONFIG_WPS */ 00765 #define madwifi_set_ap_wps_ie NULL 00766 #endif /* CONFIG_WPS */ 00767 00768 static void 00769 madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 00770 { 00771 struct hostapd_data *hapd = drv->hapd; 00772 struct ieee80211req_wpaie ie; 00773 int ielen = 0; 00774 u8 *iebuf = NULL; 00775 00776 /* 00777 * Fetch negotiated WPA/RSN parameters from the system. 00778 */ 00779 memset(&ie, 0, sizeof(ie)); 00780 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 00781 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 00782 /* 00783 * See ATH_WPS_IE comment in the beginning of the file for a 00784 * possible cause for the failure.. 00785 */ 00786 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", 00787 __func__, strerror(errno)); 00788 goto no_ie; 00789 } 00790 wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE", 00791 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 00792 wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE", 00793 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 00794 iebuf = ie.wpa_ie; 00795 /* madwifi seems to return some random data if WPA/RSN IE is not set. 00796 * Assume the IE was not included if the IE type is unknown. */ 00797 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 00798 iebuf[1] = 0; 00799 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 00800 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 00801 * set. This is needed for WPA2. */ 00802 iebuf = ie.rsn_ie; 00803 if (iebuf[0] != WLAN_EID_RSN) 00804 iebuf[1] = 0; 00805 } 00806 00807 ielen = iebuf[1]; 00808 if (ielen == 0) 00809 iebuf = NULL; 00810 else 00811 ielen += 2; 00812 00813 no_ie: 00814 drv_event_assoc(hapd, addr, iebuf, ielen); 00815 00816 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 00817 /* Cached accounting data is not valid anymore. */ 00818 memset(drv->acct_mac, 0, ETH_ALEN); 00819 memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 00820 } 00821 } 00822 00823 static void 00824 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv, 00825 char *custom, char *end) 00826 { 00827 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 00828 00829 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 00830 char *pos; 00831 u8 addr[ETH_ALEN]; 00832 pos = strstr(custom, "addr="); 00833 if (pos == NULL) { 00834 wpa_printf(MSG_DEBUG, 00835 "MLME-MICHAELMICFAILURE.indication " 00836 "without sender address ignored"); 00837 return; 00838 } 00839 pos += 5; 00840 if (hwaddr_aton(pos, addr) == 0) { 00841 union wpa_event_data data; 00842 os_memset(&data, 0, sizeof(data)); 00843 data.michael_mic_failure.unicast = 1; 00844 data.michael_mic_failure.src = addr; 00845 wpa_supplicant_event(drv->hapd, 00846 EVENT_MICHAEL_MIC_FAILURE, &data); 00847 } else { 00848 wpa_printf(MSG_DEBUG, 00849 "MLME-MICHAELMICFAILURE.indication " 00850 "with invalid MAC address"); 00851 } 00852 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 00853 char *key, *value; 00854 u32 val; 00855 key = custom; 00856 while ((key = strchr(key, '\n')) != NULL) { 00857 key++; 00858 value = strchr(key, '='); 00859 if (value == NULL) 00860 continue; 00861 *value++ = '\0'; 00862 val = strtoul(value, NULL, 10); 00863 if (strcmp(key, "mac") == 0) 00864 hwaddr_aton(value, drv->acct_mac); 00865 else if (strcmp(key, "rx_packets") == 0) 00866 drv->acct_data.rx_packets = val; 00867 else if (strcmp(key, "tx_packets") == 0) 00868 drv->acct_data.tx_packets = val; 00869 else if (strcmp(key, "rx_bytes") == 0) 00870 drv->acct_data.rx_bytes = val; 00871 else if (strcmp(key, "tx_bytes") == 0) 00872 drv->acct_data.tx_bytes = val; 00873 key = value; 00874 } 00875 #ifdef CONFIG_WPS 00876 } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) { 00877 /* Some atheros kernels send push button as a wireless event */ 00878 /* PROBLEM! this event is received for ALL BSSs ... 00879 * so all are enabled for WPS... ugh. 00880 */ 00881 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); 00882 } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) { 00883 /* 00884 * Atheros driver uses a hack to pass Probe Request frames as a 00885 * binary data in the custom wireless event. The old way (using 00886 * packet sniffing) didn't work when bridging. 00887 * Format: "Manage.prob_req <frame len>" | zero padding | frame 00888 */ 00889 #define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */ 00890 int len = atoi(custom + 16); 00891 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 00892 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event " 00893 "length %d", len); 00894 return; 00895 } 00896 madwifi_raw_receive(drv, NULL, 00897 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 00898 #endif /* CONFIG_WPS */ 00899 } 00900 } 00901 00902 static void 00903 madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, 00904 char *data, int len) 00905 { 00906 struct iw_event iwe_buf, *iwe = &iwe_buf; 00907 char *pos, *end, *custom, *buf; 00908 00909 pos = data; 00910 end = data + len; 00911 00912 while (pos + IW_EV_LCP_LEN <= end) { 00913 /* Event data may be unaligned, so make a local, aligned copy 00914 * before processing. */ 00915 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 00916 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 00917 iwe->cmd, iwe->len); 00918 if (iwe->len <= IW_EV_LCP_LEN) 00919 return; 00920 00921 custom = pos + IW_EV_POINT_LEN; 00922 if (drv->we_version > 18 && 00923 (iwe->cmd == IWEVMICHAELMICFAILURE || 00924 iwe->cmd == IWEVASSOCREQIE || 00925 iwe->cmd == IWEVCUSTOM)) { 00926 /* WE-19 removed the pointer from struct iw_point */ 00927 char *dpos = (char *) &iwe_buf.u.data.length; 00928 int dlen = dpos - (char *) &iwe_buf; 00929 memcpy(dpos, pos + IW_EV_LCP_LEN, 00930 sizeof(struct iw_event) - dlen); 00931 } else { 00932 memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 00933 custom += IW_EV_POINT_OFF; 00934 } 00935 00936 switch (iwe->cmd) { 00937 case IWEVEXPIRED: 00938 drv_event_disassoc(drv->hapd, 00939 (u8 *) iwe->u.addr.sa_data); 00940 break; 00941 case IWEVREGISTERED: 00942 madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 00943 break; 00944 case IWEVASSOCREQIE: 00945 /* Driver hack.. Use IWEVASSOCREQIE to bypass 00946 * IWEVCUSTOM size limitations. Need to handle this 00947 * just like IWEVCUSTOM. 00948 */ 00949 case IWEVCUSTOM: 00950 if (custom + iwe->u.data.length > end) 00951 return; 00952 buf = malloc(iwe->u.data.length + 1); 00953 if (buf == NULL) 00954 return; /* XXX */ 00955 memcpy(buf, custom, iwe->u.data.length); 00956 buf[iwe->u.data.length] = '\0'; 00957 madwifi_wireless_event_wireless_custom( 00958 drv, buf, buf + iwe->u.data.length); 00959 free(buf); 00960 break; 00961 } 00962 00963 pos += iwe->len; 00964 } 00965 } 00966 00967 00968 static void 00969 madwifi_wireless_event_rtm_newlink(void *ctx, 00970 struct ifinfomsg *ifi, u8 *buf, size_t len) 00971 { 00972 struct madwifi_driver_data *drv = ctx; 00973 int attrlen, rta_len; 00974 struct rtattr *attr; 00975 00976 if (ifi->ifi_index != drv->ifindex) 00977 return; 00978 00979 attrlen = len; 00980 attr = (struct rtattr *) buf; 00981 00982 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 00983 while (RTA_OK(attr, attrlen)) { 00984 if (attr->rta_type == IFLA_WIRELESS) { 00985 madwifi_wireless_event_wireless( 00986 drv, ((char *) attr) + rta_len, 00987 attr->rta_len - rta_len); 00988 } 00989 attr = RTA_NEXT(attr, attrlen); 00990 } 00991 } 00992 00993 00994 static int 00995 madwifi_get_we_version(struct madwifi_driver_data *drv) 00996 { 00997 struct iw_range *range; 00998 struct iwreq iwr; 00999 int minlen; 01000 size_t buflen; 01001 01002 drv->we_version = 0; 01003 01004 /* 01005 * Use larger buffer than struct iw_range in order to allow the 01006 * structure to grow in the future. 01007 */ 01008 buflen = sizeof(struct iw_range) + 500; 01009 range = os_zalloc(buflen); 01010 if (range == NULL) 01011 return -1; 01012 01013 memset(&iwr, 0, sizeof(iwr)); 01014 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 01015 iwr.u.data.pointer = (caddr_t) range; 01016 iwr.u.data.length = buflen; 01017 01018 minlen = ((char *) &range->enc_capa) - (char *) range + 01019 sizeof(range->enc_capa); 01020 01021 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 01022 perror("ioctl[SIOCGIWRANGE]"); 01023 free(range); 01024 return -1; 01025 } else if (iwr.u.data.length >= minlen && 01026 range->we_version_compiled >= 18) { 01027 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 01028 "WE(source)=%d enc_capa=0x%x", 01029 range->we_version_compiled, 01030 range->we_version_source, 01031 range->enc_capa); 01032 drv->we_version = range->we_version_compiled; 01033 } 01034 01035 free(range); 01036 return 0; 01037 } 01038 01039 01040 static int 01041 madwifi_wireless_event_init(struct madwifi_driver_data *drv) 01042 { 01043 struct netlink_config *cfg; 01044 01045 madwifi_get_we_version(drv); 01046 01047 cfg = os_zalloc(sizeof(*cfg)); 01048 if (cfg == NULL) 01049 return -1; 01050 cfg->ctx = drv; 01051 cfg->newlink_cb = madwifi_wireless_event_rtm_newlink; 01052 drv->netlink = netlink_init(cfg); 01053 if (drv->netlink == NULL) { 01054 os_free(cfg); 01055 return -1; 01056 } 01057 01058 return 0; 01059 } 01060 01061 01062 static int 01063 madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 01064 int encrypt, const u8 *own_addr) 01065 { 01066 struct madwifi_driver_data *drv = priv; 01067 unsigned char buf[3000]; 01068 unsigned char *bp = buf; 01069 struct l2_ethhdr *eth; 01070 size_t len; 01071 int status; 01072 01073 /* 01074 * Prepend the Ethernet header. If the caller left us 01075 * space at the front we could just insert it but since 01076 * we don't know we copy to a local buffer. Given the frequency 01077 * and size of frames this probably doesn't matter. 01078 */ 01079 len = data_len + sizeof(struct l2_ethhdr); 01080 if (len > sizeof(buf)) { 01081 bp = malloc(len); 01082 if (bp == NULL) { 01083 printf("EAPOL frame discarded, cannot malloc temp " 01084 "buffer of size %lu!\n", (unsigned long) len); 01085 return -1; 01086 } 01087 } 01088 eth = (struct l2_ethhdr *) bp; 01089 memcpy(eth->h_dest, addr, ETH_ALEN); 01090 memcpy(eth->h_source, own_addr, ETH_ALEN); 01091 eth->h_proto = host_to_be16(ETH_P_EAPOL); 01092 memcpy(eth+1, data, data_len); 01093 01094 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); 01095 01096 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); 01097 01098 if (bp != buf) 01099 free(bp); 01100 return status; 01101 } 01102 01103 static void 01104 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 01105 { 01106 struct madwifi_driver_data *drv = ctx; 01107 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), 01108 len - sizeof(struct l2_ethhdr)); 01109 } 01110 01111 static void * 01112 madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) 01113 { 01114 struct madwifi_driver_data *drv; 01115 struct ifreq ifr; 01116 struct iwreq iwr; 01117 char brname[IFNAMSIZ]; 01118 01119 drv = os_zalloc(sizeof(struct madwifi_driver_data)); 01120 if (drv == NULL) { 01121 printf("Could not allocate memory for madwifi driver data\n"); 01122 return NULL; 01123 } 01124 01125 drv->hapd = hapd; 01126 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 01127 if (drv->ioctl_sock < 0) { 01128 perror("socket[PF_INET,SOCK_DGRAM]"); 01129 goto bad; 01130 } 01131 memcpy(drv->iface, params->ifname, sizeof(drv->iface)); 01132 01133 memset(&ifr, 0, sizeof(ifr)); 01134 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); 01135 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { 01136 perror("ioctl(SIOCGIFINDEX)"); 01137 goto bad; 01138 } 01139 drv->ifindex = ifr.ifr_ifindex; 01140 01141 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, 01142 handle_read, drv, 1); 01143 if (drv->sock_xmit == NULL) 01144 goto bad; 01145 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 01146 goto bad; 01147 if (params->bridge[0]) { 01148 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", 01149 params->bridge[0]); 01150 drv->sock_recv = l2_packet_init(params->bridge[0], NULL, 01151 ETH_P_EAPOL, handle_read, drv, 01152 1); 01153 if (drv->sock_recv == NULL) 01154 goto bad; 01155 } else if (linux_br_get(brname, drv->iface) == 0) { 01156 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " 01157 "EAPOL receive", brname); 01158 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, 01159 handle_read, drv, 1); 01160 if (drv->sock_recv == NULL) 01161 goto bad; 01162 } else 01163 drv->sock_recv = drv->sock_xmit; 01164 01165 memset(&iwr, 0, sizeof(iwr)); 01166 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 01167 01168 iwr.u.mode = IW_MODE_MASTER; 01169 01170 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { 01171 perror("ioctl[SIOCSIWMODE]"); 01172 printf("Could not set interface to master mode!\n"); 01173 goto bad; 01174 } 01175 01176 /* mark down during setup */ 01177 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 01178 madwifi_set_privacy(drv, 0); /* default to no privacy */ 01179 01180 madwifi_receive_probe_req(drv); 01181 01182 if (madwifi_wireless_event_init(drv)) 01183 goto bad; 01184 01185 return drv; 01186 bad: 01187 if (drv->sock_xmit != NULL) 01188 l2_packet_deinit(drv->sock_xmit); 01189 if (drv->ioctl_sock >= 0) 01190 close(drv->ioctl_sock); 01191 if (drv != NULL) 01192 free(drv); 01193 return NULL; 01194 } 01195 01196 01197 static void 01198 madwifi_deinit(void *priv) 01199 { 01200 struct madwifi_driver_data *drv = priv; 01201 01202 netlink_deinit(drv->netlink); 01203 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 01204 if (drv->ioctl_sock >= 0) 01205 close(drv->ioctl_sock); 01206 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 01207 l2_packet_deinit(drv->sock_recv); 01208 if (drv->sock_xmit != NULL) 01209 l2_packet_deinit(drv->sock_xmit); 01210 if (drv->sock_raw) 01211 l2_packet_deinit(drv->sock_raw); 01212 free(drv); 01213 } 01214 01215 static int 01216 madwifi_set_ssid(void *priv, const u8 *buf, int len) 01217 { 01218 struct madwifi_driver_data *drv = priv; 01219 struct iwreq iwr; 01220 01221 memset(&iwr, 0, sizeof(iwr)); 01222 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 01223 iwr.u.essid.flags = 1; /* SSID active */ 01224 iwr.u.essid.pointer = (caddr_t) buf; 01225 iwr.u.essid.length = len + 1; 01226 01227 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 01228 perror("ioctl[SIOCSIWESSID]"); 01229 printf("len=%d\n", len); 01230 return -1; 01231 } 01232 return 0; 01233 } 01234 01235 static int 01236 madwifi_get_ssid(void *priv, u8 *buf, int len) 01237 { 01238 struct madwifi_driver_data *drv = priv; 01239 struct iwreq iwr; 01240 int ret = 0; 01241 01242 memset(&iwr, 0, sizeof(iwr)); 01243 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 01244 iwr.u.essid.pointer = (caddr_t) buf; 01245 iwr.u.essid.length = len; 01246 01247 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 01248 perror("ioctl[SIOCGIWESSID]"); 01249 ret = -1; 01250 } else 01251 ret = iwr.u.essid.length; 01252 01253 return ret; 01254 } 01255 01256 static int 01257 madwifi_set_countermeasures(void *priv, int enabled) 01258 { 01259 struct madwifi_driver_data *drv = priv; 01260 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 01261 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 01262 } 01263 01264 static int 01265 madwifi_commit(void *priv) 01266 { 01267 struct madwifi_driver_data *drv = priv; 01268 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 01269 } 01270 01271 const struct wpa_driver_ops wpa_driver_atheros_ops = { 01272 .name = "atheros", 01273 .hapd_init = madwifi_init, 01274 .deinit = madwifi_deinit, 01275 .set_ieee8021x = madwifi_set_ieee8021x, 01276 .set_privacy = madwifi_set_privacy, 01277 .set_key = madwifi_set_key, 01278 .get_seqnum = madwifi_get_seqnum, 01279 .flush = madwifi_flush, 01280 .set_generic_elem = madwifi_set_opt_ie, 01281 .sta_set_flags = madwifi_sta_set_flags, 01282 .read_sta_data = madwifi_read_sta_driver_data, 01283 .hapd_send_eapol = madwifi_send_eapol, 01284 .sta_disassoc = madwifi_sta_disassoc, 01285 .sta_deauth = madwifi_sta_deauth, 01286 .hapd_set_ssid = madwifi_set_ssid, 01287 .hapd_get_ssid = madwifi_get_ssid, 01288 .set_countermeasures = madwifi_set_countermeasures, 01289 .sta_clear_stats = madwifi_sta_clear_stats, 01290 .commit = madwifi_commit, 01291 .set_ap_wps_ie = madwifi_set_ap_wps_ie, 01292 };