00001
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <unistd.h>
00021 #include <string.h>
00022 #include <sys/ioctl.h>
00023 #include <errno.h>
00024
00025 #include "wireless_copy.h"
00026 #include "common.h"
00027 #include "driver.h"
00028 #include "l2_packet.h"
00029 #include "driver_wext.h"
00030 #include "wpa_supplicant.h"
00031
00032 struct wpa_driver_ipw_data {
00033 void *wext;
00034 void *ctx;
00035 char ifname[IFNAMSIZ + 1];
00036 int sock;
00037 };
00038
00039
00040
00041 #define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
00042
00043 #define IPW_CMD_SET_WPA_PARAM 1
00044 #define IPW_CMD_SET_WPA_IE 2
00045 #define IPW_CMD_SET_ENCRYPTION 3
00046 #define IPW_CMD_MLME 4
00047
00048 #define IPW_PARAM_WPA_ENABLED 1
00049 #define IPW_PARAM_TKIP_COUNTERMEASURES 2
00050 #define IPW_PARAM_DROP_UNENCRYPTED 3
00051 #define IPW_PARAM_PRIVACY_INVOKED 4
00052 #define IPW_PARAM_AUTH_ALGS 5
00053 #define IPW_PARAM_IEEE_802_1X 6
00054
00055 #define IPW_MLME_STA_DEAUTH 1
00056 #define IPW_MLME_STA_DISASSOC 2
00057
00058 #define IPW_CRYPT_ERR_UNKNOWN_ALG 2
00059 #define IPW_CRYPT_ERR_UNKNOWN_ADDR 3
00060 #define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4
00061 #define IPW_CRYPT_ERR_KEY_SET_FAILED 5
00062 #define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6
00063 #define IPW_CRYPT_ERR_CARD_CONF_FAILED 7
00064
00065 #define IPW_CRYPT_ALG_NAME_LEN 16
00066
00067 struct ipw_param {
00068 u32 cmd;
00069 u8 sta_addr[ETH_ALEN];
00070 union {
00071 struct {
00072 u8 name;
00073 u32 value;
00074 } wpa_param;
00075 struct {
00076 u32 len;
00077 u8 reserved[32];
00078 u8 data[0];
00079 } wpa_ie;
00080 struct{
00081 u32 command;
00082 u32 reason_code;
00083 } mlme;
00084 struct {
00085 u8 alg[IPW_CRYPT_ALG_NAME_LEN];
00086 u8 set_tx;
00087 u32 err;
00088 u8 idx;
00089 u8 seq[8];
00090 u16 key_len;
00091 u8 key[0];
00092 } crypt;
00093
00094 } u;
00095 };
00096
00097
00098
00099 static int ipw_ioctl(struct wpa_driver_ipw_data *drv,
00100 struct ipw_param *param, int len, int show_err)
00101 {
00102 struct iwreq iwr;
00103
00104 memset(&iwr, 0, sizeof(iwr));
00105 strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
00106 iwr.u.data.pointer = (caddr_t) param;
00107 iwr.u.data.length = len;
00108
00109 if (ioctl(drv->sock, IPW_IOCTL_WPA_SUPPLICANT, &iwr) < 0) {
00110 int ret = errno;
00111 if (show_err)
00112 perror("ioctl[IPW_IOCTL_WPA_SUPPLICANT]");
00113 return ret;
00114 }
00115
00116 return 0;
00117 }
00118
00119
00120 static void ipw_show_set_key_error(struct ipw_param *param)
00121 {
00122 switch (param->u.crypt.err) {
00123 case IPW_CRYPT_ERR_UNKNOWN_ALG:
00124 wpa_printf(MSG_INFO, "Unknown algorithm '%s'.",
00125 param->u.crypt.alg);
00126 wpa_printf(MSG_INFO, "You may need to load kernel module to "
00127 "register that algorithm.");
00128 wpa_printf(MSG_INFO, "E.g., 'modprobe ieee80211_crypt_wep' for"
00129 " WEP.");
00130 break;
00131 case IPW_CRYPT_ERR_UNKNOWN_ADDR:
00132 wpa_printf(MSG_INFO, "Unknown address " MACSTR ".",
00133 MAC2STR(param->sta_addr));
00134 break;
00135 case IPW_CRYPT_ERR_CRYPT_INIT_FAILED:
00136 wpa_printf(MSG_INFO, "Crypt algorithm initialization failed.");
00137 break;
00138 case IPW_CRYPT_ERR_KEY_SET_FAILED:
00139 wpa_printf(MSG_INFO, "Key setting failed.");
00140 break;
00141 case IPW_CRYPT_ERR_TX_KEY_SET_FAILED:
00142 wpa_printf(MSG_INFO, "TX key index setting failed.");
00143 break;
00144 case IPW_CRYPT_ERR_CARD_CONF_FAILED:
00145 wpa_printf(MSG_INFO, "Card configuration failed.");
00146 break;
00147 }
00148 }
00149
00150
00151 static int ipw_set_wpa_ie(struct wpa_driver_ipw_data *drv,
00152 const u8 *wpa_ie, size_t wpa_ie_len)
00153 {
00154 struct ipw_param *param;
00155 int ret;
00156 size_t blen = sizeof(*param) + wpa_ie_len;
00157
00158 param = (struct ipw_param *) malloc(blen);
00159 if (param == NULL)
00160 return -1;
00161
00162 memset(param, 0, blen);
00163 param->cmd = IPW_CMD_SET_WPA_IE;
00164 param->u.wpa_ie.len = wpa_ie_len;
00165 memcpy(param->u.wpa_ie.data, wpa_ie, wpa_ie_len);
00166
00167 ret = ipw_ioctl(drv, param, blen, 1);
00168
00169 free(param);
00170 return ret;
00171 }
00172
00173
00174 static int ipw_set_wpa_param(struct wpa_driver_ipw_data *drv, u8 name,
00175 u32 value)
00176 {
00177 struct ipw_param param;
00178
00179 memset(¶m, 0, sizeof(param));
00180 param.cmd = IPW_CMD_SET_WPA_PARAM;
00181 param.u.wpa_param.name = name;
00182 param.u.wpa_param.value = value;
00183
00184 return ipw_ioctl(drv, ¶m, sizeof(param), 1);
00185 }
00186
00187
00188 static int ipw_mlme(struct wpa_driver_ipw_data *drv, const u8 *addr,
00189 int cmd, int reason)
00190 {
00191 struct ipw_param param;
00192
00193 memset(¶m, 0, sizeof(param));
00194 memcpy(param.sta_addr, addr, ETH_ALEN);
00195 param.cmd = IPW_CMD_MLME;
00196 param.u.mlme.command = cmd;
00197 param.u.mlme.reason_code = reason;
00198
00199 return ipw_ioctl(drv, ¶m, sizeof(param), 1);
00200 }
00201
00202
00203 static int wpa_driver_ipw_set_wpa(void *priv, int enabled)
00204 {
00205 struct wpa_driver_ipw_data *drv = priv;
00206 int ret = 0;
00207
00208 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00209
00210 if (!enabled && ipw_set_wpa_ie(drv, NULL, 0) < 0)
00211 ret = -1;
00212
00213 if (ipw_set_wpa_param(drv, IPW_PARAM_WPA_ENABLED, enabled) < 0)
00214 ret = -1;
00215
00216 return ret;
00217 }
00218
00219
00220 static int wpa_driver_ipw_set_key(void *priv, wpa_alg alg,
00221 const u8 *addr, int key_idx, int set_tx,
00222 const u8 *seq, size_t seq_len,
00223 const u8 *key, size_t key_len)
00224 {
00225 struct wpa_driver_ipw_data *drv = priv;
00226 struct ipw_param *param;
00227 u8 *buf;
00228 size_t blen;
00229 int ret = 0;
00230 char *alg_name;
00231
00232 switch (alg) {
00233 case WPA_ALG_NONE:
00234 alg_name = "none";
00235 break;
00236 case WPA_ALG_WEP:
00237 alg_name = "WEP";
00238 break;
00239 case WPA_ALG_TKIP:
00240 alg_name = "TKIP";
00241 break;
00242 case WPA_ALG_CCMP:
00243 alg_name = "CCMP";
00244 break;
00245 default:
00246 return -1;
00247 }
00248
00249 wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
00250 "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx,
00251 (unsigned long) seq_len, (unsigned long) key_len);
00252
00253 if (seq_len > 8)
00254 return -2;
00255
00256 blen = sizeof(*param) + key_len;
00257 buf = malloc(blen);
00258 if (buf == NULL)
00259 return -1;
00260 memset(buf, 0, blen);
00261
00262 param = (struct ipw_param *) buf;
00263 param->cmd = IPW_CMD_SET_ENCRYPTION;
00264 memset(param->sta_addr, 0xff, ETH_ALEN);
00265 strncpy((char *) param->u.crypt.alg, alg_name, IPW_CRYPT_ALG_NAME_LEN);
00266 param->u.crypt.set_tx = set_tx ? 1 : 0;
00267 param->u.crypt.idx = key_idx;
00268 memcpy(param->u.crypt.seq, seq, seq_len);
00269 param->u.crypt.key_len = key_len;
00270 memcpy((u8 *) (param + 1), key, key_len);
00271
00272 if (ipw_ioctl(drv, param, blen, 1)) {
00273 wpa_printf(MSG_WARNING, "Failed to set encryption.");
00274 ipw_show_set_key_error(param);
00275 ret = -1;
00276 }
00277 free(buf);
00278
00279 return ret;
00280 }
00281
00282
00283 static int wpa_driver_ipw_set_countermeasures(void *priv, int enabled)
00284 {
00285 struct wpa_driver_ipw_data *drv = priv;
00286 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00287 return ipw_set_wpa_param(drv, IPW_PARAM_TKIP_COUNTERMEASURES,
00288 enabled);
00289
00290 }
00291
00292
00293 static int wpa_driver_ipw_set_drop_unencrypted(void *priv, int enabled)
00294 {
00295 struct wpa_driver_ipw_data *drv = priv;
00296 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
00297 return ipw_set_wpa_param(drv, IPW_PARAM_DROP_UNENCRYPTED,
00298 enabled);
00299 }
00300
00301
00302 static int wpa_driver_ipw_deauthenticate(void *priv, const u8 *addr,
00303 int reason_code)
00304 {
00305 struct wpa_driver_ipw_data *drv = priv;
00306 return ipw_mlme(drv, addr, IPW_MLME_STA_DEAUTH, reason_code);
00307 }
00308
00309
00310 static int wpa_driver_ipw_disassociate(void *priv, const u8 *addr,
00311 int reason_code)
00312 {
00313 struct wpa_driver_ipw_data *drv = priv;
00314 return ipw_mlme(drv, addr, IPW_MLME_STA_DISASSOC, reason_code);
00315 }
00316
00317
00318 static int
00319 wpa_driver_ipw_associate(void *priv, struct wpa_driver_associate_params *params)
00320 {
00321 struct wpa_driver_ipw_data *drv = priv;
00322 int ret = 0;
00323 int unencrypted_eapol;
00324
00325 if (ipw_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
00326 ret = -1;
00327 if (wpa_driver_wext_set_ssid(drv->wext, params->ssid,
00328 params->ssid_len) < 0)
00329 ret = -1;
00330 if (wpa_driver_wext_set_bssid(drv->wext, params->bssid) < 0)
00331 ret = -1;
00332
00333 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
00334 params->key_mgmt_suite == KEY_MGMT_PSK)
00335 unencrypted_eapol = 0;
00336 else
00337 unencrypted_eapol = 1;
00338
00339 if (ipw_set_wpa_param(drv, IPW_PARAM_IEEE_802_1X,
00340 unencrypted_eapol) < 0) {
00341 wpa_printf(MSG_DEBUG, "ipw: Failed to configure "
00342 "ieee_802_1x param");
00343 }
00344
00345 return ret;
00346 }
00347
00348
00349 static int wpa_driver_ipw_set_auth_alg(void *priv, int auth_alg)
00350 {
00351 struct wpa_driver_ipw_data *drv = priv;
00352 int algs = 0;
00353
00354 if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
00355 algs |= 1;
00356 if (auth_alg & AUTH_ALG_SHARED_KEY)
00357 algs |= 2;
00358 if (auth_alg & AUTH_ALG_LEAP)
00359 algs |= 4;
00360 if (algs == 0)
00361 algs = 1;
00362
00363 wpa_printf(MSG_DEBUG, "%s: auth_alg=0x%x", __FUNCTION__, algs);
00364 return ipw_set_wpa_param(drv, IPW_PARAM_AUTH_ALGS, algs);
00365 }
00366
00367
00368 static int wpa_driver_ipw_get_bssid(void *priv, u8 *bssid)
00369 {
00370 struct wpa_driver_ipw_data *drv = priv;
00371 return wpa_driver_wext_get_bssid(drv->wext, bssid);
00372 }
00373
00374
00375 static int wpa_driver_ipw_get_ssid(void *priv, u8 *ssid)
00376 {
00377 struct wpa_driver_ipw_data *drv = priv;
00378 return wpa_driver_wext_get_ssid(drv->wext, ssid);
00379 }
00380
00381
00382 static int wpa_driver_ipw_scan(void *priv, const u8 *ssid, size_t ssid_len)
00383 {
00384 struct wpa_driver_ipw_data *drv = priv;
00385 return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
00386 }
00387
00388
00389 static int wpa_driver_ipw_get_scan_results(void *priv,
00390 struct wpa_scan_result *results,
00391 size_t max_size)
00392 {
00393 struct wpa_driver_ipw_data *drv = priv;
00394 return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
00395 }
00396
00397
00398 static void * wpa_driver_ipw_init(void *ctx, const char *ifname)
00399 {
00400 struct wpa_driver_ipw_data *drv;
00401
00402 wpa_printf(MSG_DEBUG, "%s is called", __FUNCTION__);
00403 drv = malloc(sizeof(*drv));
00404 if (drv == NULL)
00405 return NULL;
00406 memset(drv, 0, sizeof(*drv));
00407 drv->wext = wpa_driver_wext_init(ctx, ifname);
00408 if (drv->wext == NULL) {
00409 free(drv);
00410 return NULL;
00411 }
00412
00413 drv->ctx = ctx;
00414 strncpy(drv->ifname, ifname, sizeof(drv->ifname));
00415 drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
00416 if (drv->sock < 0) {
00417 wpa_driver_wext_deinit(drv->wext);
00418 free(drv);
00419 return NULL;
00420 }
00421
00422 return drv;
00423 }
00424
00425
00426 static void wpa_driver_ipw_deinit(void *priv)
00427 {
00428 struct wpa_driver_ipw_data *drv = priv;
00429 wpa_driver_wext_deinit(drv->wext);
00430 close(drv->sock);
00431 free(drv);
00432 }
00433
00434
00435 const struct wpa_driver_ops wpa_driver_ipw_ops = {
00436 .name = "ipw",
00437 .desc = "Intel ipw2100/2200 driver",
00438 .get_bssid = wpa_driver_ipw_get_bssid,
00439 .get_ssid = wpa_driver_ipw_get_ssid,
00440 .set_wpa = wpa_driver_ipw_set_wpa,
00441 .set_key = wpa_driver_ipw_set_key,
00442 .set_countermeasures = wpa_driver_ipw_set_countermeasures,
00443 .set_drop_unencrypted = wpa_driver_ipw_set_drop_unencrypted,
00444 .scan = wpa_driver_ipw_scan,
00445 .get_scan_results = wpa_driver_ipw_get_scan_results,
00446 .deauthenticate = wpa_driver_ipw_deauthenticate,
00447 .disassociate = wpa_driver_ipw_disassociate,
00448 .associate = wpa_driver_ipw_associate,
00449 .set_auth_alg = wpa_driver_ipw_set_auth_alg,
00450 .init = wpa_driver_ipw_init,
00451 .deinit = wpa_driver_ipw_deinit,
00452 };
00453