+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <linux/wireless.h>
-#include <net/ethernet.h>
-
-#include "hd.h"
-#include "hd_int.h"
-#include "wlan.h"
-
-#ifndef LIBHD_TINY
-
-#define AUTH_ALG_OPEN_SYSTEM 0x01
-#define AUTH_ALG_SHARED_KEY 0x02
-#define AUTH_ALG_LEAP 0x04
-
-typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-
-struct wpa_driver_ops {
- int (*set_wpa)(const char *ifnmae, int enabled);
- int (*set_auth_alg)(const char *ifname, int auth_alg);
- int (*set_key)(const char *ifname, wpa_alg alg, unsigned char *addr,
- int key_idx, int set_tx, u8 *seq, size_t seq_len,
- u8 *key, size_t key_len);
-};
-
-struct wpa_driver_ops wpa_driver_hostap_ops;
-struct wpa_driver_ops wpa_driver_prism54_ops;
-struct wpa_driver_ops wpa_driver_hermes_ops;
-struct wpa_driver_ops wpa_driver_madwifi_ops;
-struct wpa_driver_ops wpa_driver_atmel_ops;
-struct wpa_driver_ops wpa_driver_wext_ops;
-struct wpa_driver_ops wpa_driver_ndiswrapper_ops;
-struct wpa_driver_ops wpa_driver_ipw_ops;
-
-/* the iw_ functions are copied from libiw, so we do not need to
- link against it */
-
-int iw_sockets_open(void)
-{
- static const int families[] = {
- AF_INET, AF_IPX, AF_AX25, AF_APPLETALK
- };
- unsigned int i;
- int sock;
-
- /*
- * Now pick any (exisiting) useful socket family for generic queries
- * Note : don't open all the socket, only returns when one matches,
- * all protocols might not be valid.
- * Workaround by Jim Kaba <jkaba@sarnoff.com>
- * Note : in 99% of the case, we will just open the inet_sock.
- * The remaining 1% case are not fully correct...
- */
-
- /* Try all families we support */
- for(i = 0; i < sizeof(families)/sizeof(int); ++i)
- {
- /* Try to open the socket, if success returns it */
- sock = socket(families[i], SOCK_DGRAM, 0);
- if(sock >= 0)
- return sock;
- }
-
- return -1;
-}
-
-static inline int
-iw_get_ext(int skfd, /* Socket to the kernel */
- const char * ifname, /* Device name */
- int request, /* WE ID */
- struct iwreq * pwrq) /* Fixed part of the request */
-{
- /* Set device name */
- strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
- /* Do the request */
- return(ioctl(skfd, request, pwrq));
-}
-
-int iw_get_range_info(int skfd,
- const char * ifname,
- struct iw_range * range)
-{
- struct iwreq wrq;
- char buffer[sizeof(struct iw_range) * 2]; /* Large enough */
- struct iw_range * range_raw;
-
- /* Cleanup */
- bzero(buffer, sizeof(buffer));
-
- wrq.u.data.pointer = (caddr_t) buffer;
- wrq.u.data.length = sizeof(buffer);
- wrq.u.data.flags = 0;
- if(iw_get_ext(skfd, ifname, SIOCGIWRANGE, &wrq) < 0)
- return(-1);
-
- /* Point to the buffer */
- range_raw = (struct iw_range *) buffer;
-
- /* For new versions, we can check the version directly, for old versions
- * we use magic. 300 bytes is a also magic number, don't touch... */
- if(wrq.u.data.length < 300) {
- /* That's v10 or earlier. Ouch ! Let's make a guess...*/
- range_raw->we_version_compiled = 9;
- }
-
- /* Check how it needs to be processed */
- if(range_raw->we_version_compiled > 15) {
- /* This is our native format, that's easy... */
- /* Copy stuff at the right place, ignore extra */
- memcpy((char *) range, buffer, sizeof(struct iw_range));
- }
- else {
- /* not supported */
- return(-1);
- }
-
- return(0);
-}
-
-double iw_freq2float(const struct iw_freq * in)
-{
- int i;
- double res = (double) in->m;
- for(i = 0; i < in->e; i++)
- res *= 10;
- return(res);
-}
-
-void hd_scan_wlan(hd_data_t *hd_data)
-{
- hd_t *hd;
- hd_res_t *res;
- struct iw_range range;
- int k;
- int skfd;
- struct wpa_driver_ops *wpa_drv=NULL;
-
- if(!hd_probe_feature(hd_data, pr_wlan)) return;
-
- hd_data->module = mod_wlan;
-
- PROGRESS(1, 0, "detecting wlan features");
-
- if ((skfd = iw_sockets_open()) < 0) {
- ADD2LOG( "could not open socket, wlan feature query failed\n" );
- return;
- }
-
- for(hd = hd_data->hd; hd; hd = hd->next) {
- if(
- hd->base_class.id == bc_network &&
- hd->unix_dev_name ) {
- /* Get list of frequencies / channels */
- if(iw_get_range_info(skfd, hd->unix_dev_name, &range) < 0) {
- /* this failed, maybe device does not support wireless extensions */
- continue;
- }
- ADD2LOG("*** device %s is wireless ***\n", hd->unix_dev_name);
- hd->is.wlan = 1;
- res = new_mem(sizeof *res);
- res->any.type = res_wlan;
-
- if(range.num_frequency > 0) {
- char buff[20];
- for(k = 0; k < range.num_frequency; k++) {
- snprintf(buff, 19, "%i", range.freq[k].i);
- add_str_list(&res->wlan.channels, buff);
- snprintf(buff, 19, "%g", (float)iw_freq2float(&(range.freq[k]))/1000000000);
- add_str_list(&res->wlan.frequencies, buff);
- }
- for(k = 0; k < range.num_bitrates; k++) {
- snprintf(buff, 19, "%g", (float)range.bitrate[k]/1000000);
- add_str_list(&res->wlan.bitrates, buff);
- }
- for(k = 0; k < range.num_encoding_sizes; k++) {
- snprintf(buff, 19, "WEP%i", range.encoding_size[k]*8);
- add_str_list(&res->wlan.enc_modes, buff);
- }
-
- /* open mode is always supported */
- add_str_list(&res->wlan.auth_modes, "open");
- /* if WEP is supported, be assume shared key auth support */
- if(range.num_encoding_sizes) {
- add_str_list(&res->wlan.auth_modes, "sharedkey");
- }
-
- /* detect WPA capabilities */
- if (hd->drivers) {
- if (search_str_list(hd->drivers, "hostap_cs") ||
- search_str_list(hd->drivers, "hostap_pci") ||
- search_str_list(hd->drivers, "hostap_plx") )
- wpa_drv = &wpa_driver_hostap_ops;
- /* prism54 is not ready yet
- else if (search_str_list(hd->drivers, "prism54")==0)
- wpa_drv = &wpa_driver_prism54_ops;
- */
- else if (search_str_list(hd->drivers, "ath_pci"))
- wpa_drv = &wpa_driver_madwifi_ops;
- else if (strncmp(hd->drivers->str, "at76", 4)==0)
- wpa_drv = &wpa_driver_atmel_ops;
- else if (search_str_list(hd->drivers, "ndiswrapper"))
- wpa_drv = &wpa_driver_ndiswrapper_ops;
- else if ((search_str_list(hd->drivers, "ipw2100")) ||
- (search_str_list(hd->drivers, "ipw2200")) )
- wpa_drv = &wpa_driver_ipw_ops;
- }
-
- if (wpa_drv) {
- if (wpa_drv->set_wpa(hd->unix_dev_name, 1) == 0) {
- add_str_list(&res->wlan.auth_modes, "wpa-psk");
- add_str_list(&res->wlan.auth_modes, "wpa-eap");
- if (wpa_drv->set_auth_alg &&
- wpa_drv->set_auth_alg(hd->unix_dev_name, AUTH_ALG_LEAP)==0)
- add_str_list(&res->wlan.auth_modes, "wpa-leap");
- if (wpa_drv->set_key(hd->unix_dev_name, WPA_ALG_TKIP, "ff:ff:ff:ff:ff:ff",
- 0, 0, 0, 0,
- "00000000000000000000000000000000", 32) ==0)
- add_str_list(&res->wlan.enc_modes, "TKIP");
- if (wpa_drv->set_key(hd->unix_dev_name, WPA_ALG_CCMP, "ff:ff:ff:ff:ff:ff",
- 0, 0, 0, 0,
- "0000000000000000", 16) ==0)
- add_str_list(&res->wlan.enc_modes, "CCMP");
- wpa_drv->set_wpa(hd->unix_dev_name, 0);
- }
- }
- }
- add_res_entry(&hd->res, res);
- }
- }
-}
-
-/* following functions are copied from wpa_supplicant
- they are used to detect WPA capabilities */
-
-/* begin hostap */
-
-#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0)
-#define PRISM2_IOCTL_HOSTAPD (SIOCDEVPRIVATE + 14)
-#define HOSTAP_CRYPT_ALG_NAME_LEN 16
-#define HOSTAP_CRYPT_FLAG_SET_TX_KEY (1 << (0))
-#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
- ((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
-
-enum {
- PRISM2_SET_ENCRYPTION = 6,
- PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
- PRISM2_PARAM_AP_AUTH_ALGS = 15,
- PRISM2_PARAM_HOST_ROAMING = 21,
- PRISM2_PARAM_WPA = 36,
- PRISM2_PARAM_PRIVACY_INVOKED = 37,
-};
-
-struct prism2_hostapd_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u16 aid;
- u16 capability;
- u8 tx_supp_rates;
- } add_sta;
- struct {
- u32 inactive_sec;
- } get_info_sta;
- struct {
- u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
- u32 flags;
- u32 err;
- u8 idx;
- u8 seq[8]; /* sequence counter (set: RX, get: TX) */
- u16 key_len;
- u8 key[0];
- } crypt;
- struct {
- u32 flags_and;
- u32 flags_or;
- } set_flags_sta;
- struct {
- u16 rid;
- u16 len;
- u8 data[0];
- } rid;
- struct {
- u8 len;
- u8 data[0];
- } generic_elem;
- struct {
- u16 cmd;
- u16 reason_code;
- } mlme;
- struct {
- u8 ssid_len;
- u8 ssid[32];
- } scan_req;
- } u;
-};
-
-
-int hostapd_ioctl(const char *dev, struct prism2_hostapd_param *param,
- int len, int show_err)
-{
- int s;
- int ret =0;
- struct iwreq iwr;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, dev, IFNAMSIZ);
- iwr.u.data.pointer = (caddr_t) param;
- iwr.u.data.length = len;
-
- if (ioctl(s, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) {
- ret=1;
- }
- close(s);
-
- return 0;
-}
-
-int prism2param(const char *ifname, int param, int value)
-{
- struct iwreq iwr;
- int *i, s, ret = 0;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
- i = (int *) iwr.u.name;
- *i++ = param;
- *i++ = value;
-
- if (ioctl(s, PRISM2_IOCTL_PRISM2_PARAM, &iwr) < 0) {
- ret = -1;
- }
- close(s);
- return ret;
-}
-
-int wpa_driver_hostap_set_auth_alg(const char *ifname, int auth_alg)
-{
- int algs = 0;
-
- if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
- algs |= 1;
- if (auth_alg & AUTH_ALG_SHARED_KEY)
- algs |= 2;
- if (auth_alg & AUTH_ALG_LEAP)
- algs |= 4;
- if (algs == 0)
- algs = 1; /* at least one algorithm should be set */
-
- return prism2param(ifname, PRISM2_PARAM_AP_AUTH_ALGS, algs);
-}
-
-int wpa_driver_hostap_set_wpa(const char *ifname, int enabled)
-{
- int ret = 0;
-
- if (prism2param(ifname, PRISM2_PARAM_HOST_ROAMING,
- enabled ? 2 : 0) < 0)
- ret = -1;
- if (prism2param(ifname, PRISM2_PARAM_PRIVACY_INVOKED, enabled) < 0)
- ret = -1;
- if (prism2param(ifname, PRISM2_PARAM_WPA, enabled) < 0)
- ret = -1;
-
- return ret;
-}
-
-int wpa_driver_hostap_set_key(const char *ifname, wpa_alg alg,
- unsigned char *addr, int key_idx,
- int set_tx, u8 *seq, size_t seq_len,
- u8 *key, size_t key_len)
-{
- struct prism2_hostapd_param *param;
- u8 *buf;
- size_t blen;
- int ret = 0;
- char *alg_name;
-
- switch (alg) {
- case WPA_ALG_NONE:
- alg_name = "none";
- break;
- case WPA_ALG_WEP:
- alg_name = "WEP";
- break;
- case WPA_ALG_TKIP:
- alg_name = "TKIP";
- break;
- case WPA_ALG_CCMP:
- alg_name = "CCMP";
- break;
- default:
- return -1;
- }
-
- if (seq_len > 8)
- return -2;
-
- blen = sizeof(*param) + key_len;
- buf = malloc(blen);
- if (buf == NULL)
- return -1;
- memset(buf, 0, blen);
-
- param = (struct prism2_hostapd_param *) buf;
- param->cmd = PRISM2_SET_ENCRYPTION;
- memset(param->sta_addr, 0xff, ETH_ALEN);
-
- strncpy(param->u.crypt.alg, alg_name, HOSTAP_CRYPT_ALG_NAME_LEN);
- param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0;
- param->u.crypt.idx = key_idx;
- memcpy(param->u.crypt.seq, seq, seq_len);
- param->u.crypt.key_len = key_len;
- memcpy((u8 *) (param + 1), key, key_len);
-
- if (hostapd_ioctl(ifname, param, blen, 1)) {
- ret = -1;
- }
- free(buf);
-
- return ret;
-}
-
-struct wpa_driver_ops wpa_driver_hostap_ops = {
- .set_wpa = wpa_driver_hostap_set_wpa,
- .set_key = wpa_driver_hostap_set_key,
- .set_auth_alg = wpa_driver_hostap_set_auth_alg,
-};
-
-/* end hostap */
-
-/* begin madwifi */
-
-#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0)
-#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+2)
-#define IEEE80211_CIPHER_WEP 0
-#define IEEE80211_CIPHER_TKIP 1
-#define IEEE80211_CIPHER_AES_CCM 3
-#define IEEE80211_ADDR_LEN 6
-#define IEEE80211_KEY_XMIT 0x01
-#define IEEE80211_KEY_RECV 0x02
-#define IEEE80211_KEYBUF_SIZE 16
-#define IEEE80211_MICBUF_SIZE 16
-
-enum {
- IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */
- IEEE80211_PARAM_ROAMING = 12, /* roaming mode */
- IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */
-};
-
-struct ieee80211req_key {
- u_int8_t ik_type; /* key/cipher type */
- u_int8_t ik_pad;
- u_int16_t ik_keyix; /* key index */
- u_int8_t ik_keylen; /* key length in bytes */
- u_int8_t ik_flags;
-#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */
- u_int8_t ik_macaddr[IEEE80211_ADDR_LEN];
- u_int64_t ik_keyrsc; /* key receive sequence counter */
- u_int64_t ik_keytsc; /* key transmit sequence counter */
- u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
-};
-
-int
-set80211param(const char *dev, int op, int arg)
-{
- struct iwreq iwr;
- int s=-1;
-
- if (s < 0 ? (s = socket(AF_INET, SOCK_DGRAM, 0)) == -1 : 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, dev, IFNAMSIZ);
- iwr.u.mode = op;
- memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
-
- if (ioctl(s, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
- return -1;
- }
- return 0;
-}
-
-static int
-wpa_driver_madwifi_set_wpa(const char *ifname, int enabled)
-{
- int ret = 0;
-
- if (set80211param(ifname, IEEE80211_PARAM_ROAMING, enabled ? 2 : 0) < 0)
- ret = -1;
- if (set80211param(ifname, IEEE80211_PARAM_PRIVACY, enabled) < 0)
- ret = -1;
- if (set80211param(ifname, IEEE80211_PARAM_WPA, enabled ? 3 : 0) < 0)
- ret = -1;
-
- return ret;
-}
-
-static int
-set80211priv(const char *dev, int op, void *data, int len)
-{
- struct iwreq iwr;
- int s=-1;
-
- if (s < 0 ? (s = socket(AF_INET, SOCK_DGRAM, 0)) == -1 : 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, dev, IFNAMSIZ);
- if (len < IFNAMSIZ) {
- /*
- * Argument data fits inline; put it there.
- */
- memcpy(iwr.u.name, data, len);
- } else {
- /*
- * Argument data too big for inline transfer; setup a
- * parameter block instead; the kernel will transfer
- * the data for the driver.
- */
- iwr.u.data.pointer = data;
- iwr.u.data.length = len;
- }
-
- if (ioctl(s, op, &iwr) < 0) {
- return -1;
- }
- return 0;
-}
-
-static int
-wpa_driver_madwifi_set_key(const char *ifname, wpa_alg alg,
- unsigned char *addr, int key_idx,
- int set_tx, u8 *seq, size_t seq_len,
- u8 *key, size_t key_len)
-{
- struct ieee80211req_key wk;
- char *alg_name;
- u_int8_t cipher;
-
- if (alg == WPA_ALG_NONE)
- return 0;
-
- switch (alg) {
- case WPA_ALG_WEP:
- alg_name = "WEP";
- cipher = IEEE80211_CIPHER_WEP;
- break;
- case WPA_ALG_TKIP:
- alg_name = "TKIP";
- cipher = IEEE80211_CIPHER_TKIP;
- break;
- case WPA_ALG_CCMP:
- alg_name = "CCMP";
- cipher = IEEE80211_CIPHER_AES_CCM;
- break;
- default:
- return -1;
- }
-
- if (seq_len > sizeof(u_int64_t)) {
- return -2;
- }
- if (key_len > sizeof(wk.ik_keydata)) {
- return -3;
- }
-
- memset(&wk, 0, sizeof(wk));
- wk.ik_type = cipher;
- wk.ik_flags = IEEE80211_KEY_RECV;
- if (set_tx) {
- wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT;
- memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
- } else
- memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN);
- wk.ik_keyix = key_idx;
- wk.ik_keylen = key_len;
- memcpy(&wk.ik_keyrsc, seq, seq_len);
- memcpy(wk.ik_keydata, key, key_len);
-
- return set80211priv(ifname, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
-}
-
-struct wpa_driver_ops wpa_driver_madwifi_ops = {
- .set_wpa = wpa_driver_madwifi_set_wpa,
- .set_key = wpa_driver_madwifi_set_key,
-};
-
-/* end madwifi */
-
-/* begin ipw */
-
-#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
-#define IPW_CMD_SET_WPA_PARAM 1
-#define IPW_CMD_SET_ENCRYPTION 3
-#define IPW_PARAM_WPA_ENABLED 1
-#define IPW_PARAM_AUTH_ALGS 5
-#define IPW_CRYPT_ALG_NAME_LEN 16
-
-struct ipw_param {
- u32 cmd;
- u8 sta_addr[ETH_ALEN];
- union {
- struct {
- u8 name;
- u32 value;
- } wpa_param;
- struct {
- u32 len;
- u8 *data;
- } wpa_ie;
- struct{
- int command;
- int reason_code;
- } mlme;
- struct {
- u8 alg[IPW_CRYPT_ALG_NAME_LEN];
- u8 set_tx;
- u32 err;
- u8 idx;
- u8 seq[8];
- u16 key_len;
- u8 key[0];
- } crypt;
-
- } u;
-};
-
-int ipw_ioctl(const char *dev, struct ipw_param *param, int len)
-{
- struct iwreq iwr;
- int s;
- int ret = 0;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, dev, IFNAMSIZ);
- iwr.u.data.pointer = (caddr_t) param;
- iwr.u.data.length = len;
-
- if (ioctl(s, IPW_IOCTL_WPA_SUPPLICANT, &iwr) < 0) {
- ret = -1;
- }
-
- close(s);
- return ret;
-}
-
-int wpa_driver_ipw_set_wpa(const char *ifname, int enabled)
-{
- int ret = 0;
- struct ipw_param param;
-
- memset(¶m, 0, sizeof(param));
- param.cmd = IPW_CMD_SET_WPA_PARAM;
- param.u.wpa_param.name = IPW_PARAM_WPA_ENABLED;
- param.u.wpa_param.value = enabled;
-
- if (ipw_ioctl(ifname, ¶m, sizeof(param)) < 0)
- ret = -1;
-
- return ret;
-}
-
-int wpa_driver_ipw_set_key(const char *ifname, wpa_alg alg,
- unsigned char *addr, int key_idx, int set_tx,
- u8 *seq, size_t seq_len,
- u8 *key, size_t key_len)
-{
- struct ipw_param *param;
- u8 *buf;
- size_t blen;
- int ret = 0;
- char *alg_name;
-
- switch (alg) {
- case WPA_ALG_NONE:
- alg_name = "none";
- break;
- case WPA_ALG_WEP:
- alg_name = "WEP";
- break;
- case WPA_ALG_TKIP:
- alg_name = "TKIP";
- break;
- case WPA_ALG_CCMP:
- alg_name = "CCMP";
- break;
- default:
- return -1;
- }
-
- if (seq_len > 8)
- return -2;
-
- blen = sizeof(*param) + key_len;
- buf = malloc(blen);
- if (buf == NULL)
- return -1;
- memset(buf, 0, blen);
-
- param = (struct ipw_param *) buf;
- param->cmd = IPW_CMD_SET_ENCRYPTION;
- memset(param->sta_addr, 0xff, ETH_ALEN);
- strncpy(param->u.crypt.alg, alg_name, IPW_CRYPT_ALG_NAME_LEN);
- param->u.crypt.set_tx = set_tx ? 1 : 0;
- param->u.crypt.idx = key_idx;
- memcpy(param->u.crypt.seq, seq, seq_len);
- param->u.crypt.key_len = key_len;
- memcpy((u8 *) (param + 1), key, key_len);
-
- if (ipw_ioctl(ifname, param, blen)) {
- ret = -1;
- }
- free(buf);
-
- return ret;
-}
-
-int wpa_driver_ipw_set_auth_alg(const char *ifname, int auth_alg)
-{
- int algs = 0;
- struct ipw_param param;
-
- if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
- algs |= 1;
- if (auth_alg & AUTH_ALG_SHARED_KEY)
- algs |= 2;
- if (auth_alg & AUTH_ALG_LEAP)
- algs |= 4;
- if (algs == 0)
- algs = 1; /* at least one algorithm should be set */
-
- memset(¶m, 0, sizeof(param));
- param.cmd = IPW_CMD_SET_WPA_PARAM;
- param.u.wpa_param.name = IPW_PARAM_AUTH_ALGS;
- param.u.wpa_param.value = algs;
-
- return ipw_ioctl(ifname, ¶m, sizeof(param));
-}
-
-struct wpa_driver_ops wpa_driver_ipw_ops = {
- .set_wpa = wpa_driver_ipw_set_wpa,
- .set_key = wpa_driver_ipw_set_key,
- .set_auth_alg = wpa_driver_ipw_set_auth_alg
-};
-
-/* end ipw */
-
-/* begin atmel */
-
-#define ATMEL_WPA_IOCTL (SIOCIWFIRSTPRIV + 2)
-#define ATMEL_WPA_IOCTL_PARAM (SIOCIWFIRSTPRIV + 3)
-#define ATMEL_WPA_IOCTL_GET_PARAM (SIOCIWFIRSTPRIV + 4)
-
-#define MAX_KEY_LENGTH 40
-
-/* ATMEL_WPA_IOCTL ioctl() cmd: */
-enum {
- SET_WPA_ENCRYPTION = 1,
- SET_CIPHER_SUITES = 2,
-};
-
-/* ATMEL_WPA_IOCTL_PARAM ioctl() cmd: */
-enum {
- ATMEL_PARAM_WPA = 1,
- ATMEL_PARAM_PRIVACY_INVOKED = 2,
- ATMEL_PARAM_WPA_TYPE = 3,
-};
-
-struct atmel_param{
- unsigned char sta_addr[6];
- int cmd;
- u8 alg;
- u8 key_idx;
- u8 set_tx;
- u8 seq[8];
- u8 seq_len;
- u16 key_len;
- u8 key[MAX_KEY_LENGTH];
- struct{
- int reason_code;
- u8 state;
- }mlme;
- u8 pairwise_suite;
- u8 group_suite;
- u8 key_mgmt_suite;
-};
-
-int atmel_ioctl(const char *dev, struct atmel_param *param, int len)
-{
- int s;
- int ret=0;
- struct iwreq iwr;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, dev, IFNAMSIZ);
- iwr.u.data.pointer = (caddr_t) param;
- iwr.u.data.length = len;
-
- if (ioctl(s, ATMEL_WPA_IOCTL, &iwr) < 0) {
- ret = -1;
- }
- close(s);
-
- return 0;
-}
-
-int atmel2param(const char *ifname, int param, int value)
-{
- struct iwreq iwr;
- int *i, s, ret = 0;
-
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return -1;
- }
-
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, ifname, IFNAMSIZ);
- i = (int *) iwr.u.name;
- *i++ = param;
- *i++ = value;
-
- if (ioctl(s, ATMEL_WPA_IOCTL_PARAM, &iwr) < 0) {
- ret = -1;
- }
- close(s);
- return ret;
-}
-
-int wpa_driver_atmel_set_wpa(const char *ifname, int enabled)
-{
- int ret = 0;
-
- if (atmel2param(ifname, ATMEL_PARAM_PRIVACY_INVOKED, enabled) < 0)
- ret = -1;
- if (atmel2param(ifname, ATMEL_PARAM_WPA, enabled) < 0)
- ret = -1;
-
- return ret;
-}
-
-int wpa_driver_atmel_set_key(const char *ifname, wpa_alg alg,
- unsigned char *addr, int key_idx,
- int set_tx, u8 *seq, size_t seq_len,
- u8 *key, size_t key_len)
-{
- int ret = 0;
- struct atmel_param *param;
- u8 *buf;
- u8 alg_type;
-
- size_t blen;
- char *alg_name;
-
- switch (alg) {
- case WPA_ALG_NONE:
- alg_name = "none";
- alg_type = 0;
- break;
- case WPA_ALG_WEP:
- alg_name = "WEP";
- alg_type = 1;
- break;
- case WPA_ALG_TKIP:
- alg_name = "TKIP";
- alg_type = 2;
- break;
- case WPA_ALG_CCMP:
- alg_name = "CCMP";
- alg_type = 3;
- break;
- default:
- return -1;
- }
-
- if (seq_len > 8)
- return -2;
-
- blen = sizeof(*param) + key_len;
- buf = malloc(blen);
- if (buf == NULL)
- return -1;
- memset(buf, 0, blen);
-
- param = (struct atmel_param *) buf;
-
- param->cmd = SET_WPA_ENCRYPTION;
-
- if (addr == NULL)
- memset(param->sta_addr, 0xff, ETH_ALEN);
- else
- memcpy(param->sta_addr, addr, ETH_ALEN);
-
- param->alg = alg_type;
- param->key_idx = key_idx;
- param->set_tx = set_tx;
- memcpy(param->seq, seq, seq_len);
- param->seq_len = seq_len;
- param->key_len = key_len;
- memcpy((u8 *)param->key, key, key_len);
-
- if (atmel_ioctl(ifname, param, blen)) {
- ret = -1;
- }
- free(buf);
-
- return ret;
-}
-
-struct wpa_driver_ops wpa_driver_atmel_ops = {
- .set_wpa = wpa_driver_atmel_set_wpa,
- .set_key = wpa_driver_atmel_set_key,
-};
-
-/* end atmel */
-
-/* begin ndiswrapper */
-
-#define WPA_SET_WPA SIOCIWFIRSTPRIV+1
-#define WPA_SET_KEY SIOCIWFIRSTPRIV+2
-#define WPA_SET_AUTH_ALG SIOCIWFIRSTPRIV+8
-
-struct wpa_key
-{
- wpa_alg alg;
- u8 *addr;
- int key_index;
- int set_tx;
- u8 *seq;
- size_t seq_len;
- u8 *key;
- size_t key_len;
-};
-
-int wpa_ndiswrapper_set_ext(const char *ifname, int request, struct iwreq *pwrq)
-{
- int s;
- int ret;
-
- s = socket( AF_INET, SOCK_DGRAM, 0);
- if (s < 0)
- return -1;
-
- strncpy(pwrq->ifr_name, ifname, IFNAMSIZ);
- ret = ioctl(s, request, pwrq);
- close(s);
- return ret;
-}
-
-int wpa_ndiswrapper_set_wpa(const char *ifname, int enabled)
-{
- struct iwreq priv_req;
- int ret = 0;
-
- memset(&priv_req, 0, sizeof(priv_req));
-
- priv_req.u.data.flags = enabled;
- if (wpa_ndiswrapper_set_ext(ifname, WPA_SET_WPA, &priv_req) < 0)
- ret = -1;
- return ret;
-}
-
-int wpa_ndiswrapper_set_key(const char *ifname, wpa_alg alg, u8 *addr,
- int key_idx, int set_tx, u8 *seq,
- size_t seq_len, u8 *key, size_t key_len)
-{
- struct wpa_key wpa_key;
- int ret = 0;
- struct iwreq priv_req;
-
- memset(&priv_req, 0, sizeof(priv_req));
-
- wpa_key.alg = alg;
- wpa_key.addr = addr;
- wpa_key.key_index = key_idx;
- wpa_key.set_tx = set_tx;
- wpa_key.seq = seq;
- wpa_key.seq_len = seq_len;
- wpa_key.key = key;
- wpa_key.key_len = key_len;
-
- priv_req.u.data.pointer = (void *)&wpa_key;
-
- if (wpa_ndiswrapper_set_ext(ifname, WPA_SET_KEY, &priv_req) < 0)
- ret = -1;
- return ret;
-}
-
-static int wpa_ndiswrapper_set_auth_alg(const char *ifname, int auth_alg)
-{
- int ret = 0;
- struct iwreq priv_req;
-
- memset(&priv_req, 0, sizeof(priv_req));
-
- priv_req.u.param.value = auth_alg;
- if (wpa_ndiswrapper_set_ext(ifname, WPA_SET_AUTH_ALG, &priv_req) < 0)
- ret = -1;
- return ret;
-}
-
-struct wpa_driver_ops wpa_driver_ndiswrapper_ops = {
- .set_wpa = wpa_ndiswrapper_set_wpa,
- .set_key = wpa_ndiswrapper_set_key,
- .set_auth_alg = wpa_ndiswrapper_set_auth_alg,
-};
-
-/* end ndiswrapper */
-
-#endif /* !defined(LIBHD_TINY) */
-