Updated WE-18 (WPA) proposal
Jouni Malinen
jkmaline
Sun Aug 29 21:54:41 PDT 2004
Finally, I had enough time to implement and test the proposed WE-18
(WPA) changes with Host AP driver and wpa_supplicant. This testing was
indeed needed since number of issues showed up. I have made an updated
version of the WE-18 proposal that seems to work with
hostap and wpa_supplicant (current development snapshot from
http://hostap/epitest.fi/). I have not yet verified how much of
interface needed for hostapd could be moved to these new parts of WE-18
instead of the currently used private ioctls.
Since WE-17 has apparently not yet been merged all the way into
linux-2.6 tree, the patch below is against Linux 2.6.8.1 that has been
patched with WE-17 patch (http://www.hpl.hp.com/personal/
Jean_Tourrilhes/Linux/iw268_we17-10.diff). This should be quite close
to what the final WE-18 would be diffed against. This WE-18 patch is
still experimental and it may still need to be changed (i.e., this
should not yet be merged into linux-2.6).
Change log against the latest WE-18 proposal (http://www.hpl.hp.com/
personal/Jean_Tourrilhes/Linux/iw_we18-3.diff):
- replaced optional parameter (iw_point) to SIOCSIWSCAN with a new ioctl
(SIOCSIWSCANEXT) since the previous design was not really backwards
compatible (e.g., 'iwlist wlan0 scan' did not work)
- replaced IWEVWPAIE/IWEVRSNIE with more generic IWEVGENIE which can
also be used with non-WPA (e.g., IEEE 802.11e/WMM) IEs; in addition,
fixed the type for this event to be IW_HEADER_TYPE_POINT (was _PARAM)
- use larger IW_GENERIC_IE_MAX (256->1024) to be able to handle possible
needs for future IEEE 802.11 amendments
- added new IW_AUTH_INDEX parameters IW_AUTH_WPA_ENABLED and
IW_AUTH_RX_UNENCRYPTED_EAPOL that were missing from the functionality
needed by wpa_supplicant interface
- changed IW_AUTH_WPA_VERSION, IW_AUTH_PAIRWISE_CIPHER,
IW_AUTH_GROUP_CIPHER, and IW_AUTH_KEY_MGMT to bit fields
- added LEAP to IW_AUTH_80211_AUTH_ALG values
- added IW_ENCODE_EXT_SET_TX_KEY (set key value and mark key as default
TX key with one ioctl)
- added some more comments to areas that were unclear (have generated
questions)
- added min_tokens values for SIOCSIWENCODEEXT and SIOCGIWENCODEEXT
Question: is length field in struct iw_point in bytes or tokens
(token_size bytes)? I assumed it was in bytes, but this did not work
very well with WE ioctls that had token_size != 1; I made SIOCSIWSCANEXT
use token_size = 1 for now, but it could be replaced to be
sizeof(struct) and min_tokens=max_tokesn=1 once this question is
resolved.
diff -upr 2.6.8.1-WE17/include/linux/wireless.h 2.6.8.1-WE18/include/linux/wireless.h
--- 2.6.8.1-WE17/include/linux/wireless.h 2004-08-29 21:23:32.277037256 -0700
+++ 2.6.8.1-WE18/include/linux/wireless.h 2004-08-29 19:25:33.000000000 -0700
@@ -1,7 +1,7 @@
/*
* This file define a set of standard wireless extensions
*
- * Version : 17 21.6.04
+ * Version : 18 29.8.04
*
* Authors : Jean Tourrilhes - HPL - <jt at hpl.hp.com>
* Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved.
@@ -82,7 +82,7 @@
* (there is some stuff that will be added in the future...)
* I just plan to increment with each new version.
*/
-#define WIRELESS_EXT 17
+#define WIRELESS_EXT 18
/*
* Changes :
@@ -182,6 +182,19 @@
* - Document (struct iw_quality *)->updated, add new flags (INVALID)
* - Wireless Event capability in struct iw_range
* - Add support for relative TxPower (yick !)
+ *
+ * V17 to V18 (From Jouni Malinen <jkmaline at cc.hut.fi>)
+ * ----------
+ * - Add support for WPA/WPA2
+ * - Add extended encoding configuration (SIOCSIWENCODEEXT and
+ * SIOCGIWENCODEEXT)
+ * - Add SIOCSIWGENIE/SIOCGIWGENIE
+ * - Add SIOCSIWMLME
+ * - Add struct iw_range bit field for supported encoding capabilities
+ * - Add extended scan request (SIOCSIWSCANEXT)
+ * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
+ * related parameters (extensible up to 4096 parameter values)
+ * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE
*/
/**************************** CONSTANTS ****************************/
@@ -256,6 +269,29 @@
#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
+/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
+ * This ioctl uses struct iw_point and data buffer that includes IE id and len
+ * fields. More than one IE may be included in the request. Setting the generic
+ * IE to empty buffer (len=0) removes the generic IE from the driver. */
+#define SIOCSIWGENIE 0x8B30 /* set generic IE */
+#define SIOCGIWGENIE 0x8B31 /* get generic IE */
+
+/* WPA : IEEE 802.11 MLME requests */
+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses
+ * struct iw_mlme */
+/* WPA : Authentication mode parameters */
+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */
+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */
+
+/* WPA : Extended version of encoding configuration */
+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */
+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */
+
+/* Extended scan request; like SIOCSIWSCAN, but with additional parameters in
+ * struct iw_scan_req buffer. This shares SIOCGIWSCAN for reading the results.
+ */
+#define SIOCSIWSCANEXT 0x8B36 /* trigger scanning (extended) */
+
/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
/* These 32 ioctl are wireless device private, for 16 commands.
@@ -297,6 +333,15 @@
#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..)
+ * (scan results); This includes id and
+ * length fields. One IWEVGENIE may
+ * contain more than one IE. Scan
+ * results may contain one or more
+ * IWEVGENIE events. */
+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure
+ * (struct iw_michaelmicfailure)
+ */
#define IWEVFIRST 0x8C00
@@ -432,12 +477,87 @@
#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
+/* struct iw_scan_req scan_type */
+#define IW_SCAN_TYPE_ACTIVE 0
+#define IW_SCAN_TYPE_PASSIVE 1
/* Maximum size of returned data */
#define IW_SCAN_MAX_DATA 4096 /* In bytes */
/* Max number of char in custom event - use multiple of them if needed */
#define IW_CUSTOM_MAX 256 /* In bytes */
+/* Generic information element */
+#define IW_GENERIC_IE_MAX 1024
+
+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
+#define IW_MLME_DEAUTH 0
+#define IW_MLME_DISASSOC 1
+
+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
+#define IW_AUTH_INDEX 0x0FFF
+#define IW_AUTH_FLAGS 0xF000
+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
+ * parameter that is being set/get to; value will be read/written to
+ * struct iw_param value field) */
+#define IW_AUTH_WPA_VERSION 0
+#define IW_AUTH_CIPHER_PAIRWISE 1
+#define IW_AUTH_CIPHER_GROUP 2
+#define IW_AUTH_KEY_MGMT 3
+#define IW_AUTH_TKIP_COUNTERMEASURES 4
+#define IW_AUTH_DROP_UNENCRYPTED 5
+#define IW_AUTH_80211_AUTH_ALG 6
+#define IW_AUTH_WPA_ENABLED 7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
+
+/* IW_AUTH_WPA_VERSION values (bit field) */
+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+#define IW_AUTH_WPA_VERSION_WPA 0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
+
+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
+#define IW_AUTH_CIPHER_NONE 0x00000001
+#define IW_AUTH_CIPHER_WEP40 0x00000002
+#define IW_AUTH_CIPHER_TKIP 0x00000004
+#define IW_AUTH_CIPHER_CCMP 0x00000008
+#define IW_AUTH_CIPHER_WEP104 0x00000010
+
+/* IW_AUTH_KEY_MGMT values (bit field) */
+#define IW_AUTH_KEY_MGMT_802_1X 1
+#define IW_AUTH_KEY_MGMT_PSK 2
+
+/* IW_AUTH_80211_AUTH_ALG values (bit field) */
+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
+#define IW_AUTH_ALG_SHARED_KEY 0x00000002
+#define IW_AUTH_ALG_LEAP 0x00000004
+
+/* SIOCSIWENCODEEXT definitions */
+#define IW_ENCODE_SEQ_MAX_SIZE 8
+/* struct iw_encode_ext ->alg */
+#define IW_ENCODE_ALG_NONE 0
+#define IW_ENCODE_ALG_WEP 1
+#define IW_ENCODE_ALG_TKIP 2
+#define IW_ENCODE_ALG_CCMP 3
+/* struct iw_encode_ext ->ext_flags */
+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
+
+/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
+#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */
+#define IW_MICFAILURE_GROUP 0x00000004
+#define IW_MICFAILURE_PAIRWISE 0x00000008
+#define IW_MICFAILURE_STAKEY 0x00000010
+#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported)
+ */
+
+/* Bit field values for enc_capa in struct iw_range */
+#define IW_ENC_CAPA_WPA 0x00000001
+#define IW_ENC_CAPA_WPA2 0x00000002
+#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
+#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
+
/* Event capability macros - in (struct iw_range *)->event_capa
* Because we have more than 32 possible events, we use an array of
* 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
@@ -546,6 +666,86 @@ struct iw_thrspy
struct iw_quality high; /* High threshold */
};
+/*
+ * Data for extended scan request (MLME-SCAN.request)
+ */
+struct iw_scan_req
+{
+ __u8 mode; /* IW_MODE_AUTO (= Both), IW_MODE_ADHOC, or
+ * IW_MODE_INFRA */
+ __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
+ __u8 essid_len;
+ __u8 num_channels; /* num entries in channel_list;
+ * 0 = scan all allowed channels */
+ struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
+ * individual address of a specific BSS */
+ /* Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
+ * the current ESSID. This allows scan requests for specific ESSID
+ * without having to change the current ESSID and potentially breaking
+ * the current association. */
+ __u8 essid[IW_ESSID_MAX_SIZE];
+ __u32 probe_delay; /* delay in usec prior to transmitting
+ * ProbeReq */
+ __u32 min_channel_time; /* in TU, >= probe_delay */
+ __u32 max_channel_time; /* in TU, >= min_channel_time */
+ struct iw_freq channel_list[IW_MAX_FREQUENCIES];
+};
+
+/* ------------------------- WPA SUPPORT ------------------------- */
+
+/*
+ * Extended data structure for get/set encoding (this is used with
+ * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
+ * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
+ * only the data contents changes (key data -> this structure, including
+ * key data).
+ *
+ * If the new key is the first group key, it will be set as the default
+ * TX key. Otherwise, default TX key index is only changed if
+ * IW_ENCODE_EXT_SET_TX_KEY flag is set.
+ *
+ * Key will be changed with SIOCSIWENCODEEXT in all cases except for
+ * special "change TX key index" operation which is indicated by setting
+ * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
+ *
+ * tx_seq/rx_seq are only used when respective
+ * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
+ * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
+ * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
+ * used only by an Authenticator (AP or an IBSS station) to get the
+ * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
+ * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
+ * debugging/testing.
+ */
+struct iw_encode_ext
+{
+ __u32 ext_flags; /* IW_ENCODE_EXT_* */
+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+ struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
+ * (group) keys or unicast address for
+ * individual keys */
+ __u16 alg; /* IW_ENCODE_ALG_* */
+ __u16 key_len;
+ __u8 key[0];
+};
+
+/* SIOCSIWMLME data */
+struct iw_mlme
+{
+ __u16 cmd; /* IW_MLME_* */
+ __u16 reason_code;
+ struct sockaddr addr;
+};
+
+/* IWEVMICHAELMICFAILURE data */
+struct iw_michaelmicfailure
+{
+ __u32 flags;
+ struct sockaddr src_addr;
+ __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+};
+
/* ------------------------ WIRELESS STATS ------------------------ */
/*
* Wireless statistics (used for /proc/net/wireless)
@@ -725,6 +925,8 @@ struct iw_range
struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
/* Note : this frequency list doesn't need to fit channel numbers,
* because each entry contain its channel index */
+
+ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
};
/*
diff -upr 2.6.8.1-WE17/net/core/wireless.c 2.6.8.1-WE18/net/core/wireless.c
--- 2.6.8.1-WE17/net/core/wireless.c 2004-08-29 21:23:32.285036040 -0700
+++ 2.6.8.1-WE18/net/core/wireless.c 2004-08-29 21:27:41.406163872 -0700
@@ -186,6 +186,12 @@ static const struct iw_ioctl_description
.header_type = IW_HEADER_TYPE_ADDR,
.flags = IW_DESCR_FLAG_DUMP,
},
+ [SIOCSIWMLME - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = sizeof(struct iw_mlme),
+ .min_tokens = 1,
+ .max_tokens = 1,
+ },
[SIOCGIWAPLIST - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_POINT,
.token_size = sizeof(struct sockaddr) +
@@ -272,6 +278,52 @@ static const struct iw_ioctl_description
[SIOCGIWPOWER - SIOCIWFIRST] = {
.header_type = IW_HEADER_TYPE_PARAM,
},
+ [SIOCSIWGENIE - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .max_tokens = IW_GENERIC_IE_MAX,
+ },
+ [SIOCGIWGENIE - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .max_tokens = IW_GENERIC_IE_MAX,
+ },
+ [SIOCSIWAUTH - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_PARAM,
+ },
+ [SIOCGIWAUTH - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_PARAM,
+ },
+ [SIOCSIWENCODEEXT - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .min_tokens = sizeof(struct iw_encode_ext),
+ .max_tokens = sizeof(struct iw_encode_ext) +
+ IW_ENCODING_TOKEN_MAX,
+ },
+ [SIOCGIWENCODEEXT - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .min_tokens = sizeof(struct iw_encode_ext),
+ .max_tokens = sizeof(struct iw_encode_ext) +
+ IW_ENCODING_TOKEN_MAX,
+ },
+ [SIOCSIWSCANEXT - SIOCIWFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+#if 0
+ /* FIX: JKM - is this correct? Is length in struct iw_point
+ * number of bytes or number of tokens in the buffer?
+ * I changed this to use token_size=1 for now, since I assumed
+ * length from user space would always be in bytes.. */
+ .token_size = sizeof(struct iw_scan_req),
+ .min_tokens = 1,
+ .max_tokens = 1,
+#else
+ .token_size = 1,
+ .min_tokens = sizeof(struct iw_scan_req),
+ .max_tokens = sizeof(struct iw_scan_req),
+#endif
+ },
};
static const int standard_ioctl_num = (sizeof(standard_ioctl) /
sizeof(struct iw_ioctl_description));
@@ -298,6 +350,16 @@ static const struct iw_ioctl_description
[IWEVEXPIRED - IWEVFIRST] = {
.header_type = IW_HEADER_TYPE_ADDR,
},
+ [IWEVGENIE - IWEVFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .max_tokens = IW_GENERIC_IE_MAX,
+ },
+ [IWEVMICHAELMICFAILURE - IWEVFIRST] = {
+ .header_type = IW_HEADER_TYPE_POINT,
+ .token_size = 1,
+ .max_tokens = sizeof(struct iw_michaelmicfailure),
+ },
};
static const int standard_event_num = (sizeof(standard_event) /
sizeof(struct iw_ioctl_description));
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list