radiotap.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Radiotap parser
  3. *
  4. * Copyright 2007 Andy Green <andy@warmcat.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Alternatively, this software may be distributed under the terms of BSD
  11. * license.
  12. *
  13. * See README and COPYING for more details.
  14. *
  15. *
  16. * Modified for userspace by Johannes Berg <johannes@sipsolutions.net>
  17. * I only modified some things on top to ease syncing should bugs be found.
  18. */
  19. #include "includes.h"
  20. #include "common.h"
  21. #include "radiotap_iter.h"
  22. #define le16_to_cpu le_to_host16
  23. #define le32_to_cpu le_to_host32
  24. #define __le32 uint32_t
  25. #define ulong unsigned long
  26. #define unlikely(cond) (cond)
  27. #define get_unaligned(p) \
  28. ({ \
  29. struct packed_dummy_struct { \
  30. typeof(*(p)) __val; \
  31. } __attribute__((packed)) *__ptr = (void *) (p); \
  32. \
  33. __ptr->__val; \
  34. })
  35. /* function prototypes and related defs are in radiotap_iter.h */
  36. /**
  37. * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
  38. * @iterator: radiotap_iterator to initialize
  39. * @radiotap_header: radiotap header to parse
  40. * @max_length: total length we can parse into (eg, whole packet length)
  41. *
  42. * Returns: 0 or a negative error code if there is a problem.
  43. *
  44. * This function initializes an opaque iterator struct which can then
  45. * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
  46. * argument which is present in the header. It knows about extended
  47. * present headers and handles them.
  48. *
  49. * How to use:
  50. * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
  51. * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
  52. * checking for a good 0 return code. Then loop calling
  53. * __ieee80211_radiotap_iterator_next()... it returns either 0,
  54. * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
  55. * The iterator's @this_arg member points to the start of the argument
  56. * associated with the current argument index that is present, which can be
  57. * found in the iterator's @this_arg_index member. This arg index corresponds
  58. * to the IEEE80211_RADIOTAP_... defines.
  59. *
  60. * Radiotap header length:
  61. * You can find the CPU-endian total radiotap header length in
  62. * iterator->max_length after executing ieee80211_radiotap_iterator_init()
  63. * successfully.
  64. *
  65. * Alignment Gotcha:
  66. * You must take care when dereferencing iterator.this_arg
  67. * for multibyte types... the pointer is not aligned. Use
  68. * get_unaligned((type *)iterator.this_arg) to dereference
  69. * iterator.this_arg for type "type" safely on all arches.
  70. *
  71. * Example code:
  72. * See Documentation/networking/radiotap-headers.txt
  73. */
  74. int ieee80211_radiotap_iterator_init(
  75. struct ieee80211_radiotap_iterator *iterator,
  76. struct ieee80211_radiotap_header *radiotap_header,
  77. int max_length)
  78. {
  79. /* Linux only supports version 0 radiotap format */
  80. if (radiotap_header->it_version)
  81. return -EINVAL;
  82. /* sanity check for allowed length and radiotap length field */
  83. if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len)))
  84. return -EINVAL;
  85. iterator->rtheader = radiotap_header;
  86. iterator->max_length = le16_to_cpu(get_unaligned(
  87. &radiotap_header->it_len));
  88. iterator->arg_index = 0;
  89. iterator->bitmap_shifter = le32_to_cpu(get_unaligned(
  90. &radiotap_header->it_present));
  91. iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
  92. iterator->this_arg = NULL;
  93. /* find payload start allowing for extended bitmap(s) */
  94. if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
  95. while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) &
  96. (1<<IEEE80211_RADIOTAP_EXT)) {
  97. iterator->arg += sizeof(u32);
  98. /*
  99. * check for insanity where the present bitmaps
  100. * keep claiming to extend up to or even beyond the
  101. * stated radiotap header length
  102. */
  103. if (((ulong)iterator->arg - (ulong)iterator->rtheader)
  104. > (ulong)iterator->max_length)
  105. return -EINVAL;
  106. }
  107. iterator->arg += sizeof(u32);
  108. /*
  109. * no need to check again for blowing past stated radiotap
  110. * header length, because ieee80211_radiotap_iterator_next
  111. * checks it before it is dereferenced
  112. */
  113. }
  114. /* we are all initialized happily */
  115. return 0;
  116. }
  117. /**
  118. * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
  119. * @iterator: radiotap_iterator to move to next arg (if any)
  120. *
  121. * Returns: 0 if there is an argument to handle,
  122. * -ENOENT if there are no more args or -EINVAL
  123. * if there is something else wrong.
  124. *
  125. * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
  126. * in @this_arg_index and sets @this_arg to point to the
  127. * payload for the field. It takes care of alignment handling and extended
  128. * present fields. @this_arg can be changed by the caller (eg,
  129. * incremented to move inside a compound argument like
  130. * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
  131. * little-endian format whatever the endianess of your CPU.
  132. *
  133. * Alignment Gotcha:
  134. * You must take care when dereferencing iterator.this_arg
  135. * for multibyte types... the pointer is not aligned. Use
  136. * get_unaligned((type *)iterator.this_arg) to dereference
  137. * iterator.this_arg for type "type" safely on all arches.
  138. */
  139. int ieee80211_radiotap_iterator_next(
  140. struct ieee80211_radiotap_iterator *iterator)
  141. {
  142. /*
  143. * small length lookup table for all radiotap types we heard of
  144. * starting from b0 in the bitmap, so we can walk the payload
  145. * area of the radiotap header
  146. *
  147. * There is a requirement to pad args, so that args
  148. * of a given length must begin at a boundary of that length
  149. * -- but note that compound args are allowed (eg, 2 x u16
  150. * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
  151. * a reliable indicator of alignment requirement.
  152. *
  153. * upper nybble: content alignment for arg
  154. * lower nybble: content length for arg
  155. */
  156. static const u8 rt_sizes[] = {
  157. [IEEE80211_RADIOTAP_TSFT] = 0x88,
  158. [IEEE80211_RADIOTAP_FLAGS] = 0x11,
  159. [IEEE80211_RADIOTAP_RATE] = 0x11,
  160. [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
  161. [IEEE80211_RADIOTAP_FHSS] = 0x22,
  162. [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
  163. [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
  164. [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
  165. [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
  166. [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
  167. [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
  168. [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
  169. [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
  170. [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
  171. [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
  172. [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
  173. [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
  174. [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11,
  175. /*
  176. * add more here as they are defined in
  177. * include/net/ieee80211_radiotap.h
  178. */
  179. };
  180. /*
  181. * for every radiotap entry we can at
  182. * least skip (by knowing the length)...
  183. */
  184. while (iterator->arg_index < (int) sizeof(rt_sizes)) {
  185. int hit = 0;
  186. int pad;
  187. if (!(iterator->bitmap_shifter & 1))
  188. goto next_entry; /* arg not present */
  189. /*
  190. * arg is present, account for alignment padding
  191. * 8-bit args can be at any alignment
  192. * 16-bit args must start on 16-bit boundary
  193. * 32-bit args must start on 32-bit boundary
  194. * 64-bit args must start on 64-bit boundary
  195. *
  196. * note that total arg size can differ from alignment of
  197. * elements inside arg, so we use upper nybble of length
  198. * table to base alignment on
  199. *
  200. * also note: these alignments are ** relative to the
  201. * start of the radiotap header **. There is no guarantee
  202. * that the radiotap header itself is aligned on any
  203. * kind of boundary.
  204. *
  205. * the above is why get_unaligned() is used to dereference
  206. * multibyte elements from the radiotap area
  207. */
  208. pad = (((ulong)iterator->arg) -
  209. ((ulong)iterator->rtheader)) &
  210. ((rt_sizes[iterator->arg_index] >> 4) - 1);
  211. if (pad)
  212. iterator->arg +=
  213. (rt_sizes[iterator->arg_index] >> 4) - pad;
  214. /*
  215. * this is what we will return to user, but we need to
  216. * move on first so next call has something fresh to test
  217. */
  218. iterator->this_arg_index = iterator->arg_index;
  219. iterator->this_arg = iterator->arg;
  220. hit = 1;
  221. /* internally move on the size of this arg */
  222. iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
  223. /*
  224. * check for insanity where we are given a bitmap that
  225. * claims to have more arg content than the length of the
  226. * radiotap section. We will normally end up equalling this
  227. * max_length on the last arg, never exceeding it.
  228. */
  229. if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
  230. (ulong) iterator->max_length)
  231. return -EINVAL;
  232. next_entry:
  233. iterator->arg_index++;
  234. if (unlikely((iterator->arg_index & 31) == 0)) {
  235. /* completed current u32 bitmap */
  236. if (iterator->bitmap_shifter & 1) {
  237. /* b31 was set, there is more */
  238. /* move to next u32 bitmap */
  239. iterator->bitmap_shifter = le32_to_cpu(
  240. get_unaligned(iterator->next_bitmap));
  241. iterator->next_bitmap++;
  242. } else
  243. /* no more bitmaps: end */
  244. iterator->arg_index = sizeof(rt_sizes);
  245. } else /* just try the next bit */
  246. iterator->bitmap_shifter >>= 1;
  247. /* if we found a valid arg earlier, return it now */
  248. if (hit)
  249. return 0;
  250. }
  251. /* we don't know how to handle any more args, we're done */
  252. return -ENOENT;
  253. }