1 diff -Nur linux-2.4.32/include/linux/netdevice.h linux-2.4.32-we/include/linux/netdevice.h
2 --- linux-2.4.32/include/linux/netdevice.h 2004-11-17 12:54:22.000000000 +0100
3 +++ linux-2.4.32-we/include/linux/netdevice.h 2006-03-13 12:10:57.000000000 +0100
6 /* List of functions to handle Wireless Extensions (instead of ioctl).
7 * See <net/iw_handler.h> for details. Jean II */
8 - struct iw_handler_def * wireless_handlers;
9 + const struct iw_handler_def * wireless_handlers;
10 + /* Instance data managed by the core of Wireless Extensions. */
11 + struct iw_public_data * wireless_data;
13 struct ethtool_ops *ethtool_ops;
15 diff -Nur linux-2.4.32/include/linux/wireless.h linux-2.4.32-we/include/linux/wireless.h
16 --- linux-2.4.32/include/linux/wireless.h 2003-11-28 19:26:21.000000000 +0100
17 +++ linux-2.4.32-we/include/linux/wireless.h 2006-03-13 12:11:02.000000000 +0100
20 * This file define a set of standard wireless extensions
22 - * Version : 16 2.4.03
23 + * Version : 18 12.3.05
25 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
26 - * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
27 + * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
30 #ifndef _LINUX_WIRELESS_H
32 * # include/net/iw_handler.h
34 * Note as well that /proc/net/wireless implementation has now moved in :
35 - * # include/linux/wireless.c
36 + * # net/core/wireless.c
38 * Wireless Events (2002 -> onward) :
39 * --------------------------------
40 * Events are defined at the end of this file, and implemented in :
41 - * # include/linux/wireless.c
42 + * # net/core/wireless.c
47 * (there is some stuff that will be added in the future...)
48 * I just plan to increment with each new version.
50 -#define WIRELESS_EXT 16
51 +#define WIRELESS_EXT 18
56 * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
57 * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
58 * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
62 + * - Add flags to frequency -> auto/fixed
63 + * - Document (struct iw_quality *)->updated, add new flags (INVALID)
64 + * - Wireless Event capability in struct iw_range
65 + * - Add support for relative TxPower (yick !)
67 + * V17 to V18 (From Jouni Malinen <jkmaline@cc.hut.fi>)
69 + * - Add support for WPA/WPA2
70 + * - Add extended encoding configuration (SIOCSIWENCODEEXT and
72 + * - Add SIOCSIWGENIE/SIOCGIWGENIE
74 + * - Add SIOCSIWPMKSA
75 + * - Add struct iw_range bit field for supported encoding capabilities
76 + * - Add optional scan request parameters for SIOCSIWSCAN
77 + * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
78 + * related parameters (extensible up to 4096 parameter values)
79 + * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
80 + * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
83 /**************************** CONSTANTS ****************************/
85 #define SIOCSIWPOWER 0x8B2C /* set Power Management settings */
86 #define SIOCGIWPOWER 0x8B2D /* get Power Management settings */
88 +/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
89 + * This ioctl uses struct iw_point and data buffer that includes IE id and len
90 + * fields. More than one IE may be included in the request. Setting the generic
91 + * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers
92 + * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers
93 + * are required to report the used IE as a wireless event, e.g., when
94 + * associating with an AP. */
95 +#define SIOCSIWGENIE 0x8B30 /* set generic IE */
96 +#define SIOCGIWGENIE 0x8B31 /* get generic IE */
98 +/* WPA : IEEE 802.11 MLME requests */
99 +#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses
100 + * struct iw_mlme */
101 +/* WPA : Authentication mode parameters */
102 +#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */
103 +#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */
105 +/* WPA : Extended version of encoding configuration */
106 +#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */
107 +#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */
109 +/* WPA2 : PMKSA cache management */
110 +#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */
112 /* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
114 -/* These 16 ioctl are wireless device private.
115 +/* These 32 ioctl are wireless device private, for 16 commands.
116 * Each driver is free to use them for whatever purpose it chooses,
117 * however the driver *must* export the description of those ioctls
118 * with SIOCGIWPRIV and *must* use arguments as defined below.
120 * We now have 32 commands, so a bit more space ;-).
121 * Also, all 'odd' commands are only usable by root and don't return the
122 * content of ifr/iwr to user (but you are not obliged to use the set/get
123 - * convention, just use every other two command).
124 - * And I repeat : you are not obliged to use them with iwspy, but you
125 + * convention, just use every other two command). More details in iwpriv.c.
126 + * And I repeat : you are not forced to use them with iwpriv, but you
127 * must be compliant with it.
131 #define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
132 #define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
133 #define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
134 +#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..)
135 + * (scan results); This includes id and
136 + * length fields. One IWEVGENIE may
137 + * contain more than one IE. Scan
138 + * results may contain one or more
139 + * IWEVGENIE events. */
140 +#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure
141 + * (struct iw_michaelmicfailure)
143 +#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request.
144 + * The data includes id and length
145 + * fields and may contain more than one
146 + * IE. This event is required in
147 + * Managed mode if the driver
148 + * generates its own WPA/RSN IE. This
149 + * should be sent just before
150 + * IWEVREGISTERED event for the
152 +#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association
153 + * Response. The data includes id and
154 + * length fields and may contain more
155 + * than one IE. This may be sent
156 + * between IWEVASSOCREQIE and
157 + * IWEVREGISTERED events for the
159 +#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN
160 + * pre-authentication
161 + * (struct iw_pmkid_cand) */
163 #define IWEVFIRST 0x8C00
166 #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
167 #define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
169 +/* Statistics flags (bitmask in updated) */
170 +#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */
171 +#define IW_QUAL_LEVEL_UPDATED 0x2
172 +#define IW_QUAL_NOISE_UPDATED 0x4
173 +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
174 +#define IW_QUAL_LEVEL_INVALID 0x20
175 +#define IW_QUAL_NOISE_INVALID 0x40
177 +/* Frequency flags */
178 +#define IW_FREQ_AUTO 0x00 /* Let the driver decides */
179 +#define IW_FREQ_FIXED 0x01 /* Force a specific value */
181 /* Maximum number of size of encoding token available
182 * they are listed in the range structure */
183 #define IW_MAX_ENCODING_SIZES 8
185 #define IW_TXPOW_TYPE 0x00FF /* Type of value */
186 #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
187 #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
188 +#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */
189 #define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
191 /* Retry limits and lifetime flags available */
192 @@ -412,12 +499,113 @@
193 #define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
194 #define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
195 #define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
196 +/* struct iw_scan_req scan_type */
197 +#define IW_SCAN_TYPE_ACTIVE 0
198 +#define IW_SCAN_TYPE_PASSIVE 1
199 /* Maximum size of returned data */
200 #define IW_SCAN_MAX_DATA 4096 /* In bytes */
202 /* Max number of char in custom event - use multiple of them if needed */
203 #define IW_CUSTOM_MAX 256 /* In bytes */
205 +/* Generic information element */
206 +#define IW_GENERIC_IE_MAX 1024
208 +/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
209 +#define IW_MLME_DEAUTH 0
210 +#define IW_MLME_DISASSOC 1
212 +/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
213 +#define IW_AUTH_INDEX 0x0FFF
214 +#define IW_AUTH_FLAGS 0xF000
215 +/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
216 + * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
217 + * parameter that is being set/get to; value will be read/written to
218 + * struct iw_param value field) */
219 +#define IW_AUTH_WPA_VERSION 0
220 +#define IW_AUTH_CIPHER_PAIRWISE 1
221 +#define IW_AUTH_CIPHER_GROUP 2
222 +#define IW_AUTH_KEY_MGMT 3
223 +#define IW_AUTH_TKIP_COUNTERMEASURES 4
224 +#define IW_AUTH_DROP_UNENCRYPTED 5
225 +#define IW_AUTH_80211_AUTH_ALG 6
226 +#define IW_AUTH_WPA_ENABLED 7
227 +#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
228 +#define IW_AUTH_ROAMING_CONTROL 9
229 +#define IW_AUTH_PRIVACY_INVOKED 10
231 +/* IW_AUTH_WPA_VERSION values (bit field) */
232 +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
233 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002
234 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
236 +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
237 +#define IW_AUTH_CIPHER_NONE 0x00000001
238 +#define IW_AUTH_CIPHER_WEP40 0x00000002
239 +#define IW_AUTH_CIPHER_TKIP 0x00000004
240 +#define IW_AUTH_CIPHER_CCMP 0x00000008
241 +#define IW_AUTH_CIPHER_WEP104 0x00000010
243 +/* IW_AUTH_KEY_MGMT values (bit field) */
244 +#define IW_AUTH_KEY_MGMT_802_1X 1
245 +#define IW_AUTH_KEY_MGMT_PSK 2
247 +/* IW_AUTH_80211_AUTH_ALG values (bit field) */
248 +#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
249 +#define IW_AUTH_ALG_SHARED_KEY 0x00000002
250 +#define IW_AUTH_ALG_LEAP 0x00000004
252 +/* IW_AUTH_ROAMING_CONTROL values */
253 +#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */
254 +#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming
257 +/* SIOCSIWENCODEEXT definitions */
258 +#define IW_ENCODE_SEQ_MAX_SIZE 8
259 +/* struct iw_encode_ext ->alg */
260 +#define IW_ENCODE_ALG_NONE 0
261 +#define IW_ENCODE_ALG_WEP 1
262 +#define IW_ENCODE_ALG_TKIP 2
263 +#define IW_ENCODE_ALG_CCMP 3
264 +/* struct iw_encode_ext ->ext_flags */
265 +#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
266 +#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
267 +#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
268 +#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
270 +/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
271 +#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */
272 +#define IW_MICFAILURE_GROUP 0x00000004
273 +#define IW_MICFAILURE_PAIRWISE 0x00000008
274 +#define IW_MICFAILURE_STAKEY 0x00000010
275 +#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported)
278 +/* Bit field values for enc_capa in struct iw_range */
279 +#define IW_ENC_CAPA_WPA 0x00000001
280 +#define IW_ENC_CAPA_WPA2 0x00000002
281 +#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
282 +#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
284 +/* Event capability macros - in (struct iw_range *)->event_capa
285 + * Because we have more than 32 possible events, we use an array of
286 + * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
287 +#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \
288 + (cmd - SIOCIWFIRSTPRIV + 0x60) : \
289 + (cmd - SIOCSIWCOMMIT))
290 +#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
291 +#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
292 +/* Event capability constants - event autogenerated by the kernel
293 + * This list is valid for most 802.11 devices, customise as needed... */
294 +#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \
295 + IW_EVENT_CAPA_MASK(0x8B06) | \
296 + IW_EVENT_CAPA_MASK(0x8B1A))
297 +#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
298 +/* "Easy" macro to set events in iw_range (less efficient) */
299 +#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
300 +#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
303 /****************************** TYPES ******************************/
305 /* --------------------------- SUBTYPES --------------------------- */
307 __s32 m; /* Mantissa */
308 __s16 e; /* Exponent */
309 __u8 i; /* List index (when in range struct) */
310 - __u8 pad; /* Unused - just for alignement */
311 + __u8 flags; /* Flags (fixed/auto) */
315 @@ -507,6 +695,132 @@
316 struct iw_quality high; /* High threshold */
320 + * Optional data for scan request
322 + * Note: these optional parameters are controlling parameters for the
323 + * scanning behavior, these do not apply to getting scan results
324 + * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and
325 + * provide a merged results with all BSSes even if the previous scan
326 + * request limited scanning to a subset, e.g., by specifying an SSID.
327 + * Especially, scan results are required to include an entry for the
328 + * current BSS if the driver is in Managed mode and associated with an AP.
332 + __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
334 + __u8 num_channels; /* num entries in channel_list;
335 + * 0 = scan all allowed channels */
336 + __u8 flags; /* reserved as padding; use zero, this may
337 + * be used in the future for adding flags
338 + * to request different scan behavior */
339 + struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
340 + * individual address of a specific BSS */
343 + * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
344 + * the current ESSID. This allows scan requests for specific ESSID
345 + * without having to change the current ESSID and potentially breaking
346 + * the current association.
348 + __u8 essid[IW_ESSID_MAX_SIZE];
351 + * Optional parameters for changing the default scanning behavior.
352 + * These are based on the MLME-SCAN.request from IEEE Std 802.11.
353 + * TU is 1.024 ms. If these are set to 0, driver is expected to use
354 + * reasonable default values. min_channel_time defines the time that
355 + * will be used to wait for the first reply on each channel. If no
356 + * replies are received, next channel will be scanned after this. If
357 + * replies are received, total time waited on the channel is defined by
358 + * max_channel_time.
360 + __u32 min_channel_time; /* in TU */
361 + __u32 max_channel_time; /* in TU */
363 + struct iw_freq channel_list[IW_MAX_FREQUENCIES];
366 +/* ------------------------- WPA SUPPORT ------------------------- */
369 + * Extended data structure for get/set encoding (this is used with
370 + * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
371 + * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
372 + * only the data contents changes (key data -> this structure, including
375 + * If the new key is the first group key, it will be set as the default
376 + * TX key. Otherwise, default TX key index is only changed if
377 + * IW_ENCODE_EXT_SET_TX_KEY flag is set.
379 + * Key will be changed with SIOCSIWENCODEEXT in all cases except for
380 + * special "change TX key index" operation which is indicated by setting
381 + * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
383 + * tx_seq/rx_seq are only used when respective
384 + * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
385 + * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
386 + * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
387 + * used only by an Authenticator (AP or an IBSS station) to get the
388 + * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
389 + * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
390 + * debugging/testing.
392 +struct iw_encode_ext
394 + __u32 ext_flags; /* IW_ENCODE_EXT_* */
395 + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
396 + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
397 + struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
398 + * (group) keys or unicast address for
399 + * individual keys */
400 + __u16 alg; /* IW_ENCODE_ALG_* */
405 +/* SIOCSIWMLME data */
408 + __u16 cmd; /* IW_MLME_* */
410 + struct sockaddr addr;
413 +/* SIOCSIWPMKSA data */
414 +#define IW_PMKSA_ADD 1
415 +#define IW_PMKSA_REMOVE 2
416 +#define IW_PMKSA_FLUSH 3
418 +#define IW_PMKID_LEN 16
422 + __u32 cmd; /* IW_PMKSA_* */
423 + struct sockaddr bssid;
424 + __u8 pmkid[IW_PMKID_LEN];
427 +/* IWEVMICHAELMICFAILURE data */
428 +struct iw_michaelmicfailure
431 + struct sockaddr src_addr;
432 + __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
435 +/* IWEVPMKIDCAND data */
436 +#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */
437 +struct iw_pmkid_cand
439 + __u32 flags; /* IW_PMKID_CAND_* */
440 + __u32 index; /* the smaller the index, the higher the
442 + struct sockaddr bssid;
445 /* ------------------------ WIRELESS STATS ------------------------ */
447 * Wireless statistics (used for /proc/net/wireless)
448 @@ -610,11 +924,12 @@
449 /* Old Frequency (backward compat - moved lower ) */
450 __u16 old_num_channels;
451 __u8 old_num_frequency;
452 - /* Filler to keep "version" at the same offset */
455 + /* Wireless event capability bitmasks */
456 + __u32 event_capa[6];
458 /* signal level threshold range */
462 /* Quality of link & SNR stuff */
463 /* Quality range (link, level, noise)
465 struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
466 /* Note : this frequency list doesn't need to fit channel numbers,
467 * because each entry contain its channel index */
469 + __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
473 diff -Nur linux-2.4.32/include/net/iw_handler.h linux-2.4.32-we/include/net/iw_handler.h
474 --- linux-2.4.32/include/net/iw_handler.h 2003-11-28 19:26:21.000000000 +0100
475 +++ linux-2.4.32-we/include/net/iw_handler.h 2006-03-13 12:10:57.000000000 +0100
478 * This file define the new driver API for Wireless Extensions
480 - * Version : 5 4.12.02
481 + * Version : 6 21.6.04
483 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
484 - * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
485 + * Copyright (c) 2001-2004 Jean Tourrilhes, All Rights Reserved.
488 #ifndef _IW_HANDLER_H
491 * I just plan to increment with each new version.
493 -#define IW_HANDLER_VERSION 5
494 +#define IW_HANDLER_VERSION 6
498 @@ -224,11 +224,18 @@
501 * - Add new spy support : struct iw_spy_data & prototypes
505 + * - Change the way we get to spy_data method for added safety
506 + * - Remove spy #ifdef, they are always on -> cleaner code
507 + * - Add IW_DESCR_FLAG_NOMAX flag for very large requests
508 + * - Start migrating get_wireless_stats to struct iw_handler_def
511 /**************************** CONSTANTS ****************************/
513 -/* Enable enhanced spy support. Disable to reduce footprint */
514 +/* Enhanced spy support available */
515 #define IW_WIRELESS_SPY
516 #define IW_WIRELESS_THRSPY
519 #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
520 #define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
521 /* SET : Omit payload from generated iwevent */
522 +#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */
523 /* Driver level flags */
524 #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
526 @@ -311,23 +319,25 @@
527 /* Array of handlers for standard ioctls
528 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
530 - iw_handler * standard;
531 + const iw_handler * standard;
533 /* Array of handlers for private ioctls
534 * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
536 - iw_handler * private;
537 + const iw_handler * private;
539 /* Arguments of private handler. This one is just a list, so you
540 * can put it in any order you want and should not leave holes...
541 * We will automatically export that to user space... */
542 - struct iw_priv_args * private_args;
543 + const struct iw_priv_args * private_args;
545 - /* Driver enhanced spy support */
546 - long spy_offset; /* Spy data offset */
547 + /* This field will be *removed* in the next version of WE */
548 + long spy_offset; /* DO NOT USE */
550 - /* In the long term, get_wireless_stats will move from
551 - * 'struct net_device' to here, to minimise bloat. */
552 + /* New location of get_wireless_stats, to de-bloat struct net_device.
553 + * The old pointer in struct net_device will be gradually phased
554 + * out, and drivers are encouraged to use this one... */
555 + struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
558 /* ---------------------- IOCTL DESCRIPTION ---------------------- */
559 @@ -374,18 +384,29 @@
563 -#ifdef IW_WIRELESS_SPY
564 /* --- Standard spy support --- */
566 u_char spy_address[IW_MAX_SPY][ETH_ALEN];
567 struct iw_quality spy_stat[IW_MAX_SPY];
568 -#ifdef IW_WIRELESS_THRSPY
569 /* --- Enhanced spy support (event) */
570 struct iw_quality spy_thr_low; /* Low threshold */
571 struct iw_quality spy_thr_high; /* High threshold */
572 u_char spy_thr_under[IW_MAX_SPY];
573 -#endif /* IW_WIRELESS_THRSPY */
574 -#endif /* IW_WIRELESS_SPY */
577 +/* --------------------- DEVICE WIRELESS DATA --------------------- */
579 + * This is all the wireless data specific to a device instance that
580 + * is managed by the core of Wireless Extensions.
581 + * We only keep pointer to those structures, so that a driver is free
582 + * to share them between instances.
583 + * This structure should be initialised before registering the device.
584 + * Access to this data follow the same rules as any other struct net_device
585 + * data (i.e. valid as long as struct net_device exist, same locking rules).
587 +struct iw_public_data {
588 + /* Driver enhanced spy support */
589 + struct iw_spy_data * spy_data;
592 /**************************** PROTOTYPES ****************************/
593 diff -Nur linux-2.4.32/net/core/dev.c linux-2.4.32-we/net/core/dev.c
594 --- linux-2.4.32/net/core/dev.c 2005-04-04 03:42:20.000000000 +0200
595 +++ linux-2.4.32-we/net/core/dev.c 2006-03-13 12:10:57.000000000 +0100
596 @@ -2426,7 +2426,7 @@
597 /* Follow me in net/core/wireless.c */
598 ret = wireless_process_ioctl(&ifr, cmd);
600 - if (!ret && IW_IS_GET(cmd) &&
601 + if (IW_IS_GET(cmd) &&
602 copy_to_user(arg, &ifr, sizeof(struct ifreq)))
605 diff -Nur linux-2.4.32/net/core/wireless.c linux-2.4.32-we/net/core/wireless.c
606 --- linux-2.4.32/net/core/wireless.c 2003-11-28 19:26:21.000000000 +0100
607 +++ linux-2.4.32-we/net/core/wireless.c 2006-03-13 12:11:02.000000000 +0100
609 * This file implement the Wireless Extensions APIs.
611 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
612 - * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved.
613 + * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
615 * (As all part of the Linux kernel, this file is GPL)
618 * o Add common spy support : iw_handler_set_spy(), wireless_spy_update()
619 * o Add enhanced spy support : iw_handler_set_thrspy() and event.
620 * o Add WIRELESS_EXT version display in /proc/net/wireless
622 + * v6 - 18.06.04 - Jean II
623 + * o Change get_spydata() method for added safety
624 + * o Remove spy #ifdef, they are always on -> cleaner code
625 + * o Allow any size GET request if user specifies length > max
626 + * and if request has IW_DESCR_FLAG_NOMAX flag or is SIOCGIWPRIV
627 + * o Start migrating get_wireless_stats to struct iw_handler_def
628 + * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
629 + * Based on patch from Pavel Roskin <proski@gnu.org> :
630 + * o Fix kernel data leak to user space in private handler handling
633 /***************************** INCLUDES *****************************/
636 /**************************** CONSTANTS ****************************/
638 -/* Enough lenience, let's make sure things are proper... */
639 -#define WE_STRICT_WRITE /* Check write buffer size */
640 -/* I'll probably drop both the define and kernel message in the next version */
642 -/* Debuging stuff */
643 +/* Debugging stuff */
644 #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
645 #undef WE_EVENT_DEBUG /* Debug Event dispatcher */
646 #undef WE_SPY_DEBUG /* Debug enhanced spy support */
647 @@ -131,14 +137,14 @@
648 { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
650 { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
652 - { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
654 + { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_mlme), sizeof(struct iw_mlme), 0},
656 - { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
657 + { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, IW_DESCR_FLAG_NOMAX},
659 - { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
660 + { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_scan_req), 0},
662 - { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0},
663 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, IW_DESCR_FLAG_NOMAX},
665 { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT},
668 { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
670 { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
672 + { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
674 + { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
676 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0},
678 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0},
680 + { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
682 + { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
683 + /* SIOCSIWENCODEEXT */
684 + { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_encode_ext), sizeof(struct iw_encode_ext) + IW_ENCODING_TOKEN_MAX, 0},
685 + /* SIOCGIWENCODEEXT */
686 + { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_encode_ext), sizeof(struct iw_encode_ext) + IW_ENCODING_TOKEN_MAX, 0},
688 + { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_pmksa), sizeof(struct iw_pmksa), 0},
691 static const int standard_ioctl_num = (sizeof(standard_ioctl) /
692 sizeof(struct iw_ioctl_description));
693 @@ -198,12 +223,22 @@
694 { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
696 { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
698 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0},
699 + /* IWEVMICHAELMICFAILURE */
700 + { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_michaelmicfailure), 0},
701 + /* IWEVASSOCREQIE */
702 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0},
703 + /* IWEVASSOCRESPIE */
704 + { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0},
705 + /* IWEVPMKIDCAND */
706 + { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_pmkid_cand), 0},
708 static const int standard_event_num = (sizeof(standard_event) /
709 sizeof(struct iw_ioctl_description));
711 /* Size (in bytes) of the various private data types */
712 -static const char priv_type_size[] = {
713 +static const char iw_priv_type_size[] = {
714 0, /* IW_PRIV_TYPE_NONE */
715 1, /* IW_PRIV_TYPE_BYTE */
716 1, /* IW_PRIV_TYPE_CHAR */
717 @@ -270,12 +305,15 @@
719 static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
722 + if((dev->wireless_handlers != NULL) &&
723 + (dev->wireless_handlers->get_wireless_stats != NULL))
724 + return dev->wireless_handlers->get_wireless_stats(dev);
726 + /* Old location, will be phased out in next WE */
727 return (dev->get_wireless_stats ?
728 dev->get_wireless_stats(dev) :
729 (struct iw_statistics *) NULL);
730 - /* In the future, get_wireless_stats may move from 'struct net_device'
731 - * to 'struct iw_handler_def', to de-bloat struct net_device.
732 - * Definitely worse a thought... */
735 /* ---------------------------------------------------------------- */
736 @@ -310,14 +348,32 @@
738 /* ---------------------------------------------------------------- */
740 - * Number of private arguments
741 + * Calculate size of private arguments
743 static inline int get_priv_size(__u16 args)
745 int num = args & IW_PRIV_SIZE_MASK;
746 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
748 - return num * priv_type_size[type];
749 + return num * iw_priv_type_size[type];
752 +/* ---------------------------------------------------------------- */
754 + * Re-calculate the size of private arguments
756 +static inline int adjust_priv_size(__u16 args,
757 + union iwreq_data * wrqu)
759 + int num = wrqu->data.length;
760 + int max = args & IW_PRIV_SIZE_MASK;
761 + int type = (args & IW_PRIV_TYPE_MASK) >> 12;
763 + /* Make sure the driver doesn't goof up */
767 + return num * iw_priv_type_size[type];
771 @@ -350,11 +406,14 @@
775 - stats->qual.updated & 1 ? '.' : ' ',
776 + stats->qual.updated & IW_QUAL_QUAL_UPDATED
778 ((__u8) stats->qual.level),
779 - stats->qual.updated & 2 ? '.' : ' ',
780 + stats->qual.updated & IW_QUAL_LEVEL_UPDATED
782 ((__u8) stats->qual.noise),
783 - stats->qual.updated & 4 ? '.' : ' ',
784 + stats->qual.updated & IW_QUAL_NOISE_UPDATED
788 stats->discard.fragment,
789 @@ -470,13 +529,15 @@
790 /* Check NULL pointer */
791 if(iwr->u.data.pointer == NULL)
793 -#ifdef WE_STRICT_WRITE
795 /* Check if there is enough buffer up there */
796 if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
797 - printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args);
798 + /* User space can't know in advance how large the buffer
799 + * needs to be. Give it a hint, so that we can support
800 + * any size buffer we want somewhat efficiently... */
801 + iwr->u.data.length = dev->wireless_handlers->num_private_args;
804 -#endif /* WE_STRICT_WRITE */
806 /* Set the number of available ioctls. */
807 iwr->u.data.length = dev->wireless_handlers->num_private_args;
809 const struct iw_ioctl_description * descr;
810 struct iw_request_info info;
814 /* Get the description of the IOCTL */
815 if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
817 #endif /* WE_SET_EVENT */
821 + int user_length = 0;
824 + /* Calculate space needed by arguments. Always allocate
825 + * for max space. Easier, and won't last long... */
826 + extra_size = descr->max_tokens * descr->token_size;
828 /* Check what user space is giving us */
830 /* Check NULL pointer */
831 @@ -554,18 +620,33 @@
832 if(iwr->u.data.pointer == NULL)
834 /* Save user space buffer size for checking */
835 - user_size = iwr->u.data.length;
836 + user_length = iwr->u.data.length;
838 + /* Don't check if user_length > max to allow forward
839 + * compatibility. The test user_length < min is
840 + * implied by the test at the end. */
842 + /* Support for very large requests */
843 + if((descr->flags & IW_DESCR_FLAG_NOMAX) &&
844 + (user_length > descr->max_tokens)) {
845 + /* Allow userspace to GET more than max so
846 + * we can support any size GET requests.
847 + * There is still a limit : -ENOMEM. */
848 + extra_size = user_length * descr->token_size;
849 + /* Note : user_length is originally a __u16,
850 + * and token_size is controlled by us,
851 + * so extra_size won't get negative and
852 + * won't overflow... */
856 #ifdef WE_IOCTL_DEBUG
857 printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
858 - dev->name, descr->max_tokens * descr->token_size);
859 + dev->name, extra_size);
860 #endif /* WE_IOCTL_DEBUG */
862 - /* Always allocate for max space. Easier, and won't last
864 - extra = kmalloc(descr->max_tokens * descr->token_size,
866 + /* Create the kernel buffer */
867 + extra = kmalloc(extra_size, GFP_KERNEL);
871 @@ -591,14 +672,11 @@
873 /* If we have something to return to the user */
874 if (!ret && IW_IS_GET(cmd)) {
875 -#ifdef WE_STRICT_WRITE
876 /* Check if there is enough buffer up there */
877 - if(user_size < iwr->u.data.length) {
878 - printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length);
879 + if(user_length < iwr->u.data.length) {
883 -#endif /* WE_STRICT_WRITE */
885 err = copy_to_user(iwr->u.data.pointer, extra,
890 struct iwreq * iwr = (struct iwreq *) ifr;
891 - struct iw_priv_args * descr = NULL;
892 + const struct iw_priv_args * descr = NULL;
893 struct iw_request_info info;
897 ((extra_size + offset) <= IFNAMSIZ))
900 - /* Size of set arguments */
901 + /* Size of get arguments */
902 extra_size = get_priv_size(descr->get_args);
904 /* Does it fits in iwr ? */
907 /* If we have something to return to the user */
908 if (!ret && IW_IS_GET(cmd)) {
910 + /* Adjust for the actual length if it's variable,
911 + * avoid leaking kernel bits outside. */
912 + if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) {
913 + extra_size = adjust_priv_size(descr->get_args,
917 err = copy_to_user(iwr->u.data.pointer, extra,
920 @@ -1042,9 +1128,25 @@
921 * One of the main advantage of centralising spy support here is that
922 * it becomes much easier to improve and extend it without having to touch
923 * the drivers. One example is the addition of the Spy-Threshold events.
924 - * Note : IW_WIRELESS_SPY is defined in iw_handler.h
927 +/* ---------------------------------------------------------------- */
929 + * Return the pointer to the spy data in the driver.
930 + * Because this is called on the Rx path via wireless_spy_update(),
931 + * we want it to be efficient...
933 +static inline struct iw_spy_data * get_spydata(struct net_device *dev)
935 + /* This is the new way */
936 + if(dev->wireless_data)
937 + return(dev->wireless_data->spy_data);
939 + /* This is the old way. Doesn't work for multi-headed drivers.
940 + * It will be removed in the next version of WE. */
941 + return (dev->priv + dev->wireless_handlers->spy_offset);
944 /*------------------------------------------------------------------*/
946 * Standard Wireless Handler : set Spy List
947 @@ -1054,16 +1156,26 @@
948 union iwreq_data * wrqu,
951 -#ifdef IW_WIRELESS_SPY
952 - struct iw_spy_data * spydata = (dev->priv +
953 - dev->wireless_handlers->spy_offset);
954 + struct iw_spy_data * spydata = get_spydata(dev);
955 struct sockaddr * address = (struct sockaddr *) extra;
957 + /* Make sure driver is not buggy or using the old API */
959 + return -EOPNOTSUPP;
961 /* Disable spy collection while we copy the addresses.
962 - * As we don't disable interrupts, we need to do this to avoid races.
963 - * As we are the only writer, this is good enough. */
964 + * While we copy addresses, any call to wireless_spy_update()
965 + * will NOP. This is OK, as anyway the addresses are changing. */
966 spydata->spy_number = 0;
968 + /* We want to operate without locking, because wireless_spy_update()
969 + * most likely will happen in the interrupt handler, and therefore
970 + * have its own locking constraints and needs performance.
971 + * The rtnl_lock() make sure we don't race with the other iw_handlers.
972 + * This make sure wireless_spy_update() "see" that the spy list
973 + * is temporarily disabled. */
976 /* Are there are addresses to copy? */
977 if(wrqu->data.length > 0) {
979 @@ -1089,13 +1201,14 @@
980 spydata->spy_address[i][5]);
981 #endif /* WE_SPY_DEBUG */
984 + /* Make sure above is updated before re-enabling */
987 /* Enable addresses */
988 spydata->spy_number = wrqu->data.length;
991 -#else /* IW_WIRELESS_SPY */
992 - return -EOPNOTSUPP;
993 -#endif /* IW_WIRELESS_SPY */
996 /*------------------------------------------------------------------*/
997 @@ -1107,12 +1220,14 @@
998 union iwreq_data * wrqu,
1001 -#ifdef IW_WIRELESS_SPY
1002 - struct iw_spy_data * spydata = (dev->priv +
1003 - dev->wireless_handlers->spy_offset);
1004 + struct iw_spy_data * spydata = get_spydata(dev);
1005 struct sockaddr * address = (struct sockaddr *) extra;
1008 + /* Make sure driver is not buggy or using the old API */
1010 + return -EOPNOTSUPP;
1012 wrqu->data.length = spydata->spy_number;
1014 /* Copy addresses. */
1015 @@ -1129,9 +1244,6 @@
1016 for(i = 0; i < spydata->spy_number; i++)
1017 spydata->spy_stat[i].updated = 0;
1019 -#else /* IW_WIRELESS_SPY */
1020 - return -EOPNOTSUPP;
1021 -#endif /* IW_WIRELESS_SPY */
1024 /*------------------------------------------------------------------*/
1025 @@ -1143,11 +1255,13 @@
1026 union iwreq_data * wrqu,
1029 -#ifdef IW_WIRELESS_THRSPY
1030 - struct iw_spy_data * spydata = (dev->priv +
1031 - dev->wireless_handlers->spy_offset);
1032 + struct iw_spy_data * spydata = get_spydata(dev);
1033 struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
1035 + /* Make sure driver is not buggy or using the old API */
1037 + return -EOPNOTSUPP;
1040 memcpy(&(spydata->spy_thr_low), &(threshold->low),
1041 2 * sizeof(struct iw_quality));
1042 @@ -1160,9 +1274,6 @@
1043 #endif /* WE_SPY_DEBUG */
1046 -#else /* IW_WIRELESS_THRSPY */
1047 - return -EOPNOTSUPP;
1048 -#endif /* IW_WIRELESS_THRSPY */
1051 /*------------------------------------------------------------------*/
1052 @@ -1174,22 +1285,20 @@
1053 union iwreq_data * wrqu,
1056 -#ifdef IW_WIRELESS_THRSPY
1057 - struct iw_spy_data * spydata = (dev->priv +
1058 - dev->wireless_handlers->spy_offset);
1059 + struct iw_spy_data * spydata = get_spydata(dev);
1060 struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
1062 + /* Make sure driver is not buggy or using the old API */
1064 + return -EOPNOTSUPP;
1067 memcpy(&(threshold->low), &(spydata->spy_thr_low),
1068 2 * sizeof(struct iw_quality));
1071 -#else /* IW_WIRELESS_THRSPY */
1072 - return -EOPNOTSUPP;
1073 -#endif /* IW_WIRELESS_THRSPY */
1076 -#ifdef IW_WIRELESS_THRSPY
1077 /*------------------------------------------------------------------*/
1079 * Prepare and send a Spy Threshold event
1080 @@ -1227,7 +1336,6 @@
1081 /* Send event to user space */
1082 wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
1084 -#endif /* IW_WIRELESS_THRSPY */
1086 /* ---------------------------------------------------------------- */
1088 @@ -1240,12 +1348,14 @@
1089 unsigned char * address,
1090 struct iw_quality * wstats)
1092 -#ifdef IW_WIRELESS_SPY
1093 - struct iw_spy_data * spydata = (dev->priv +
1094 - dev->wireless_handlers->spy_offset);
1095 + struct iw_spy_data * spydata = get_spydata(dev);
1099 + /* Make sure driver is not buggy or using the old API */
1104 printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
1105 #endif /* WE_SPY_DEBUG */
1106 @@ -1257,7 +1367,7 @@
1107 sizeof(struct iw_quality));
1110 -#ifdef IW_WIRELESS_THRSPY
1112 /* Generate an event if we cross the spy threshold.
1113 * To avoid event storms, we have a simple hysteresis : we generate
1114 * event only when we go under the low threshold or above the
1115 @@ -1277,6 +1387,4 @@
1119 -#endif /* IW_WIRELESS_THRSPY */
1120 -#endif /* IW_WIRELESS_SPY */