00001
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <unistd.h>
00019 #include <string.h>
00020 #include <sys/ioctl.h>
00021 #include <errno.h>
00022
00023 #include "wireless_copy.h"
00024 #include "common.h"
00025 #include "driver.h"
00026 #include "driver_wext.h"
00027 #include "eloop.h"
00028 #include "driver_hostap.h"
00029 #include "l2_packet.h"
00030 #include "wpa_supplicant.h"
00031
00032
00033 struct wpa_driver_hostap_data {
00034 void *wext;
00035 void *ctx;
00036 char ifname[IFNAMSIZ + 1];
00037 int sock;
00038 int current_mode;
00039 };
00040
00041
00042 static int hostapd_ioctl(struct wpa_driver_hostap_data *drv,
00043 struct prism2_hostapd_param *param,
00044 int len, int show_err)
00045 {
00046 struct iwreq iwr;
00047
00048 memset(&iwr, 0, sizeof(iwr));
00049 strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00050 iwr.u.data.pointer = (caddr_t) param;
00051 iwr.u.data.length = len;
00052
00053 if (ioctl(drv->sock, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) {
00054 int ret = errno;
00055 if (show_err)
00056 perror("ioctl[PRISM2_IOCTL_HOSTAPD]");
00057 return ret;
00058 }
00059
00060 return 0;
00061 }
00062
00063
00064 static int wpa_driver_hostap_set_wpa_ie(struct wpa_driver_hostap_data *drv,
00065 const u8 *wpa_ie, size_t wpa_ie_len)
00066 {
00067 struct prism2_hostapd_param *param;
00068 int res;
00069 size_t blen = PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len;
00070 if (blen < sizeof(*param))
00071 blen = sizeof(*param);
00072
00073 param = (struct prism2_hostapd_param *) malloc(blen);
00074 if (param == NULL)
00075 return -1;
00076
00077 memset(param, 0, blen);
00078 param->cmd = PRISM2_HOSTAPD_SET_GENERIC_ELEMENT;
00079 param->u.generic_elem.len = wpa_ie_len;
00080 memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len);
00081 res = hostapd_ioctl(drv, param, blen, 1);
00082
00083 free(param);
00084
00085 return res;
00086 }
00087
00088
00089 static int prism2param(struct wpa_driver_hostap_data *drv, int param,
00090 int value)
00091 {
00092 struct iwreq iwr;
00093 int *i, ret = 0;
00094
00095 memset(&iwr, 0, sizeof(iwr));
00096 strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00097 i = (int *) iwr.u.name;
00098 *i++ = param;
00099 *i++ = value;
00100
00101 if (ioctl(drv->sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) {
00102 perror("ioctl[PRISM2_IOCTL_PRISM2_PARAM]");
00103 ret = -1;
00104 }
00105 return ret;
00106 }
00107
00108
00109 static int wpa_driver_hostap_set_wpa(void *priv, int enabled)
00110 {
00111 struct wpa_driver_hostap_data *drv = priv;
00112 int ret = 0;
00113
00114 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00115
00116 if (!enabled && wpa_driver_hostap_set_wpa_ie(drv, NULL, 0) < 0)
00117 ret = -1;
00118 if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING, enabled ? 2 : 0) < 0)
00119 ret = -1;
00120 if (prism2param(drv, PRISM2_PARAM_WPA, enabled) < 0)
00121 ret = -1;
00122
00123 return ret;
00124 }
00125
00126
00127 static void show_set_key_error(struct prism2_hostapd_param *param)
00128 {
00129 switch (param->u.crypt.err) {
00130 case HOSTAP_CRYPT_ERR_UNKNOWN_ALG:
00131 wpa_printf(MSG_INFO, "Unknown algorithm '%s'.",
00132 param->u.crypt.alg);
00133 wpa_printf(MSG_INFO, "You may need to load kernel module to "
00134 "register that algorithm.");
00135 wpa_printf(MSG_INFO, "E.g., 'modprobe hostap_crypt_wep' for "
00136 "WEP.");
00137 break;
00138 case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR:
00139 wpa_printf(MSG_INFO, "Unknown address " MACSTR ".",
00140 MAC2STR(param->sta_addr));
00141 break;
00142 case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED:
00143 wpa_printf(MSG_INFO, "Crypt algorithm initialization failed.");
00144 break;
00145 case HOSTAP_CRYPT_ERR_KEY_SET_FAILED:
00146 wpa_printf(MSG_INFO, "Key setting failed.");
00147 break;
00148 case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED:
00149 wpa_printf(MSG_INFO, "TX key index setting failed.");
00150 break;
00151 case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED:
00152 wpa_printf(MSG_INFO, "Card configuration failed.");
00153 break;
00154 }
00155 }
00156
00157
00158 static int wpa_driver_hostap_set_key(void *priv, wpa_alg alg,
00159 const u8 *addr, int key_idx,
00160 int set_tx, const u8 *seq, size_t seq_len,
00161 const u8 *key, size_t key_len)
00162 {
00163 struct wpa_driver_hostap_data *drv = priv;
00164 struct prism2_hostapd_param *param;
00165 u8 *buf;
00166 size_t blen;
00167 int ret = 0;
00168 char *alg_name;
00169
00170 switch (alg) {
00171 case WPA_ALG_NONE:
00172 alg_name = "none";
00173 break;
00174 case WPA_ALG_WEP:
00175 alg_name = "WEP";
00176 break;
00177 case WPA_ALG_TKIP:
00178 alg_name = "TKIP";
00179 break;
00180 case WPA_ALG_CCMP:
00181 alg_name = "CCMP";
00182 break;
00183 default:
00184 return -1;
00185 }
00186
00187 wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
00188 "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
00189 (unsigned long) seq_len, (unsigned long) key_len);
00190
00191 if (seq_len > 8)
00192 return -2;
00193
00194 blen = sizeof(*param) + key_len;
00195 buf = malloc(blen);
00196 if (buf == NULL)
00197 return -1;
00198 memset(buf, 0, blen);
00199
00200 param = (struct prism2_hostapd_param *) buf;
00201 param->cmd = PRISM2_SET_ENCRYPTION;
00202
00203
00204
00205
00206
00207
00208
00209 #if 0
00210 if (addr == NULL)
00211 memset(param->sta_addr, 0xff, ETH_ALEN);
00212 else
00213 memcpy(param->sta_addr, addr, ETH_ALEN);
00214 #else
00215 memset(param->sta_addr, 0xff, ETH_ALEN);
00216 #endif
00217 strncpy((char *) param->u.crypt.alg, alg_name,
00218 HOSTAP_CRYPT_ALG_NAME_LEN);
00219 param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
00220 param->u.crypt.idx = key_idx;
00221 memcpy(param->u.crypt.seq, seq, seq_len);
00222 param->u.crypt.key_len = key_len;
00223 memcpy((u8 *) (param + 1), key, key_len);
00224
00225 if (hostapd_ioctl(drv, param, blen, 1)) {
00226 wpa_printf(MSG_WARNING, "Failed to set encryption.");
00227 show_set_key_error(param);
00228 ret = -1;
00229 }
00230 free(buf);
00231
00232 return ret;
00233 }
00234
00235
00236 static int wpa_driver_hostap_set_countermeasures(void *priv, int enabled)
00237 {
00238 struct wpa_driver_hostap_data *drv = priv;
00239 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00240 return prism2param(drv, PRISM2_PARAM_TKIP_COUNTERMEASURES, enabled);
00241 }
00242
00243
00244 static int wpa_driver_hostap_set_drop_unencrypted(void *priv, int enabled)
00245 {
00246 struct wpa_driver_hostap_data *drv = priv;
00247 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00248 return prism2param(drv, PRISM2_PARAM_DROP_UNENCRYPTED, enabled);
00249 }
00250
00251
00252 static int wpa_driver_hostap_reset(struct wpa_driver_hostap_data *drv,
00253 int type)
00254 {
00255 struct iwreq iwr;
00256 int *i, ret = 0;
00257
00258 wpa_printf(MSG_DEBUG, "%s: type=%d", __FUNCTION__, type);
00259
00260 memset(&iwr, 0, sizeof(iwr));
00261 strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00262 i = (int *) iwr.u.name;
00263 *i++ = type;
00264
00265 if (ioctl(drv->sock, PRISM2_IOCTL_RESET, &iwr) < 0) {
00266 perror("ioctl[PRISM2_IOCTL_RESET]");
00267 ret = -1;
00268 }
00269 return ret;
00270 }
00271
00272
00273 static int wpa_driver_hostap_mlme(struct wpa_driver_hostap_data *drv,
00274 const u8 *addr, int cmd, int reason_code)
00275 {
00276 struct prism2_hostapd_param param;
00277 int ret;
00278
00279
00280
00281
00282
00283 memset(¶m, 0, sizeof(param));
00284 param.cmd = PRISM2_HOSTAPD_MLME;
00285 memcpy(param.sta_addr, addr, ETH_ALEN);
00286 param.u.mlme.cmd = cmd;
00287 param.u.mlme.reason_code = reason_code;
00288 ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1);
00289 if (ret == 0) {
00290 usleep(100000);
00291 ret = wpa_driver_hostap_reset(drv, 2);
00292 }
00293 return ret;
00294 }
00295
00296
00297 static int wpa_driver_hostap_deauthenticate(void *priv, const u8 *addr,
00298 int reason_code)
00299 {
00300 struct wpa_driver_hostap_data *drv = priv;
00301 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00302 return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DEAUTH,
00303 reason_code);
00304 }
00305
00306
00307 static int wpa_driver_hostap_disassociate(void *priv, const u8 *addr,
00308 int reason_code)
00309 {
00310 struct wpa_driver_hostap_data *drv = priv;
00311 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00312 return wpa_driver_hostap_mlme(drv, addr, MLME_STA_DISASSOC,
00313 reason_code);
00314 }
00315
00316
00317 static int
00318 wpa_driver_hostap_associate(void *priv,
00319 struct wpa_driver_associate_params *params)
00320 {
00321 struct wpa_driver_hostap_data *drv = priv;
00322 int ret = 0;
00323 int allow_unencrypted_eapol;
00324
00325 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
00326
00327 if (params->mode != drv->current_mode) {
00328
00329
00330 if (prism2param(drv, PRISM2_PARAM_HOST_ROAMING,
00331 params->mode == IEEE80211_MODE_IBSS ? 0 : 2) <
00332 0) {
00333 wpa_printf(MSG_DEBUG, "%s: failed to set host_roaming",
00334 __func__);
00335 }
00336 drv->current_mode = params->mode;
00337 }
00338
00339 if (prism2param(drv, PRISM2_PARAM_PRIVACY_INVOKED,
00340 params->key_mgmt_suite != KEY_MGMT_NONE) < 0)
00341 ret = -1;
00342 if (wpa_driver_hostap_set_wpa_ie(drv, params->wpa_ie,
00343 params->wpa_ie_len) < 0)
00344 ret = -1;
00345 if (wpa_driver_wext_set_mode(drv->wext, params->mode) < 0)
00346 ret = -1;
00347 if (params->freq &&
00348 wpa_driver_wext_set_freq(drv->wext, params->freq) < 0)
00349 ret = -1;
00350 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len)
00351 < 0)
00352 ret = -1;
00353 if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0)
00354 ret = -1;
00355
00356
00357
00358
00359 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
00360 params->key_mgmt_suite == KEY_MGMT_PSK)
00361 allow_unencrypted_eapol = 0;
00362 else
00363 allow_unencrypted_eapol = 1;
00364
00365 if (prism2param(drv, PRISM2_PARAM_IEEE_802_1X,
00366 allow_unencrypted_eapol) < 0) {
00367 wpa_printf(MSG_DEBUG, "hostap: Failed to configure "
00368 "ieee_802_1x param");
00369
00370
00371 }
00372
00373 return ret;
00374 }
00375
00376
00377 static int wpa_driver_hostap_scan(void *priv, const u8 *ssid, size_t ssid_len)
00378 {
00379 struct wpa_driver_hostap_data *drv = priv;
00380 struct prism2_hostapd_param param;
00381 int ret;
00382
00383 if (ssid == NULL) {
00384
00385
00386
00387
00388 return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
00389 }
00390
00391 if (ssid_len > 32)
00392 ssid_len = 32;
00393
00394 memset(¶m, 0, sizeof(param));
00395 param.cmd = PRISM2_HOSTAPD_SCAN_REQ;
00396 param.u.scan_req.ssid_len = ssid_len;
00397 memcpy(param.u.scan_req.ssid, ssid, ssid_len);
00398 ret = hostapd_ioctl(drv, ¶m, sizeof(param), 1);
00399
00400
00401
00402 eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, drv->wext,
00403 drv->ctx);
00404
00405 return ret;
00406 }
00407
00408
00409 static int wpa_driver_hostap_set_auth_alg(void *priv, int auth_alg)
00410 {
00411 struct wpa_driver_hostap_data *drv = priv;
00412 int algs = 0;
00413
00414 if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
00415 algs |= 1;
00416 if (auth_alg & AUTH_ALG_SHARED_KEY)
00417 algs |= 2;
00418 if (auth_alg & AUTH_ALG_LEAP)
00419 algs |= 4;
00420 if (algs == 0)
00421 algs = 1;
00422
00423 return prism2param(drv, PRISM2_PARAM_AP_AUTH_ALGS, algs);
00424 }
00425
00426
00427 static int wpa_driver_hostap_get_bssid(void *priv, u8 *bssid)
00428 {
00429 struct wpa_driver_hostap_data *drv = priv;
00430 return wpa_driver_wext_get_bssid(drv->wext, bssid);
00431 }
00432
00433
00434 static int wpa_driver_hostap_get_ssid(void *priv, u8 *ssid)
00435 {
00436 struct wpa_driver_hostap_data *drv = priv;
00437 return wpa_driver_wext_get_ssid(drv->wext, ssid);
00438 }
00439
00440
00441 static int wpa_driver_hostap_get_scan_results(void *priv,
00442 struct wpa_scan_result *results,
00443 size_t max_size)
00444 {
00445 struct wpa_driver_hostap_data *drv = priv;
00446 return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
00447 }
00448
00449
00450 static void * wpa_driver_hostap_init(void *ctx, const char *ifname)
00451 {
00452 struct wpa_driver_hostap_data *drv;
00453
00454 drv = malloc(sizeof(*drv));
00455 if (drv == NULL)
00456 return NULL;
00457 memset(drv, 0, sizeof(*drv));
00458 drv->wext = wpa_driver_wext_init(ctx, ifname);
00459 if (drv->wext == NULL) {
00460 free(drv);
00461 return NULL;
00462 }
00463
00464 drv->ctx = ctx;
00465 strncpy(drv->ifname, ifname, sizeof(drv->ifname));
00466 drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
00467 if (drv->sock < 0) {
00468 perror("socket");
00469 wpa_driver_wext_deinit(drv->wext);
00470 free(drv);
00471 return NULL;
00472 }
00473
00474 if (strncmp(ifname, "wlan", 4) == 0) {
00475
00476
00477
00478
00479 char ifname2[IFNAMSIZ + 1];
00480 strncpy(ifname2, ifname, sizeof(ifname2));
00481 memcpy(ifname2, "wifi", 4);
00482 wpa_driver_wext_alternative_ifindex(drv->wext, ifname2);
00483 }
00484
00485 return drv;
00486 }
00487
00488
00489 static void wpa_driver_hostap_deinit(void *priv)
00490 {
00491 struct wpa_driver_hostap_data *drv = priv;
00492 wpa_driver_wext_deinit(drv->wext);
00493 close(drv->sock);
00494 free(drv);
00495 }
00496
00497
00498 const struct wpa_driver_ops wpa_driver_hostap_ops = {
00499 .name = "hostap",
00500 .desc = "Host AP driver (Intersil Prism2/2.5/3)",
00501 .get_bssid = wpa_driver_hostap_get_bssid,
00502 .get_ssid = wpa_driver_hostap_get_ssid,
00503 .set_wpa = wpa_driver_hostap_set_wpa,
00504 .set_key = wpa_driver_hostap_set_key,
00505 .set_countermeasures = wpa_driver_hostap_set_countermeasures,
00506 .set_drop_unencrypted = wpa_driver_hostap_set_drop_unencrypted,
00507 .scan = wpa_driver_hostap_scan,
00508 .get_scan_results = wpa_driver_hostap_get_scan_results,
00509 .deauthenticate = wpa_driver_hostap_deauthenticate,
00510 .disassociate = wpa_driver_hostap_disassociate,
00511 .associate = wpa_driver_hostap_associate,
00512 .set_auth_alg = wpa_driver_hostap_set_auth_alg,
00513 .init = wpa_driver_hostap_init,
00514 .deinit = wpa_driver_hostap_deinit,
00515 };
00516