100-wireless-extension.patch 40 KB

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