diff options
Diffstat (limited to 'net/wireless/radiotap.c')
-rw-r--r-- | net/wireless/radiotap.c | 58 |
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 |