]> git.pld-linux.org Git - packages/kernel.git/blob - iw_handlers.w14-5.diff
- obsolete
[packages/kernel.git] / iw_handlers.w14-5.diff
1 diff -u -p -r --new-file linux/include/linux-w13/rtnetlink.h linux/include/linux/rtnetlink.h
2 --- linux/include/linux-w13/rtnetlink.h Thu Jun  6 14:44:08 2002
3 +++ linux/include/linux/rtnetlink.h     Thu Jun  6 15:47:44 2002
4 @@ -440,12 +440,14 @@ enum
5  #define IFLA_COST IFLA_COST
6         IFLA_PRIORITY,
7  #define IFLA_PRIORITY IFLA_PRIORITY
8 -       IFLA_MASTER
9 +       IFLA_MASTER,
10  #define IFLA_MASTER IFLA_MASTER
11 +       IFLA_WIRELESS,          /* Wireless Extension event - see wireless.h */
12 +#define IFLA_WIRELESS IFLA_WIRELESS
13  };
14  
15  
16 -#define IFLA_MAX IFLA_MASTER
17 +#define IFLA_MAX IFLA_WIRELESS
18  
19  #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
20  #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
21 diff -u -p -r --new-file linux/include/linux-w13/wireless.h linux/include/linux/wireless.h
22 --- linux/include/linux-w13/wireless.h  Thu Jun  6 15:00:28 2002
23 +++ linux/include/linux/wireless.h      Thu Jun  6 15:47:44 2002
24 @@ -1,10 +1,10 @@
25  /*
26   * This file define a set of standard wireless extensions
27   *
28 - * Version :   13      6.12.01
29 + * Version :   14      25.1.02
30   *
31   * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
32 - * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
33 + * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
34   */
35  
36  #ifndef _LINUX_WIRELESS_H
37 @@ -40,7 +40,7 @@
38   *     # include/linux/netdevice.h (one place)
39   *     # include/linux/proc_fs.h (one place)
40   *
41 - * New driver API (2001 -> onward) :
42 + * New driver API (2002 -> onward) :
43   * -------------------------------
44   * This file is only concerned with the user space API and common definitions.
45   * The new driver API is defined and documented in :
46 @@ -49,6 +49,11 @@
47   * Note as well that /proc/net/wireless implementation has now moved in :
48   *     # include/linux/wireless.c
49   *
50 + * Wireless Events (2002 -> onward) :
51 + * --------------------------------
52 + * Events are defined at the end of this file, and implemented in :
53 + *     # include/linux/wireless.c
54 + *
55   * Other comments :
56   * --------------
57   * Do not add here things that are redundant with other mechanisms
58 @@ -75,7 +80,7 @@
59   * (there is some stuff that will be added in the future...)
60   * I just plan to increment with each new version.
61   */
62 -#define WIRELESS_EXT   13
63 +#define WIRELESS_EXT   14
64  
65  /*
66   * Changes :
67 @@ -141,6 +146,13 @@
68   *     - Document creation of new driver API.
69   *     - Extract union iwreq_data from struct iwreq (for new driver API).
70   *     - Rename SIOCSIWNAME as SIOCSIWCOMMIT
71 + *
72 + * V13 to V14
73 + * ----------
74 + *     - Wireless Events support : define struct iw_event
75 + *     - Define additional specific event numbers
76 + *     - Add "addr" and "param" fields in union iwreq_data
77 + *     - AP scanning stuff (SIOCSIWSCAN and friends)
78   */
79  
80  /**************************** CONSTANTS ****************************/
81 @@ -175,6 +187,8 @@
82  #define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
83  #define SIOCGIWAP      0x8B15          /* get access point MAC addresses */
84  #define SIOCGIWAPLIST  0x8B17          /* get list of access point in range */
85 +#define SIOCSIWSCAN    0x8B18          /* trigger scanning */
86 +#define SIOCGIWSCAN    0x8B19          /* get scanning results */
87  
88  /* 802.11 specific support */
89  #define SIOCSIWESSID   0x8B1A          /* set ESSID (network name) */
90 @@ -238,6 +252,15 @@
91  #define IW_IS_SET(cmd) (!((cmd) & 0x1))
92  #define IW_IS_GET(cmd) ((cmd) & 0x1)
93  
94 +/* ----------------------- WIRELESS EVENTS ----------------------- */
95 +/* Those are *NOT* ioctls, do not issue request on them !!! */
96 +/* Most events use the same identifier as ioctl requests */
97 +
98 +#define IWEVTXDROP     0x8C00          /* Packet dropped to excessive retry */
99 +#define IWEVQUAL       0x8C01          /* Quality part of statistics */
100 +
101 +#define IWEVFIRST      0x8C00
102 +
103  /* ------------------------- PRIVATE INFO ------------------------- */
104  /*
105   * The following is used with SIOCGIWPRIV. It allow a driver to define
106 @@ -340,6 +363,19 @@
107  #define IW_RETRY_MAX           0x0002  /* Value is a maximum */
108  #define IW_RETRY_RELATIVE      0x0004  /* Value is not in seconds/ms/us */
109  
110 +/* Scanning request flags */
111 +#define IW_SCAN_DEFAULT                0x0000  /* Default scan of the driver */
112 +#define IW_SCAN_ALL_ESSID      0x0001  /* Scan all ESSIDs */
113 +#define IW_SCAN_THIS_ESSID     0x0002  /* Scan only this ESSID */
114 +#define IW_SCAN_ALL_FREQ       0x0004  /* Scan all Frequencies */
115 +#define IW_SCAN_THIS_FREQ      0x0008  /* Scan only this Frequency */
116 +#define IW_SCAN_ALL_MODE       0x0010  /* Scan all Modes */
117 +#define IW_SCAN_THIS_MODE      0x0020  /* Scan only this Mode */
118 +#define IW_SCAN_ALL_RATE       0x0040  /* Scan all Bit-Rates */
119 +#define IW_SCAN_THIS_RATE      0x0080  /* Scan only this Bit-Rate */
120 +/* Maximum size of returned data */
121 +#define IW_SCAN_MAX_DATA       4096    /* In bytes */
122 +
123  /****************************** TYPES ******************************/
124  
125  /* --------------------------- SUBTYPES --------------------------- */
126 @@ -466,9 +502,12 @@ union      iwreq_data
127  
128         struct iw_point encoding;       /* Encoding stuff : tokens */
129         struct iw_param power;          /* PM duration/timeout */
130 +       struct iw_quality qual;         /* Quality part of statistics */
131  
132         struct sockaddr ap_addr;        /* Access point address */
133 +       struct sockaddr addr;           /* Destination address (hw) */
134  
135 +       struct iw_param param;          /* Other small parameters */
136         struct iw_point data;           /* Other large parameters */
137  };
138  
139 @@ -595,5 +634,36 @@ struct     iw_priv_args
140         __u16           get_args;       /* Type and number of args */
141         char            name[IFNAMSIZ]; /* Name of the extension */
142  };
143 +
144 +/* ----------------------- WIRELESS EVENTS ----------------------- */
145 +/*
146 + * Wireless events are carried through the rtnetlink socket to user
147 + * space. They are encapsulated in the IFLA_WIRELESS field of
148 + * a RTM_NEWLINK message.
149 + */
150 +
151 +/*
152 + * A Wireless Event. Contains basically the same data as the ioctl...
153 + */
154 +struct iw_event
155 +{
156 +       __u16           len;                    /* Real lenght of this stuff */
157 +       __u16           cmd;                    /* Wireless IOCTL */
158 +       union iwreq_data        u;              /* IOCTL fixed payload */
159 +};
160 +
161 +/* Size of the Event prefix (including padding and alignement junk) */
162 +#define IW_EV_LCP_LEN  (sizeof(struct iw_event) - sizeof(union iwreq_data))
163 +/* Size of the various events */
164 +#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
165 +#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
166 +#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
167 +#define IW_EV_POINT_LEN        (IW_EV_LCP_LEN + sizeof(struct iw_point))
168 +#define IW_EV_PARAM_LEN        (IW_EV_LCP_LEN + sizeof(struct iw_param))
169 +#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
170 +#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
171 +
172 +/* Note : in the case of iw_point, the extra data will come at the
173 + * end of the event */
174  
175  #endif /* _LINUX_WIRELESS_H */
176 diff -u -p -r --new-file linux/include/net-w13/iw_handler.h linux/include/net/iw_handler.h
177 --- linux/include/net-w13/iw_handler.h  Thu Jun  6 15:06:16 2002
178 +++ linux/include/net/iw_handler.h      Thu Jun  6 15:48:06 2002
179 @@ -1,10 +1,10 @@
180  /*
181   * This file define the new driver API for Wireless Extensions
182   *
183 - * Version :   2       6.12.01
184 + * Version :   3       17.1.02
185   *
186   * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
187 - * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
188 + * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
189   */
190  
191  #ifndef _IW_HANDLER_H
192 @@ -33,7 +33,7 @@
193   *     o The user space interface is tied to ioctl because of the use
194   *       copy_to/from_user.
195   *
196 - * New driver API (2001 -> onward) :
197 + * New driver API (2002 -> onward) :
198   * -------------------------------
199   * The new driver API is just a bunch of standard functions (handlers),
200   * each handling a specific Wireless Extension. The driver just export
201 @@ -206,7 +206,18 @@
202   * will be needed...
203   * I just plan to increment with each new version.
204   */
205 -#define IW_HANDLER_VERSION     2
206 +#define IW_HANDLER_VERSION     3
207 +
208 +/*
209 + * Changes :
210 + *
211 + * V2 to V3
212 + * --------
213 + *     - Move event definition in <linux/wireless.h>
214 + *     - Add Wireless Event support :
215 + *             o wireless_send_event() prototype
216 + *             o iwe_stream_add_event/point() inline functions
217 + */
218  
219  /**************************** CONSTANTS ****************************/
220  
221 @@ -225,6 +236,7 @@
222  #define IW_HEADER_TYPE_POINT   6       /* struct iw_point */
223  #define IW_HEADER_TYPE_PARAM   7       /* struct iw_param */
224  #define IW_HEADER_TYPE_ADDR    8       /* struct sockaddr */
225 +#define IW_HEADER_TYPE_QUAL    9       /* struct iw_quality */
226  
227  /* Handling flags */
228  /* Most are not implemented. I just use them as a reminder of some
229 @@ -233,7 +245,8 @@
230  /* Wrapper level flags */
231  #define IW_DESCR_FLAG_DUMP     0x0001  /* Not part of the dump command */
232  #define IW_DESCR_FLAG_EVENT    0x0002  /* Generate an event on SET */
233 -#define IW_DESCR_FLAG_RESTRICT 0x0004  /* GET request is ROOT only */
234 +#define IW_DESCR_FLAG_RESTRICT 0x0004  /* GET : request is ROOT only */
235 +                               /* SET : Omit payload from generated iwevent */
236  /* Driver level flags */
237  #define IW_DESCR_FLAG_WAIT     0x0100  /* Wait for driver event */
238  
239 @@ -303,25 +316,6 @@ struct iw_handler_def
240          * 'struct net_device' to here, to minimise bloat. */
241  };
242  
243 -/* ----------------------- WIRELESS EVENTS ----------------------- */
244 -/*
245 - * Currently we don't support events, so let's just plan for the
246 - * future...
247 - */
248 -
249 -/*
250 - * A Wireless Event.
251 - */
252 -// How do we define short header ? We don't want a flag on length.
253 -// Probably a flag on event ? Highest bit to zero...
254 -struct iw_event
255 -{
256 -       __u16           length;                 /* Lenght of this stuff */
257 -       __u16           event;                  /* Wireless IOCTL */
258 -       union   iwreq_data      header;         /* IOCTL fixed payload */
259 -       char            extra[0];               /* Optional IOCTL data */
260 -};
261 -
262  /* ---------------------- IOCTL DESCRIPTION ---------------------- */
263  /*
264   * One of the main goal of the new interface is to deal entirely with
265 @@ -369,6 +363,88 @@ extern int dev_get_wireless_info(char * 
266  extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
267  
268  /* Second : functions that may be called by driver modules */
269 -/* None yet */
270  
271 -#endif /* _LINUX_WIRELESS_H */
272 +/* Send a single event to user space */
273 +extern void wireless_send_event(struct net_device *    dev,
274 +                               unsigned int            cmd,
275 +                               union iwreq_data *      wrqu,
276 +                               char *                  extra);
277 +
278 +/* We may need a function to send a stream of events to user space.
279 + * More on that later... */
280 +
281 +/************************* INLINE FUNTIONS *************************/
282 +/*
283 + * Function that are so simple that it's more efficient inlining them
284 + */
285 +
286 +/*------------------------------------------------------------------*/
287 +/*
288 + * Wrapper to add an Wireless Event to a stream of events.
289 + */
290 +static inline char *
291 +iwe_stream_add_event(char *    stream,         /* Stream of events */
292 +                    char *     ends,           /* End of stream */
293 +                    struct iw_event *iwe,      /* Payload */
294 +                    int        event_len)      /* Real size of payload */
295 +{
296 +       /* Check if it's possible */
297 +       if((stream + event_len) < ends) {
298 +               iwe->len = event_len;
299 +               memcpy(stream, (char *) iwe, event_len);
300 +               stream += event_len;
301 +       }
302 +       return stream;
303 +}
304 +
305 +/*------------------------------------------------------------------*/
306 +/*
307 + * Wrapper to add an short Wireless Event containing a pointer to a
308 + * stream of events.
309 + */
310 +static inline char *
311 +iwe_stream_add_point(char *    stream,         /* Stream of events */
312 +                    char *     ends,           /* End of stream */
313 +                    struct iw_event *iwe,      /* Payload */
314 +                    char *     extra)
315 +{
316 +       int     event_len = IW_EV_POINT_LEN + iwe->u.data.length;
317 +       /* Check if it's possible */
318 +       if((stream + event_len) < ends) {
319 +               iwe->len = event_len;
320 +               memcpy(stream, (char *) iwe, IW_EV_POINT_LEN);
321 +               memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
322 +               stream += event_len;
323 +       }
324 +       return stream;
325 +}
326 +
327 +/*------------------------------------------------------------------*/
328 +/*
329 + * Wrapper to add a value to a Wireless Event in a stream of events.
330 + * Be careful, this one is tricky to use properly :
331 + * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
332 + */
333 +static inline char *
334 +iwe_stream_add_value(char *    event,          /* Event in the stream */
335 +                    char *     value,          /* Value in event */
336 +                    char *     ends,           /* End of stream */
337 +                    struct iw_event *iwe,      /* Payload */
338 +                    int        event_len)      /* Real size of payload */
339 +{
340 +       /* Don't duplicate LCP */
341 +       event_len -= IW_EV_LCP_LEN;
342 +
343 +       /* Check if it's possible */
344 +       if((value + event_len) < ends) {
345 +               /* Add new value */
346 +               memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
347 +               value += event_len;
348 +               /* Patch LCP */
349 +               iwe->len = value - event;
350 +               memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
351 +       }
352 +       return value;
353 +}
354 +
355 +#endif /* _IW_HANDLER_H */
356 diff -u -p -r --new-file linux/net/netsyms-w13.c linux/net/netsyms.c
357 --- linux/net/netsyms-w13.c     Thu Jun  6 15:46:34 2002
358 +++ linux/net/netsyms.c Thu Jun  6 15:47:44 2002
359 @@ -588,4 +588,10 @@ EXPORT_SYMBOL(register_gifconf);
360  EXPORT_SYMBOL(net_call_rx_atomic);
361  EXPORT_SYMBOL(softnet_data);
362  
363 +#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
364 +/* Don't include the whole header mess for a single function */
365 +extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
366 +EXPORT_SYMBOL(wireless_send_event);
367 +#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
368 +
369  #endif  /* CONFIG_NET */
370 diff -u -p -r --new-file linux/net/core/wireless-w13.c linux/net/core/wireless.c
371 --- linux/net/core/wireless-w13.c       Thu Jun  6 15:46:45 2002
372 +++ linux/net/core/wireless.c   Thu Jun  6 15:48:06 2002
373 @@ -2,7 +2,7 @@
374   * This file implement the Wireless Extensions APIs.
375   *
376   * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
377 - * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
378 + * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
379   *
380   * (As all part of the Linux kernel, this file is GPL)
381   */
382 @@ -25,6 +25,16 @@
383   *     o Added iw_handler handling ;-)
384   *     o Added standard ioctl description
385   *     o Initial dumb commit strategy based on orinoco.c
386 + *
387 + * v3 - 19.12.01 - Jean II
388 + *     o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
389 + *     o Add event dispatcher function
390 + *     o Add event description
391 + *     o Propagate events as rtnetlink IFLA_WIRELESS option
392 + *     o Generate event on selected SET requests
393 + *
394 + * v4 - 18.04.01 - Jean II
395 + *     o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
396   */
397  
398  /***************************** INCLUDES *****************************/
399 @@ -33,6 +43,7 @@
400  #include <linux/config.h>              /* Not needed ??? */
401  #include <linux/types.h>               /* off_t */
402  #include <linux/netdevice.h>           /* struct ifreq, dev_get_by_name() */
403 +#include <linux/rtnetlink.h>           /* rtnetlink stuff */
404  
405  #include <linux/wireless.h>            /* Pretty obvious */
406  #include <net/iw_handler.h>            /* New driver API */
407 @@ -44,14 +55,23 @@
408  
409  /* Debuging stuff */
410  #undef WE_IOCTL_DEBUG          /* Debug IOCTL API */
411 +#undef WE_EVENT_DEBUG          /* Debug Event dispatcher */
412 +
413 +/* Options */
414 +#define WE_EVENT_NETLINK       /* Propagate events using rtnetlink */
415 +#define WE_SET_EVENT           /* Generate an event on some set commands */
416  
417  /************************* GLOBAL VARIABLES *************************/
418  /*
419   * You should not use global variables, because or re-entrancy.
420   * On our case, it's only const, so it's OK...
421   */
422 +/*
423 + * Meta-data about all the standard Wireless Extension request we
424 + * know about.
425 + */
426  static const struct iw_ioctl_description       standard_ioctl[] = {
427 -       /* SIOCSIWCOMMIT (internal) */
428 +       /* SIOCSIWCOMMIT */
429         { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
430         /* SIOCGIWNAME */
431         { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
432 @@ -99,18 +119,18 @@ static const struct iw_ioctl_description
433         { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
434         /* SIOCGIWAPLIST */
435         { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
436 -       /* -- hole -- */
437 -       { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
438 -       /* -- hole -- */
439 -       { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
440 +       /* SIOCSIWSCAN */
441 +       { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
442 +       /* SIOCGIWSCAN */
443 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0},
444         /* SIOCSIWESSID */
445 -       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
446 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT},
447         /* SIOCGIWESSID */
448 -       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
449 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_DUMP},
450         /* SIOCSIWNICKN */
451 -       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
452 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
453         /* SIOCGIWNICKN */
454 -       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
455 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
456         /* -- hole -- */
457         { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
458         /* -- hole -- */
459 @@ -136,7 +156,7 @@ static const struct iw_ioctl_description
460         /* SIOCGIWRETRY */
461         { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
462         /* SIOCSIWENCODE */
463 -       { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
464 +       { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
465         /* SIOCGIWENCODE */
466         { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
467         /* SIOCSIWPOWER */
468 @@ -144,9 +164,38 @@ static const struct iw_ioctl_description
469         /* SIOCGIWPOWER */
470         { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
471  };
472 +static const int standard_ioctl_num = (sizeof(standard_ioctl) /
473 +                                      sizeof(struct iw_ioctl_description));
474 +
475 +/*
476 + * Meta-data about all the additional standard Wireless Extension events
477 + * we know about.
478 + */
479 +static const struct iw_ioctl_description       standard_event[] = {
480 +       /* IWEVTXDROP */
481 +       { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
482 +       /* IWEVQUAL */
483 +       { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
484 +};
485 +static const int standard_event_num = (sizeof(standard_event) /
486 +                                      sizeof(struct iw_ioctl_description));
487  
488  /* Size (in bytes) of the various private data types */
489 -char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
490 +static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
491 +
492 +/* Size (in bytes) of various events */
493 +static const int event_type_size[] = {
494 +       IW_EV_LCP_LEN,
495 +       0,
496 +       IW_EV_CHAR_LEN,
497 +       0,
498 +       IW_EV_UINT_LEN,
499 +       IW_EV_FREQ_LEN,
500 +       IW_EV_POINT_LEN,                /* Without variable payload */
501 +       IW_EV_PARAM_LEN,
502 +       IW_EV_ADDR_LEN,
503 +       IW_EV_QUAL_LEN,
504 +};
505  
506  /************************ COMMON SUBROUTINES ************************/
507  /*
508 @@ -162,7 +211,8 @@ char priv_type_size[] = { 0, 1, 1, 0, 4,
509  static inline iw_handler get_handler(struct net_device *dev,
510                                      unsigned int cmd)
511  {
512 -       unsigned int    index;          /* MUST be unsigned */
513 +       /* Don't "optimise" the following variable, it will crash */
514 +       unsigned int    index;          /* *MUST* be unsigned */
515  
516         /* Check if we have some wireless handlers defined */
517         if(dev->wireless_handlers == NULL)
518 @@ -269,9 +319,9 @@ static inline int sprintf_wireless_stats
519                                stats->status,
520                                stats->qual.qual,
521                                stats->qual.updated & 1 ? '.' : ' ',
522 -                              stats->qual.level,
523 +                              ((__u8) stats->qual.level),
524                                stats->qual.updated & 2 ? '.' : ' ',
525 -                              stats->qual.noise,
526 +                              ((__u8) stats->qual.noise),
527                                stats->qual.updated & 4 ? '.' : ' ',
528                                stats->discard.nwid,
529                                stats->discard.code,
530 @@ -423,12 +473,14 @@ static inline int ioctl_standard_call(st
531         int                                     ret = -EINVAL;
532  
533         /* Get the description of the IOCTL */
534 +       if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
535 +               return -EOPNOTSUPP;
536         descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
537  
538  #ifdef WE_IOCTL_DEBUG
539 -       printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
540 +       printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
541                ifr->ifr_name, cmd);
542 -       printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
543 +       printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
544  #endif /* WE_IOCTL_DEBUG */
545  
546         /* Prepare the call */
547 @@ -437,8 +489,16 @@ static inline int ioctl_standard_call(st
548  
549         /* Check if we have a pointer to user space data or not */
550         if(descr->header_type != IW_HEADER_TYPE_POINT) {
551 +
552                 /* No extra arguments. Trivial to handle */
553                 ret = handler(dev, &info, &(iwr->u), NULL);
554 +
555 +#ifdef WE_SET_EVENT
556 +               /* Generate an event to notify listeners of the change */
557 +               if((descr->flags & IW_DESCR_FLAG_EVENT) &&
558 +                  ((ret == 0) || (ret == -EIWCOMMIT)))
559 +                       wireless_send_event(dev, cmd, &(iwr->u), NULL);
560 +#endif /* WE_SET_EVENT */
561         } else {
562                 char *  extra;
563                 int     err;
564 @@ -466,8 +526,8 @@ static inline int ioctl_standard_call(st
565                 }
566  
567  #ifdef WE_IOCTL_DEBUG
568 -               printk(KERN_DEBUG "Malloc %d bytes\n",
569 -                      descr->max_tokens * descr->token_size);
570 +               printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
571 +                      dev->name, descr->max_tokens * descr->token_size);
572  #endif /* WE_IOCTL_DEBUG */
573  
574                 /* Always allocate for max space. Easier, and won't last
575 @@ -488,7 +548,8 @@ static inline int ioctl_standard_call(st
576                                 return -EFAULT;
577                         }
578  #ifdef WE_IOCTL_DEBUG
579 -                       printk(KERN_DEBUG "Got %d bytes\n",
580 +                       printk(KERN_DEBUG "%s (WE) : Got %d bytes\n",
581 +                              dev->name,
582                                iwr->u.data.length * descr->token_size);
583  #endif /* WE_IOCTL_DEBUG */
584                 }
585 @@ -504,11 +565,26 @@ static inline int ioctl_standard_call(st
586                         if (err)
587                                 ret =  -EFAULT;                            
588  #ifdef WE_IOCTL_DEBUG
589 -                       printk(KERN_DEBUG "Wrote %d bytes\n",
590 +                       printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n",
591 +                              dev->name,
592                                iwr->u.data.length * descr->token_size);
593  #endif /* WE_IOCTL_DEBUG */
594                 }
595  
596 +#ifdef WE_SET_EVENT
597 +               /* Generate an event to notify listeners of the change */
598 +               if((descr->flags & IW_DESCR_FLAG_EVENT) &&
599 +                  ((ret == 0) || (ret == -EIWCOMMIT))) {
600 +                       if(descr->flags & IW_DESCR_FLAG_RESTRICT)
601 +                               /* If the event is restricted, don't
602 +                                * export the payload */
603 +                               wireless_send_event(dev, cmd, &(iwr->u), NULL);
604 +                       else
605 +                               wireless_send_event(dev, cmd, &(iwr->u),
606 +                                                   extra);
607 +               }
608 +#endif /* WE_SET_EVENT */
609 +
610                 /* Cleanup - I told you it wasn't that long ;-) */
611                 kfree(extra);
612         }
613 @@ -558,11 +634,12 @@ static inline int ioctl_private_call(str
614                 }
615  
616  #ifdef WE_IOCTL_DEBUG
617 -       printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
618 +       printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n",
619                ifr->ifr_name, cmd);
620         if(descr) {
621 -               printk(KERN_DEBUG "Name %s, set %X, get %X\n",
622 -                      descr->name, descr->set_args, descr->get_args);
623 +               printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n",
624 +                      dev->name, descr->name,
625 +                      descr->set_args, descr->get_args);
626         }
627  #endif /* WE_IOCTL_DEBUG */
628  
629 @@ -617,7 +694,8 @@ static inline int ioctl_private_call(str
630                 }
631  
632  #ifdef WE_IOCTL_DEBUG
633 -               printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
634 +               printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
635 +                      dev->name, extra_size);
636  #endif /* WE_IOCTL_DEBUG */
637  
638                 /* Always allocate for max space. Easier, and won't last
639 @@ -636,7 +714,8 @@ static inline int ioctl_private_call(str
640                                 return -EFAULT;
641                         }
642  #ifdef WE_IOCTL_DEBUG
643 -                       printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
644 +                       printk(KERN_DEBUG "%s (WE) : Got %d elem\n",
645 +                              dev->name, iwr->u.data.length);
646  #endif /* WE_IOCTL_DEBUG */
647                 }
648  
649 @@ -650,8 +729,8 @@ static inline int ioctl_private_call(str
650                         if (err)
651                                 ret =  -EFAULT;                            
652  #ifdef WE_IOCTL_DEBUG
653 -                       printk(KERN_DEBUG "Wrote %d elem\n",
654 -                              iwr->u.data.length);
655 +                       printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n",
656 +                              dev->name, iwr->u.data.length);
657  #endif /* WE_IOCTL_DEBUG */
658                 }
659  
660 @@ -730,4 +809,178 @@ int wireless_process_ioctl(struct ifreq 
661         }
662         /* Not reached */
663         return -EINVAL;
664 +}
665 +
666 +/************************* EVENT PROCESSING *************************/
667 +/*
668 + * Process events generated by the wireless layer or the driver.
669 + * Most often, the event will be propagated through rtnetlink
670 + */
671 +
672 +#ifdef WE_EVENT_NETLINK
673 +/* "rtnl" is defined in net/core/rtnetlink.c, but we need it here.
674 + * It is declared in <linux/rtnetlink.h> */
675 +
676 +/* ---------------------------------------------------------------- */
677 +/*
678 + * Fill a rtnetlink message with our event data.
679 + * Note that we propage only the specified event and don't dump the
680 + * current wireless config. Dumping the wireless config is far too
681 + * expensive (for each parameter, the driver need to query the hardware).
682 + */
683 +static inline int rtnetlink_fill_iwinfo(struct sk_buff *       skb,
684 +                                       struct net_device *     dev,
685 +                                       int                     type,
686 +                                       char *                  event,
687 +                                       int                     event_len)
688 +{
689 +       struct ifinfomsg *r;
690 +       struct nlmsghdr  *nlh;
691 +       unsigned char    *b = skb->tail;
692 +
693 +       nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
694 +       r = NLMSG_DATA(nlh);
695 +       r->ifi_family = AF_UNSPEC;
696 +       r->ifi_type = dev->type;
697 +       r->ifi_index = dev->ifindex;
698 +       r->ifi_flags = dev->flags;
699 +       r->ifi_change = 0;      /* Wireless changes don't affect those flags */
700 +
701 +       /* Add the wireless events in the netlink packet */
702 +       RTA_PUT(skb, IFLA_WIRELESS,
703 +               event_len, event);
704 +
705 +       nlh->nlmsg_len = skb->tail - b;
706 +       return skb->len;
707 +
708 +nlmsg_failure:
709 +rtattr_failure:
710 +       skb_trim(skb, b - skb->data);
711 +       return -1;
712 +}
713 +
714 +/* ---------------------------------------------------------------- */
715 +/*
716 + * Create and broadcast and send it on the standard rtnetlink socket
717 + * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c
718 + * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field
719 + * within a RTM_NEWLINK event.
720 + */
721 +static inline void rtmsg_iwinfo(struct net_device *    dev,
722 +                               char *                  event,
723 +                               int                     event_len)
724 +{
725 +       struct sk_buff *skb;
726 +       int size = NLMSG_GOODSIZE;
727 +
728 +       skb = alloc_skb(size, GFP_ATOMIC);
729 +       if (!skb)
730 +               return;
731 +
732 +       if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK,
733 +                                 event, event_len) < 0) {
734 +               kfree_skb(skb);
735 +               return;
736 +       }
737 +       NETLINK_CB(skb).dst_groups = RTMGRP_LINK;
738 +       netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC);
739 +}
740 +#endif /* WE_EVENT_NETLINK */
741 +
742 +/* ---------------------------------------------------------------- */
743 +/*
744 + * Main event dispatcher. Called from other parts and drivers.
745 + * Send the event on the apropriate channels.
746 + * May be called from interrupt context.
747 + */
748 +void wireless_send_event(struct net_device *   dev,
749 +                        unsigned int           cmd,
750 +                        union iwreq_data *     wrqu,
751 +                        char *                 extra)
752 +{
753 +       const struct iw_ioctl_description *     descr = NULL;
754 +       int extra_len = 0;
755 +       struct iw_event  *event;                /* Mallocated whole event */
756 +       int event_len;                          /* Its size */
757 +       int hdr_len;                            /* Size of the event header */
758 +       /* Don't "optimise" the following variable, it will crash */
759 +       unsigned        cmd_index;              /* *MUST* be unsigned */
760 +
761 +       /* Get the description of the IOCTL */
762 +       if(cmd <= SIOCIWLAST) {
763 +               cmd_index = cmd - SIOCIWFIRST;
764 +               if(cmd_index < standard_ioctl_num)
765 +                       descr = &(standard_ioctl[cmd_index]);
766 +       } else {
767 +               cmd_index = cmd - IWEVFIRST;
768 +               if(cmd_index < standard_event_num)
769 +                       descr = &(standard_event[cmd_index]);
770 +       }
771 +       /* Don't accept unknown events */
772 +       if(descr == NULL) {
773 +               /* Note : we don't return an error to the driver, because
774 +                * the driver would not know what to do about it. It can't
775 +                * return an error to the user, because the event is not
776 +                * initiated by a user request.
777 +                * The best the driver could do is to log an error message.
778 +                * We will do it ourselves instead...
779 +                */
780 +               printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
781 +                      dev->name, cmd);
782 +               return;
783 +       }
784 +#ifdef WE_EVENT_DEBUG
785 +       printk(KERN_DEBUG "%s (WE) : Got event 0x%04X\n",
786 +              dev->name, cmd);
787 +       printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
788 +#endif /* WE_EVENT_DEBUG */
789 +
790 +       /* Check extra parameters and set extra_len */
791 +       if(descr->header_type == IW_HEADER_TYPE_POINT) {
792 +               /* Check if number of token fits within bounds */
793 +               if(wrqu->data.length > descr->max_tokens) {
794 +                       printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length);
795 +                       return;
796 +               }
797 +               if(wrqu->data.length < descr->min_tokens) {
798 +                       printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length);
799 +                       return;
800 +               }
801 +               /* Calculate extra_len - extra is NULL for restricted events */
802 +               if(extra != NULL)
803 +                       extra_len = wrqu->data.length * descr->token_size;
804 +#ifdef WE_EVENT_DEBUG
805 +               printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
806 +#endif /* WE_EVENT_DEBUG */
807 +       }
808 +
809 +       /* Total length of the event */
810 +       hdr_len = event_type_size[descr->header_type];
811 +       event_len = hdr_len + extra_len;
812 +
813 +#ifdef WE_EVENT_DEBUG
814 +       printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len);
815 +#endif /* WE_EVENT_DEBUG */
816 +
817 +       /* Create temporary buffer to hold the event */
818 +       event = kmalloc(event_len, GFP_ATOMIC);
819 +       if(event == NULL)
820 +               return;
821 +
822 +       /* Fill event */
823 +       event->len = event_len;
824 +       event->cmd = cmd;
825 +       memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN);
826 +       if(extra != NULL)
827 +               memcpy(((char *) event) + hdr_len, extra, extra_len);
828 +
829 +#ifdef WE_EVENT_NETLINK
830 +       /* rtnetlink event channel */
831 +       rtmsg_iwinfo(dev, (char *) event, event_len);
832 +#endif /* WE_EVENT_NETLINK */
833 +
834 +       /* Cleanup */
835 +       kfree(event);
836 +
837 +       return;         /* Always success, I guess ;-) */
838  }
This page took 0.093854 seconds and 3 git commands to generate.