aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/radiotap.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/radiotap.c')
-rw-r--r--net/wireless/radiotap.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 1332c445d1c7..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -14,6 +14,7 @@
14 * See COPYING for more details. 14 * See COPYING for more details.
15 */ 15 */
16 16
17#include <linux/kernel.h>
17#include <net/cfg80211.h> 18#include <net/cfg80211.h>
18#include <net/ieee80211_radiotap.h> 19#include <net/ieee80211_radiotap.h>
19#include <asm/unaligned.h> 20#include <asm/unaligned.h>
@@ -45,7 +46,7 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = {
45}; 46};
46 47
47static const struct ieee80211_radiotap_namespace radiotap_ns = { 48static const struct ieee80211_radiotap_namespace radiotap_ns = {
48 .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]), 49 .n_bits = ARRAY_SIZE(rtap_namespace_sizes),
49 .align_size = rtap_namespace_sizes, 50 .align_size = rtap_namespace_sizes,
50}; 51};
51 52
@@ -200,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
200{ 201{
201 while (1) { 202 while (1) {
202 int hit = 0; 203 int hit = 0;
203 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
204 uint32_t oui; 205 uint32_t oui;
205 206
206 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -260,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
260 if (pad) 261 if (pad)
261 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
262 263
264 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
265 int vnslen;
266
267 if ((unsigned long)iterator->_arg + size -
268 (unsigned long)iterator->_rtheader >
269 (unsigned long)iterator->_max_length)
270 return -EINVAL;
271
272 oui = (*iterator->_arg << 16) |
273 (*(iterator->_arg + 1) << 8) |
274 *(iterator->_arg + 2);
275 subns = *(iterator->_arg + 3);
276
277 find_ns(iterator, oui, subns);
278
279 vnslen = get_unaligned_le16(iterator->_arg + 4);
280 iterator->_next_ns_data = iterator->_arg + size + vnslen;
281 if (!iterator->current_namespace)
282 size += vnslen;
283 }
284
263 /* 285 /*
264 * this is what we will return to user, but we need to 286 * this is what we will return to user, but we need to
265 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -286,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
286 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
287 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
288 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
289 iterator->_bitmap_shifter >>= 1;
290 iterator->_arg_index++;
291
292 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
293 312
294 vnslen = get_unaligned_le16(iterator->this_arg + 4);
295 iterator->_next_ns_data = iterator->_arg + vnslen;
296 oui = (*iterator->this_arg << 16) |
297 (*(iterator->this_arg + 1) << 8) |
298 *(iterator->this_arg + 2);
299 subns = *(iterator->this_arg + 3);
300
301 find_ns(iterator, oui, subns);
302
303 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
304 /* allow parsers to show this information */ 314 /*
315 * If parser didn't register this vendor
316 * namespace with us, allow it to show it
317 * as 'raw. Do do that, set argument index
318 * to vendor namespace.
319 */
305 iterator->this_arg_index = 320 iterator->this_arg_index =
306 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
307 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
308 if ((unsigned long)iterator->this_arg + 323 hit = 1;
309 iterator->this_arg_size - 324 goto next_entry;
310 (unsigned long)iterator->_rtheader >
311 (unsigned long)(unsigned long)iterator->_max_length)
312 return -EINVAL;
313 hit = 1;
314 break;
315 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
316 iterator->_bitmap_shifter >>= 1;
317 iterator->_arg_index++;
318
319 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
320 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
321 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
322 break; 329 goto next_entry;
323 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
324 /* 331 /*
325 * bit 31 was set, there is more 332 * bit 31 was set, there is more