~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/wireless/wext-spy.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /net/wireless/wext-spy.c (Version linux-6.12-rc7) and /net/wireless/wext-spy.c (Version linux-4.15.18)


  1 /*                                                  1 /*
  2  * This file implement the Wireless Extensions      2  * This file implement the Wireless Extensions spy API.
  3  *                                                  3  *
  4  * Authors :    Jean Tourrilhes - HPL - <jt@hp      4  * Authors :    Jean Tourrilhes - HPL - <jt@hpl.hp.com>
  5  * Copyright (c) 1997-2007 Jean Tourrilhes, Al      5  * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
  6  *                                                  6  *
  7  * (As all part of the Linux kernel, this file      7  * (As all part of the Linux kernel, this file is GPL)
  8  */                                                 8  */
  9                                                     9 
 10 #include <linux/wireless.h>                        10 #include <linux/wireless.h>
 11 #include <linux/netdevice.h>                       11 #include <linux/netdevice.h>
 12 #include <linux/etherdevice.h>                     12 #include <linux/etherdevice.h>
 13 #include <linux/export.h>                          13 #include <linux/export.h>
 14 #include <net/iw_handler.h>                        14 #include <net/iw_handler.h>
 15 #include <net/arp.h>                               15 #include <net/arp.h>
 16 #include <net/wext.h>                              16 #include <net/wext.h>
 17                                                    17 
 18 static inline struct iw_spy_data *get_spydata(     18 static inline struct iw_spy_data *get_spydata(struct net_device *dev)
 19 {                                                  19 {
 20         /* This is the new way */                  20         /* This is the new way */
 21         if (dev->wireless_data)                    21         if (dev->wireless_data)
 22                 return dev->wireless_data->spy     22                 return dev->wireless_data->spy_data;
 23         return NULL;                               23         return NULL;
 24 }                                                  24 }
 25                                                    25 
 26 int iw_handler_set_spy(struct net_device *         26 int iw_handler_set_spy(struct net_device *      dev,
 27                        struct iw_request_info      27                        struct iw_request_info * info,
 28                        union iwreq_data *          28                        union iwreq_data *       wrqu,
 29                        char *                      29                        char *                   extra)
 30 {                                                  30 {
 31         struct iw_spy_data *    spydata = get_     31         struct iw_spy_data *    spydata = get_spydata(dev);
 32         struct sockaddr *       address = (str     32         struct sockaddr *       address = (struct sockaddr *) extra;
 33                                                    33 
 34         /* Make sure driver is not buggy or us     34         /* Make sure driver is not buggy or using the old API */
 35         if (!spydata)                              35         if (!spydata)
 36                 return -EOPNOTSUPP;                36                 return -EOPNOTSUPP;
 37                                                    37 
 38         /* Disable spy collection while we cop     38         /* Disable spy collection while we copy the addresses.
 39          * While we copy addresses, any call t     39          * While we copy addresses, any call to wireless_spy_update()
 40          * will NOP. This is OK, as anyway the     40          * will NOP. This is OK, as anyway the addresses are changing. */
 41         spydata->spy_number = 0;                   41         spydata->spy_number = 0;
 42                                                    42 
 43         /* We want to operate without locking,     43         /* We want to operate without locking, because wireless_spy_update()
 44          * most likely will happen in the inte     44          * most likely will happen in the interrupt handler, and therefore
 45          * have its own locking constraints an     45          * have its own locking constraints and needs performance.
 46          * The rtnl_lock() make sure we don't      46          * The rtnl_lock() make sure we don't race with the other iw_handlers.
 47          * This make sure wireless_spy_update(     47          * This make sure wireless_spy_update() "see" that the spy list
 48          * is temporarily disabled. */             48          * is temporarily disabled. */
 49         smp_wmb();                                 49         smp_wmb();
 50                                                    50 
 51         /* Are there are addresses to copy? */     51         /* Are there are addresses to copy? */
 52         if (wrqu->data.length > 0) {               52         if (wrqu->data.length > 0) {
 53                 int i;                             53                 int i;
 54                                                    54 
 55                 /* Copy addresses */               55                 /* Copy addresses */
 56                 for (i = 0; i < wrqu->data.len     56                 for (i = 0; i < wrqu->data.length; i++)
 57                         memcpy(spydata->spy_ad     57                         memcpy(spydata->spy_address[i], address[i].sa_data,
 58                                ETH_ALEN);          58                                ETH_ALEN);
 59                 /* Reset stats */                  59                 /* Reset stats */
 60                 memset(spydata->spy_stat, 0,       60                 memset(spydata->spy_stat, 0,
 61                        sizeof(struct iw_qualit     61                        sizeof(struct iw_quality) * IW_MAX_SPY);
 62         }                                          62         }
 63                                                    63 
 64         /* Make sure above is updated before r     64         /* Make sure above is updated before re-enabling */
 65         smp_wmb();                                 65         smp_wmb();
 66                                                    66 
 67         /* Enable addresses */                     67         /* Enable addresses */
 68         spydata->spy_number = wrqu->data.lengt     68         spydata->spy_number = wrqu->data.length;
 69                                                    69 
 70         return 0;                                  70         return 0;
 71 }                                                  71 }
 72 EXPORT_SYMBOL(iw_handler_set_spy);                 72 EXPORT_SYMBOL(iw_handler_set_spy);
 73                                                    73 
 74 int iw_handler_get_spy(struct net_device *         74 int iw_handler_get_spy(struct net_device *      dev,
 75                        struct iw_request_info      75                        struct iw_request_info * info,
 76                        union iwreq_data *          76                        union iwreq_data *       wrqu,
 77                        char *                      77                        char *                   extra)
 78 {                                                  78 {
 79         struct iw_spy_data *    spydata = get_     79         struct iw_spy_data *    spydata = get_spydata(dev);
 80         struct sockaddr *       address = (str     80         struct sockaddr *       address = (struct sockaddr *) extra;
 81         int                     i;                 81         int                     i;
 82                                                    82 
 83         /* Make sure driver is not buggy or us     83         /* Make sure driver is not buggy or using the old API */
 84         if (!spydata)                              84         if (!spydata)
 85                 return -EOPNOTSUPP;                85                 return -EOPNOTSUPP;
 86                                                    86 
 87         wrqu->data.length = spydata->spy_numbe     87         wrqu->data.length = spydata->spy_number;
 88                                                    88 
 89         /* Copy addresses. */                      89         /* Copy addresses. */
 90         for (i = 0; i < spydata->spy_number; i     90         for (i = 0; i < spydata->spy_number; i++)       {
 91                 memcpy(address[i].sa_data, spy     91                 memcpy(address[i].sa_data, spydata->spy_address[i], ETH_ALEN);
 92                 address[i].sa_family = AF_UNIX     92                 address[i].sa_family = AF_UNIX;
 93         }                                          93         }
 94         /* Copy stats to the user buffer (just     94         /* Copy stats to the user buffer (just after). */
 95         if (spydata->spy_number > 0)               95         if (spydata->spy_number > 0)
 96                 memcpy(extra  + (sizeof(struct     96                 memcpy(extra  + (sizeof(struct sockaddr) *spydata->spy_number),
 97                        spydata->spy_stat,          97                        spydata->spy_stat,
 98                        sizeof(struct iw_qualit     98                        sizeof(struct iw_quality) * spydata->spy_number);
 99         /* Reset updated flags. */                 99         /* Reset updated flags. */
100         for (i = 0; i < spydata->spy_number; i    100         for (i = 0; i < spydata->spy_number; i++)
101                 spydata->spy_stat[i].updated &    101                 spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED;
102         return 0;                                 102         return 0;
103 }                                                 103 }
104 EXPORT_SYMBOL(iw_handler_get_spy);                104 EXPORT_SYMBOL(iw_handler_get_spy);
105                                                   105 
106 /*--------------------------------------------    106 /*------------------------------------------------------------------*/
107 /*                                                107 /*
108  * Standard Wireless Handler : set spy thresho    108  * Standard Wireless Handler : set spy threshold
109  */                                               109  */
110 int iw_handler_set_thrspy(struct net_device *     110 int iw_handler_set_thrspy(struct net_device *   dev,
111                           struct iw_request_in    111                           struct iw_request_info *info,
112                           union iwreq_data *      112                           union iwreq_data *    wrqu,
113                           char *                  113                           char *                extra)
114 {                                                 114 {
115         struct iw_spy_data *    spydata = get_    115         struct iw_spy_data *    spydata = get_spydata(dev);
116         struct iw_thrspy *      threshold = (s    116         struct iw_thrspy *      threshold = (struct iw_thrspy *) extra;
117                                                   117 
118         /* Make sure driver is not buggy or us    118         /* Make sure driver is not buggy or using the old API */
119         if (!spydata)                             119         if (!spydata)
120                 return -EOPNOTSUPP;               120                 return -EOPNOTSUPP;
121                                                   121 
122         /* Just do it */                          122         /* Just do it */
123         spydata->spy_thr_low = threshold->low; !! 123         memcpy(&(spydata->spy_thr_low), &(threshold->low),
124         spydata->spy_thr_high = threshold->hig !! 124                2 * sizeof(struct iw_quality));
125                                                   125 
126         /* Clear flag */                          126         /* Clear flag */
127         memset(spydata->spy_thr_under, '\0', s    127         memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
128                                                   128 
129         return 0;                                 129         return 0;
130 }                                                 130 }
131 EXPORT_SYMBOL(iw_handler_set_thrspy);             131 EXPORT_SYMBOL(iw_handler_set_thrspy);
132                                                   132 
133 /*--------------------------------------------    133 /*------------------------------------------------------------------*/
134 /*                                                134 /*
135  * Standard Wireless Handler : get spy thresho    135  * Standard Wireless Handler : get spy threshold
136  */                                               136  */
137 int iw_handler_get_thrspy(struct net_device *     137 int iw_handler_get_thrspy(struct net_device *   dev,
138                           struct iw_request_in    138                           struct iw_request_info *info,
139                           union iwreq_data *      139                           union iwreq_data *    wrqu,
140                           char *                  140                           char *                extra)
141 {                                                 141 {
142         struct iw_spy_data *    spydata = get_    142         struct iw_spy_data *    spydata = get_spydata(dev);
143         struct iw_thrspy *      threshold = (s    143         struct iw_thrspy *      threshold = (struct iw_thrspy *) extra;
144                                                   144 
145         /* Make sure driver is not buggy or us    145         /* Make sure driver is not buggy or using the old API */
146         if (!spydata)                             146         if (!spydata)
147                 return -EOPNOTSUPP;               147                 return -EOPNOTSUPP;
148                                                   148 
149         /* Just do it */                          149         /* Just do it */
150         threshold->low = spydata->spy_thr_low; !! 150         memcpy(&(threshold->low), &(spydata->spy_thr_low),
151         threshold->high = spydata->spy_thr_hig !! 151                2 * sizeof(struct iw_quality));
152                                                   152 
153         return 0;                                 153         return 0;
154 }                                                 154 }
155 EXPORT_SYMBOL(iw_handler_get_thrspy);             155 EXPORT_SYMBOL(iw_handler_get_thrspy);
156                                                   156 
157 /*--------------------------------------------    157 /*------------------------------------------------------------------*/
158 /*                                                158 /*
159  * Prepare and send a Spy Threshold event         159  * Prepare and send a Spy Threshold event
160  */                                               160  */
161 static void iw_send_thrspy_event(struct net_de    161 static void iw_send_thrspy_event(struct net_device *    dev,
162                                  struct iw_spy    162                                  struct iw_spy_data *   spydata,
163                                  unsigned char    163                                  unsigned char *        address,
164                                  struct iw_qua    164                                  struct iw_quality *    wstats)
165 {                                                 165 {
166         union iwreq_data        wrqu;             166         union iwreq_data        wrqu;
167         struct iw_thrspy        threshold;        167         struct iw_thrspy        threshold;
168                                                   168 
169         /* Init */                                169         /* Init */
170         wrqu.data.length = 1;                     170         wrqu.data.length = 1;
171         wrqu.data.flags = 0;                      171         wrqu.data.flags = 0;
172         /* Copy address */                        172         /* Copy address */
173         memcpy(threshold.addr.sa_data, address    173         memcpy(threshold.addr.sa_data, address, ETH_ALEN);
174         threshold.addr.sa_family = ARPHRD_ETHE    174         threshold.addr.sa_family = ARPHRD_ETHER;
175         /* Copy stats */                          175         /* Copy stats */
176         threshold.qual = *wstats;              !! 176         memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality));
177         /* Copy also thresholds */                177         /* Copy also thresholds */
178         threshold.low = spydata->spy_thr_low;  !! 178         memcpy(&(threshold.low), &(spydata->spy_thr_low),
179         threshold.high = spydata->spy_thr_high !! 179                2 * sizeof(struct iw_quality));
180                                                   180 
181         /* Send event to user space */            181         /* Send event to user space */
182         wireless_send_event(dev, SIOCGIWTHRSPY    182         wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
183 }                                                 183 }
184                                                   184 
185 /* -------------------------------------------    185 /* ---------------------------------------------------------------- */
186 /*                                                186 /*
187  * Call for the driver to update the spy data.    187  * Call for the driver to update the spy data.
188  * For now, the spy data is a simple array. As    188  * For now, the spy data is a simple array. As the size of the array is
189  * small, this is good enough. If we wanted to    189  * small, this is good enough. If we wanted to support larger number of
190  * spy addresses, we should use something more    190  * spy addresses, we should use something more efficient...
191  */                                               191  */
192 void wireless_spy_update(struct net_device *      192 void wireless_spy_update(struct net_device *    dev,
193                          unsigned char *          193                          unsigned char *        address,
194                          struct iw_quality *      194                          struct iw_quality *    wstats)
195 {                                                 195 {
196         struct iw_spy_data *    spydata = get_    196         struct iw_spy_data *    spydata = get_spydata(dev);
197         int                     i;                197         int                     i;
198         int                     match = -1;       198         int                     match = -1;
199                                                   199 
200         /* Make sure driver is not buggy or us    200         /* Make sure driver is not buggy or using the old API */
201         if (!spydata)                             201         if (!spydata)
202                 return;                           202                 return;
203                                                   203 
204         /* Update all records that match */       204         /* Update all records that match */
205         for (i = 0; i < spydata->spy_number; i    205         for (i = 0; i < spydata->spy_number; i++)
206                 if (ether_addr_equal(address,     206                 if (ether_addr_equal(address, spydata->spy_address[i])) {
207                         memcpy(&(spydata->spy_    207                         memcpy(&(spydata->spy_stat[i]), wstats,
208                                sizeof(struct i    208                                sizeof(struct iw_quality));
209                         match = i;                209                         match = i;
210                 }                                 210                 }
211                                                   211 
212         /* Generate an event if we cross the s    212         /* Generate an event if we cross the spy threshold.
213          * To avoid event storms, we have a si    213          * To avoid event storms, we have a simple hysteresis : we generate
214          * event only when we go under the low    214          * event only when we go under the low threshold or above the
215          * high threshold. */                     215          * high threshold. */
216         if (match >= 0) {                         216         if (match >= 0) {
217                 if (spydata->spy_thr_under[mat    217                 if (spydata->spy_thr_under[match]) {
218                         if (wstats->level > sp    218                         if (wstats->level > spydata->spy_thr_high.level) {
219                                 spydata->spy_t    219                                 spydata->spy_thr_under[match] = 0;
220                                 iw_send_thrspy    220                                 iw_send_thrspy_event(dev, spydata,
221                                                   221                                                      address, wstats);
222                         }                         222                         }
223                 } else {                          223                 } else {
224                         if (wstats->level < sp    224                         if (wstats->level < spydata->spy_thr_low.level) {
225                                 spydata->spy_t    225                                 spydata->spy_thr_under[match] = 1;
226                                 iw_send_thrspy    226                                 iw_send_thrspy_event(dev, spydata,
227                                                   227                                                      address, wstats);
228                         }                         228                         }
229                 }                                 229                 }
230         }                                         230         }
231 }                                                 231 }
232 EXPORT_SYMBOL(wireless_spy_update);               232 EXPORT_SYMBOL(wireless_spy_update);
233                                                   233 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php