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.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
201{ 201{
202 while (1) { 202 while (1) {
203 int hit = 0; 203 int hit = 0;
204 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
205 uint32_t oui; 205 uint32_t oui;
206 206
207 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
261 if (pad) 261 if (pad)
262 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
263 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
264 /* 285 /*
265 * 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
266 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
287 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
288 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
289 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290 iterator->_bitmap_shifter >>= 1;
291 iterator->_arg_index++;
292
293 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
294 312
295 vnslen = get_unaligned_le16(iterator->this_arg + 4);
296 iterator->_next_ns_data = iterator->_arg + vnslen;
297 oui = (*iterator->this_arg << 16) |
298 (*(iterator->this_arg + 1) << 8) |
299 *(iterator->this_arg + 2);
300 subns = *(iterator->this_arg + 3);
301
302 find_ns(iterator, oui, subns);
303
304 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
305 /* 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 */
306 iterator->this_arg_index = 320 iterator->this_arg_index =
307 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
309 if ((unsigned long)iterator->this_arg + 323 hit = 1;
310 iterator->this_arg_size - 324 goto next_entry;
311 (unsigned long)iterator->_rtheader >
312 (unsigned long)(unsigned long)iterator->_max_length)
313 return -EINVAL;
314 hit = 1;
315 break;
316 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317 iterator->_bitmap_shifter >>= 1;
318 iterator->_arg_index++;
319
320 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
321 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
322 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
323 break; 329 goto next_entry;
324 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
325 /* 331 /*
326 * bit 31 was set, there is more 332 * bit 31 was set, there is more