100-wireless-extension.patch 40 KB

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