From cd35db9fefa8278d780a019742b233efe8a7f0fd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 18 Nov 2008 15:45:25 +0200 Subject: [PATCH] Updated userspace MLME instructions for current mac80211 Remove the old code from driver_wext.c since the private ioctl interface is never going to be used with mac80211. driver_nl80211.c has an implementation than can be used with mac80211 (with two external patches to enable userspace MLME configuration are still required, though). --- src/drivers/driver_wext.c | 480 -------------------------------------- wpa_supplicant/ChangeLog | 3 + wpa_supplicant/defconfig | 15 +- 3 files changed, 11 insertions(+), 487 deletions(-) diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index a618a743a..74135d622 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -31,126 +31,6 @@ #include "ieee802_11_defs.h" #include "wpa_common.h" -#ifdef CONFIG_CLIENT_MLME -#include -/* old definitions from net/mac80211 */ - -typedef u32 __bitwise __be32; -typedef u64 __bitwise __be64; - -#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) -#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1) -#define PRISM2_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 3) - -#define PRISM2_PARAM_USER_SPACE_MLME 1045 -#define PRISM2_PARAM_MGMT_IF 1046 -#define PRISM2_HOSTAPD_ADD_STA 2 -#define PRISM2_HOSTAPD_REMOVE_STA 3 -#define PRISM2_HOSTAPD_GET_HW_FEATURES 1002 -#define PRISM2_HOSTAPD_MAX_BUF_SIZE 2048 - -#ifndef ALIGNED -#define ALIGNED __attribute__ ((aligned)) -#endif - -struct prism2_hostapd_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - u8 pad[2]; - union { - struct { - u16 aid; - u16 capability; - u8 supp_rates[32]; - u8 wds_flags; -#define IEEE80211_STA_DYNAMIC_ENC BIT(0) - u8 enc_flags; - u16 listen_interval; - } add_sta; - struct { - u16 num_modes; - u16 flags; - u8 data[0] ALIGNED; /* num_modes * feature data */ - } hw_features; - struct { - u16 mode; /* MODE_* */ - u16 num_supported_rates; - u16 num_basic_rates; - u8 data[0] ALIGNED; /* num_supported_rates * u16 + - * num_basic_rates * u16 */ - } set_rate_sets; - struct { - u16 mode; /* MODE_* */ - u16 chan; - u32 flag; - u8 power_level; /* regulatory limit in dBm */ - u8 antenna_max; - } set_channel_flag; - struct { - u32 rd; - } set_regulatory_domain; - struct { - u32 queue; - s32 aifs; - u32 cw_min; - u32 cw_max; - u32 burst_time; /* maximum burst time in 0.1 ms, i.e., - * 10 = 1 ms */ - } tx_queue_params; - } u; -}; - -struct hostapd_ioctl_hw_modes_hdr { - int mode; - int num_channels; - int num_rates; -}; - -/* - * frame format for the management interface that is slated - * to be replaced by "cooked monitor" with radiotap - */ -#define IEEE80211_FI_VERSION 0x80211001 -struct ieee80211_frame_info { - __be32 version; - __be32 length; - __be64 mactime; - __be64 hosttime; - __be32 phytype; - __be32 channel; - __be32 datarate; - __be32 antenna; - __be32 priority; - __be32 ssi_type; - __be32 ssi_signal; - __be32 ssi_noise; - __be32 preamble; - __be32 encoding; - - /* Note: this structure is otherwise identical to capture format used - * in linux-wlan-ng, but this additional field is used to provide meta - * data about the frame to hostapd. This was the easiest method for - * providing this information, but this might change in the future. */ - __be32 msg_type; -} __attribute__ ((packed)); - -/* old mode definitions */ -enum { - MODE_IEEE80211A = 0 /* IEEE 802.11a */, - MODE_IEEE80211B = 1 /* IEEE 802.11b only */, - MODE_ATHEROS_TURBO = 2 /* Atheros Turbo mode (2x.11a at 5 GHz) */, - MODE_IEEE80211G = 3 /* IEEE 802.11g (and 802.11b compatibility) */, - MODE_ATHEROS_TURBOG = 4 /* Atheros Turbo mode (2x.11g at 2.4 GHz) */, - NUM_IEEE80211_MODES = 5 -}; - -#ifndef ETH_P_ALL -#define ETH_P_ALL 0x0003 -#endif -#endif /* CONFIG_CLIENT_MLME */ - - - static int wpa_driver_wext_flush_pmkid(void *priv); static int wpa_driver_wext_get_range(void *priv); @@ -999,46 +879,6 @@ static int wpa_driver_wext_set_ifflags_ifname(struct wpa_driver_wext_data *drv, } -#ifdef CONFIG_CLIENT_MLME - -static int wpa_driver_prism2_param_set(struct wpa_driver_wext_data *drv, - int param, int value) -{ - struct iwreq iwr; - int *i; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - i = (int *) iwr.u.name; - *i++ = param; - *i++ = value; - - return ioctl(drv->ioctl_sock, PRISM2_IOCTL_PRISM2_PARAM, &iwr); -} - - -static int wpa_driver_prism2_param_get(struct wpa_driver_wext_data *drv, - int param) -{ - struct iwreq iwr; - int *i; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - i = (int *) iwr.u.name; - *i = param; - - if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_GET_PRISM2_PARAM, &iwr) < 0) { - perror("ioctl[PRISM2_IOCTL_GET_PRISM2_PARAM]"); - return -1; - } - - return *i; -} - -#endif /* CONFIG_CLIENT_MLME */ - - /** * wpa_driver_wext_set_ifflags - Set interface flags (SIOCSIFFLAGS) * @drv: driver_wext private data @@ -1193,18 +1033,6 @@ void wpa_driver_wext_deinit(void *priv) if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP); -#ifdef CONFIG_CLIENT_MLME - if (drv->mlmedev[0]) { - if (wpa_driver_wext_get_ifflags_ifname(drv, drv->mlmedev, - &flags) == 0) - (void) wpa_driver_wext_set_ifflags_ifname( - drv, drv->mlmedev, flags & ~IFF_UP); - wpa_driver_prism2_param_set(drv, PRISM2_PARAM_MGMT_IF, 0); - wpa_driver_prism2_param_set(drv, PRISM2_PARAM_USER_SPACE_MLME, - 0); - } -#endif /* CONFIG_CLIENT_MLME */ - close(drv->event_sock); close(drv->ioctl_sock); if (drv->mlme_sock >= 0) @@ -2463,304 +2291,6 @@ int wpa_driver_wext_set_operstate(void *priv, int state) } -#ifdef CONFIG_CLIENT_MLME -static int hostapd_ioctl(struct wpa_driver_wext_data *drv, - struct prism2_hostapd_param *param, int len) -{ - struct iwreq iwr; - - os_memset(&iwr, 0, sizeof(iwr)); - os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); - iwr.u.data.pointer = (caddr_t) param; - iwr.u.data.length = len; - - if (ioctl(drv->ioctl_sock, PRISM2_IOCTL_HOSTAPD, &iwr) < 0) { - perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); - return -1; - } - - return 0; -} - - -static struct wpa_hw_modes * -wpa_driver_wext_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) -{ - struct wpa_driver_wext_data *drv = priv; - struct prism2_hostapd_param *param; - u8 *pos, *end; - struct wpa_hw_modes *modes = NULL; - int i; - - param = os_zalloc(PRISM2_HOSTAPD_MAX_BUF_SIZE); - if (param == NULL) - return NULL; - param->cmd = PRISM2_HOSTAPD_GET_HW_FEATURES; - - if (hostapd_ioctl(drv, param, PRISM2_HOSTAPD_MAX_BUF_SIZE) < 0) { - perror("ioctl[PRISM2_IOCTL_HOSTAPD]"); - goto out; - } - - *num_modes = param->u.hw_features.num_modes; - *flags = param->u.hw_features.flags; - - pos = param->u.hw_features.data; - end = pos + PRISM2_HOSTAPD_MAX_BUF_SIZE - - (param->u.hw_features.data - (u8 *) param); - - modes = os_zalloc(*num_modes * sizeof(struct wpa_hw_modes)); - if (modes == NULL) - goto out; - - for (i = 0; i < *num_modes; i++) { - struct hostapd_ioctl_hw_modes_hdr *hdr; - struct wpa_hw_modes *feature; - int clen, rlen; - - hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos; - pos = (u8 *) (hdr + 1); - clen = hdr->num_channels * sizeof(struct wpa_channel_data); - rlen = hdr->num_rates * sizeof(struct wpa_rate_data); - - feature = &modes[i]; - switch (hdr->mode) { - case MODE_IEEE80211A: - feature->mode = WPA_MODE_IEEE80211A; - break; - case MODE_IEEE80211B: - feature->mode = WPA_MODE_IEEE80211B; - break; - case MODE_IEEE80211G: - feature->mode = WPA_MODE_IEEE80211G; - break; - case MODE_ATHEROS_TURBO: - case MODE_ATHEROS_TURBOG: - wpa_printf(MSG_ERROR, "Skip unsupported hw_mode=%d in " - "get_hw_features data", hdr->mode); - pos += clen + rlen; - continue; - default: - wpa_printf(MSG_ERROR, "Unknown hw_mode=%d in " - "get_hw_features data", hdr->mode); - wpa_supplicant_sta_free_hw_features(modes, *num_modes); - modes = NULL; - break; - } - feature->num_channels = hdr->num_channels; - feature->num_rates = hdr->num_rates; - - feature->channels = os_malloc(clen); - feature->rates = os_malloc(rlen); - if (!feature->channels || !feature->rates || - pos + clen + rlen > end) { - wpa_supplicant_sta_free_hw_features(modes, *num_modes); - modes = NULL; - break; - } - - os_memcpy(feature->channels, pos, clen); - pos += clen; - os_memcpy(feature->rates, pos, rlen); - pos += rlen; - } - -out: - os_free(param); - return modes; -} - - -int wpa_driver_wext_set_channel(void *priv, wpa_hw_mode phymode, int chan, - int freq) -{ - return wpa_driver_wext_set_freq(priv, freq); -} - - -static void wpa_driver_wext_mlme_read(int sock, void *eloop_ctx, - void *sock_ctx) -{ - struct wpa_driver_wext_data *drv = eloop_ctx; - int len; - unsigned char buf[3000]; - struct ieee80211_frame_info *fi; - struct ieee80211_rx_status rx_status; - - len = recv(sock, buf, sizeof(buf), 0); - if (len < 0) { - perror("recv[MLME]"); - return; - } - - if (len < (int) sizeof(struct ieee80211_frame_info)) { - wpa_printf(MSG_DEBUG, "WEXT: Too short MLME frame (len=%d)", - len); - return; - } - - fi = (struct ieee80211_frame_info *) buf; - if (ntohl(fi->version) != IEEE80211_FI_VERSION) { - wpa_printf(MSG_DEBUG, "WEXT: Invalid MLME frame info version " - "0x%x", ntohl(fi->version)); - return; - } - - os_memset(&rx_status, 0, sizeof(rx_status)); - rx_status.ssi = ntohl(fi->ssi_signal); - rx_status.channel = ntohl(fi->channel); - - wpa_supplicant_sta_rx(drv->ctx, - buf + sizeof(struct ieee80211_frame_info), - len - sizeof(struct ieee80211_frame_info), - &rx_status); -} - - -static int wpa_driver_wext_open_mlme(struct wpa_driver_wext_data *drv) -{ - int flags, ifindex, s; - struct sockaddr_ll addr; - struct ifreq ifr; - - if (wpa_driver_prism2_param_set(drv, PRISM2_PARAM_USER_SPACE_MLME, 1) < - 0) { - wpa_printf(MSG_ERROR, "WEXT: Failed to configure driver to " - "use user space MLME"); - return -1; - } - - if (wpa_driver_prism2_param_set(drv, PRISM2_PARAM_MGMT_IF, 1) < 0) { - wpa_printf(MSG_ERROR, "WEXT: Failed to add management " - "interface for user space MLME"); - return -1; - } - - ifindex = wpa_driver_prism2_param_get(drv, PRISM2_PARAM_MGMT_IF); - if (ifindex <= 0) { - wpa_printf(MSG_ERROR, "WEXT: MLME management device not " - "found"); - return -1; - } - - os_memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = ifindex; - if (ioctl(drv->ioctl_sock, SIOCGIFNAME, &ifr) != 0) { - perror("ioctl(SIOCGIFNAME)"); - return -1; - } - os_strlcpy(drv->mlmedev, ifr.ifr_name, sizeof(drv->mlmedev)); - wpa_printf(MSG_DEBUG, "WEXT: MLME management device '%s'", - drv->mlmedev); - - if (wpa_driver_wext_get_ifflags_ifname(drv, drv->mlmedev, &flags) != 0 - || wpa_driver_wext_set_ifflags_ifname(drv, drv->mlmedev, - flags | IFF_UP) != 0) { - wpa_printf(MSG_ERROR, "WEXT: Could not set interface " - "'%s' UP", drv->mlmedev); - return -1; - } - - s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); - if (s < 0) { - perror("socket[PF_PACKET,SOCK_RAW]"); - return -1; - } - - os_memset(&addr, 0, sizeof(addr)); - addr.sll_family = AF_PACKET; - addr.sll_ifindex = ifindex; - - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("bind(MLME)"); - return -1; - } - - if (eloop_register_read_sock(s, wpa_driver_wext_mlme_read, drv, NULL)) - { - wpa_printf(MSG_ERROR, "WEXT: Could not register MLME read " - "socket"); - close(s); - return -1; - } - - return s; -} - - -static int wpa_driver_wext_send_mlme(void *priv, const u8 *data, - size_t data_len) -{ - struct wpa_driver_wext_data *drv = priv; - int ret; - - ret = send(drv->mlme_sock, data, data_len, 0); - if (ret < 0) { - perror("send[MLME]"); - return -1; - } - - return 0; -} - - -static int wpa_driver_wext_mlme_add_sta(void *priv, const u8 *addr, - const u8 *supp_rates, - size_t supp_rates_len) -{ - struct wpa_driver_wext_data *drv = priv; - struct prism2_hostapd_param param; - size_t len; - - os_memset(¶m, 0, sizeof(param)); - param.cmd = PRISM2_HOSTAPD_ADD_STA; - os_memcpy(param.sta_addr, addr, ETH_ALEN); - len = supp_rates_len; - if (len > sizeof(param.u.add_sta.supp_rates)) - len = sizeof(param.u.add_sta.supp_rates); - os_memcpy(param.u.add_sta.supp_rates, supp_rates, len); - return hostapd_ioctl(drv, ¶m, sizeof(param)); -} - - -static int wpa_driver_wext_mlme_remove_sta(void *priv, const u8 *addr) -{ - struct wpa_driver_wext_data *drv = priv; - struct prism2_hostapd_param param; - - os_memset(¶m, 0, sizeof(param)); - param.cmd = PRISM2_HOSTAPD_REMOVE_STA; - os_memcpy(param.sta_addr, addr, ETH_ALEN); - return hostapd_ioctl(drv, ¶m, sizeof(param)); -} - -#endif /* CONFIG_CLIENT_MLME */ - - -static int wpa_driver_wext_set_param(void *priv, const char *param) -{ -#ifdef CONFIG_CLIENT_MLME - struct wpa_driver_wext_data *drv = priv; - - if (param == NULL) - return 0; - - wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); - - if (os_strstr(param, "use_mlme=1")) { - wpa_printf(MSG_DEBUG, "WEXT: Using user space MLME"); - drv->capa.flags |= WPA_DRIVER_FLAGS_USER_SPACE_MLME; - - drv->mlme_sock = wpa_driver_wext_open_mlme(drv); - if (drv->mlme_sock < 0) - return -1; - } -#endif /* CONFIG_CLIENT_MLME */ - - return 0; -} - - int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv) { return drv->we_version_compiled; @@ -2785,19 +2315,9 @@ const struct wpa_driver_ops wpa_driver_wext_ops = { .set_auth_alg = wpa_driver_wext_set_auth_alg, .init = wpa_driver_wext_init, .deinit = wpa_driver_wext_deinit, - .set_param = wpa_driver_wext_set_param, .add_pmkid = wpa_driver_wext_add_pmkid, .remove_pmkid = wpa_driver_wext_remove_pmkid, .flush_pmkid = wpa_driver_wext_flush_pmkid, .get_capa = wpa_driver_wext_get_capa, .set_operstate = wpa_driver_wext_set_operstate, -#ifdef CONFIG_CLIENT_MLME - .get_hw_feature_data = wpa_driver_wext_get_hw_feature_data, - .set_channel = wpa_driver_wext_set_channel, - .set_ssid = wpa_driver_wext_set_ssid, - .set_bssid = wpa_driver_wext_set_bssid, - .send_mlme = wpa_driver_wext_send_mlme, - .mlme_add_sta = wpa_driver_wext_mlme_add_sta, - .mlme_remove_sta = wpa_driver_wext_mlme_remove_sta, -#endif /* CONFIG_CLIENT_MLME */ }; diff --git a/wpa_supplicant/ChangeLog b/wpa_supplicant/ChangeLog index 29b30a5bc..fa53d473b 100644 --- a/wpa_supplicant/ChangeLog +++ b/wpa_supplicant/ChangeLog @@ -18,6 +18,9 @@ ChangeLog for wpa_supplicant session ticket overriding API that was included into the upstream OpenSSL 0.9.9 tree on 2008-11-15 (no additional OpenSSL patch is needed with that version anymore) + * updated userspace MLME instructions to match with the current Linux + mac80211 implementation; please also note that this can only be used + with driver_nl80211.c (the old code from driver_wext.c was removed) 2008-11-01 - v0.6.5 * added support for SHA-256 as X.509 certificate digest when using the diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index 2653654eb..1de76788d 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -346,14 +346,15 @@ CONFIG_PEERKEY=y #CONFIG_DYNAMIC_EAP_METHODS=y # Include client MLME (management frame processing). -# This can be used to move MLME processing of Devicescape IEEE 802.11 stack -# into user space. +# This can be used to move MLME processing of Linux mac80211 stack into user +# space. #CONFIG_CLIENT_MLME=y -# Currently, driver_devicescape.c build requires some additional parameters -# to be able to include some of the kernel header files. Following lines can -# be used to set these (WIRELESS_DEV must point to the root directory of the -# wireless-dev.git tree). -#WIRELESS_DEV=/usr/src/wireless-dev +# Currently, driver_nl80211.c build requires some additional parameters to be +# able to include some of the kernel header files. Following lines can be used +# to set these (WIRELESS_DEV must point to the root directory of the +# wireless-testing.git tree). In addition, mac80211 may need external patches +# to enable userspace MLME support. +#WIRELESS_DEV=/usr/src/wireless-testing #CFLAGS += -I$(WIRELESS_DEV)/net/mac80211 # IEEE Std 802.11r-2008 (Fast BSS Transition)