aboutsummaryrefslogtreecommitdiff
path: root/src/transport/wlan/radiotap-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/wlan/radiotap-parser.c')
-rw-r--r--src/transport/wlan/radiotap-parser.c360
1 files changed, 184 insertions, 176 deletions
diff --git a/src/transport/wlan/radiotap-parser.c b/src/transport/wlan/radiotap-parser.c
index 46ea6d542..51dfd7107 100644
--- a/src/transport/wlan/radiotap-parser.c
+++ b/src/transport/wlan/radiotap-parser.c
@@ -38,67 +38,69 @@
38 */ 38 */
39 39
40 40
41int ieee80211_radiotap_iterator_init( 41int
42 struct ieee80211_radiotap_iterator * iterator, 42ieee80211_radiotap_iterator_init (struct ieee80211_radiotap_iterator *iterator,
43 struct ieee80211_radiotap_header * radiotap_header, 43 struct ieee80211_radiotap_header
44 int max_length) 44 *radiotap_header, int max_length)
45{ 45{
46 if(iterator == NULL) 46 if (iterator == NULL)
47 return (-EINVAL); 47 return (-EINVAL);
48 48
49 if(radiotap_header == NULL) 49 if (radiotap_header == NULL)
50 return (-EINVAL); 50 return (-EINVAL);
51 /* Linux only supports version 0 radiotap format */ 51 /* Linux only supports version 0 radiotap format */
52 52
53 if (radiotap_header->it_version) 53 if (radiotap_header->it_version)
54 return (-EINVAL); 54 return (-EINVAL);
55 55
56 /* sanity check for allowed length and radiotap length field */ 56 /* sanity check for allowed length and radiotap length field */
57 57
58 if (max_length < (le16_to_cpu(radiotap_header->it_len))) 58 if (max_length < (le16_to_cpu (radiotap_header->it_len)))
59 return (-EINVAL); 59 return (-EINVAL);
60 60
61 iterator->rtheader = radiotap_header; 61 iterator->rtheader = radiotap_header;
62 iterator->max_length = le16_to_cpu(radiotap_header->it_len); 62 iterator->max_length = le16_to_cpu (radiotap_header->it_len);
63 iterator->arg_index = 0; 63 iterator->arg_index = 0;
64 iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present); 64 iterator->bitmap_shifter = le32_to_cpu (radiotap_header->it_present);
65 iterator->arg = ((u8 *)radiotap_header) + 65 iterator->arg = ((u8 *) radiotap_header) +
66 sizeof (struct ieee80211_radiotap_header); 66 sizeof (struct ieee80211_radiotap_header);
67 iterator->this_arg = 0; 67 iterator->this_arg = 0;
68 68
69 /* find payload start allowing for extended bitmap(s) */ 69 /* find payload start allowing for extended bitmap(s) */
70 70
71 if (unlikely(iterator->bitmap_shifter & 71 if (unlikely (iterator->bitmap_shifter &
72 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)) { 72 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK))
73 while (le32_to_cpu(*((u32 *)iterator->arg)) & 73 {
74 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK) { 74 while (le32_to_cpu (*((u32 *) iterator->arg)) &
75 iterator->arg += sizeof (u32); 75 IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK)
76 {
77 iterator->arg += sizeof (u32);
76 78
77 /* 79 /*
78 * check for insanity where the present bitmaps 80 * check for insanity where the present bitmaps
79 * keep claiming to extend up to or even beyond the 81 * keep claiming to extend up to or even beyond the
80 * stated radiotap header length 82 * stated radiotap header length
81 */ 83 */
82 84
83 if ((((void*)iterator->arg) - ((void*)iterator->rtheader)) > 85 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
84 iterator->max_length) 86 iterator->max_length)
85 return (-EINVAL); 87 return (-EINVAL);
86 88
87 } 89 }
88 90
89 iterator->arg += sizeof (u32); 91 iterator->arg += sizeof (u32);
90 92
91 /* 93 /*
92 * no need to check again for blowing past stated radiotap 94 * no need to check again for blowing past stated radiotap
93 * header length, becuase ieee80211_radiotap_iterator_next 95 * header length, becuase ieee80211_radiotap_iterator_next
94 * checks it before it is dereferenced 96 * checks it before it is dereferenced
95 */ 97 */
96 98
97 } 99 }
98 100
99 /* we are all initialized happily */ 101 /* we are all initialized happily */
100 102
101 return (0); 103 return (0);
102} 104}
103 105
104 106
@@ -115,137 +117,143 @@ int ieee80211_radiotap_iterator_init(
115 * format. 117 * format.
116 */ 118 */
117 119
118int ieee80211_radiotap_iterator_next( 120int
119 struct ieee80211_radiotap_iterator * iterator) 121ieee80211_radiotap_iterator_next (struct ieee80211_radiotap_iterator *iterator)
120{ 122{
121 123
122 /* 124 /*
123 * small length lookup table for all radiotap types we heard of 125 * small length lookup table for all radiotap types we heard of
124 * starting from b0 in the bitmap, so we can walk the payload 126 * starting from b0 in the bitmap, so we can walk the payload
125 * area of the radiotap header 127 * area of the radiotap header
126 * 128 *
127 * There is a requirement to pad args, so that args 129 * There is a requirement to pad args, so that args
128 * of a given length must begin at a boundary of that length 130 * of a given length must begin at a boundary of that length
129 * -- but note that compound args are allowed (eg, 2 x u16 131 * -- but note that compound args are allowed (eg, 2 x u16
130 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not 132 * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
131 * a reliable indicator of alignment requirement. 133 * a reliable indicator of alignment requirement.
132 * 134 *
133 * upper nybble: content alignment for arg 135 * upper nybble: content alignment for arg
134 * lower nybble: content length for arg 136 * lower nybble: content length for arg
135 */ 137 */
136 138
137 static const u8 rt_sizes[] = { 139 static const u8 rt_sizes[] = {
138 [IEEE80211_RADIOTAP_TSFT] = 0x88, 140 [IEEE80211_RADIOTAP_TSFT] = 0x88,
139 [IEEE80211_RADIOTAP_FLAGS] = 0x11, 141 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
140 [IEEE80211_RADIOTAP_RATE] = 0x11, 142 [IEEE80211_RADIOTAP_RATE] = 0x11,
141 [IEEE80211_RADIOTAP_CHANNEL] = 0x24, 143 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
142 [IEEE80211_RADIOTAP_FHSS] = 0x22, 144 [IEEE80211_RADIOTAP_FHSS] = 0x22,
143 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11, 145 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
144 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11, 146 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
145 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22, 147 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
146 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22, 148 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
147 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22, 149 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
148 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11, 150 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
149 [IEEE80211_RADIOTAP_ANTENNA] = 0x11, 151 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
150 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11, 152 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
151 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11, 153 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
152 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22, 154 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
153 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22, 155 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
154 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11, 156 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
155 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11 157 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11
156 /* 158 /*
157 * add more here as they are defined in 159 * add more here as they are defined in
158 * include/net/ieee80211_radiotap.h 160 * include/net/ieee80211_radiotap.h
159 */ 161 */
160 }; 162 };
161 163
162 /* 164 /*
163 * for every radiotap entry we can at 165 * for every radiotap entry we can at
164 * least skip (by knowing the length)... 166 * least skip (by knowing the length)...
165 */ 167 */
166 168
167 while (iterator->arg_index < (int)sizeof (rt_sizes)) { 169 while (iterator->arg_index < (int) sizeof (rt_sizes))
168 int hit = 0; 170 {
169 171 int hit = 0;
170 if (!(iterator->bitmap_shifter & 1)) 172
171 goto next_entry; /* arg not present */ 173 if (!(iterator->bitmap_shifter & 1))
172 174 goto next_entry; /* arg not present */
173 /* 175
174 * arg is present, account for alignment padding 176 /*
175 * 8-bit args can be at any alignment 177 * arg is present, account for alignment padding
176 * 16-bit args must start on 16-bit boundary 178 * 8-bit args can be at any alignment
177 * 32-bit args must start on 32-bit boundary 179 * 16-bit args must start on 16-bit boundary
178 * 64-bit args must start on 64-bit boundary 180 * 32-bit args must start on 32-bit boundary
179 * 181 * 64-bit args must start on 64-bit boundary
180 * note that total arg size can differ from alignment of 182 *
181 * elements inside arg, so we use upper nybble of length 183 * note that total arg size can differ from alignment of
182 * table to base alignment on 184 * elements inside arg, so we use upper nybble of length
183 * 185 * table to base alignment on
184 * also note: these alignments are ** relative to the 186 *
185 * start of the radiotap header **. There is no guarantee 187 * also note: these alignments are ** relative to the
186 * that the radiotap header itself is aligned on any 188 * start of the radiotap header **. There is no guarantee
187 * kind of boundary. 189 * that the radiotap header itself is aligned on any
188 */ 190 * kind of boundary.
189 191 */
190 if ((((void*)iterator->arg)-((void*)iterator->rtheader)) & 192
191 ((rt_sizes[iterator->arg_index] >> 4) - 1)) 193 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) &
192 iterator->arg_index += 194 ((rt_sizes[iterator->arg_index] >> 4) - 1))
193 (rt_sizes[iterator->arg_index] >> 4) - 195 iterator->arg_index +=
194 ((((void*)iterator->arg) - 196 (rt_sizes[iterator->arg_index] >> 4) -
195 ((void*)iterator->rtheader)) & 197 ((((void *) iterator->arg) -
196 ((rt_sizes[iterator->arg_index] >> 4) - 1)); 198 ((void *) iterator->rtheader)) &
197 199 ((rt_sizes[iterator->arg_index] >> 4) - 1));
198 /* 200
199 * this is what we will return to user, but we need to 201 /*
200 * move on first so next call has something fresh to test 202 * this is what we will return to user, but we need to
201 */ 203 * move on first so next call has something fresh to test
202 204 */
203 iterator->this_arg_index = iterator->arg_index; 205
204 iterator->this_arg = iterator->arg; 206 iterator->this_arg_index = iterator->arg_index;
205 hit = 1; 207 iterator->this_arg = iterator->arg;
206 208 hit = 1;
207 /* internally move on the size of this arg */ 209
208 210 /* internally move on the size of this arg */
209 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f; 211
210 212 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
211 /* 213
212 * check for insanity where we are given a bitmap that 214 /*
213 * claims to have more arg content than the length of the 215 * check for insanity where we are given a bitmap that
214 * radiotap section. We will normally end up equalling this 216 * claims to have more arg content than the length of the
215 * max_length on the last arg, never exceeding it. 217 * radiotap section. We will normally end up equalling this
216 */ 218 * max_length on the last arg, never exceeding it.
217 219 */
218 if ((((void*)iterator->arg) - ((void*)iterator->rtheader)) > 220
219 iterator->max_length) 221 if ((((void *) iterator->arg) - ((void *) iterator->rtheader)) >
220 return (-EINVAL); 222 iterator->max_length)
221 223 return (-EINVAL);
222 next_entry: 224
223 225next_entry:
224 iterator->arg_index++; 226
225 if (unlikely((iterator->arg_index & 31) == 0)) { 227 iterator->arg_index++;
226 /* completed current u32 bitmap */ 228 if (unlikely ((iterator->arg_index & 31) == 0))
227 if (iterator->bitmap_shifter & 1) { 229 {
228 /* b31 was set, there is more */ 230 /* completed current u32 bitmap */
229 /* move to next u32 bitmap */ 231 if (iterator->bitmap_shifter & 1)
230 iterator->bitmap_shifter = le32_to_cpu( 232 {
231 *iterator->next_bitmap); 233 /* b31 was set, there is more */
232 iterator->next_bitmap++; 234 /* move to next u32 bitmap */
233 } else { 235 iterator->bitmap_shifter = le32_to_cpu (*iterator->next_bitmap);
234 /* no more bitmaps: end */ 236 iterator->next_bitmap++;
235 iterator->arg_index = sizeof (rt_sizes); 237 }
236 } 238 else
237 } else { /* just try the next bit */ 239 {
238 iterator->bitmap_shifter >>= 1; 240 /* no more bitmaps: end */
239 } 241 iterator->arg_index = sizeof (rt_sizes);
240 242 }
241 /* if we found a valid arg earlier, return it now */ 243 }
242 244 else
243 if (hit) 245 { /* just try the next bit */
244 return (iterator->this_arg_index); 246 iterator->bitmap_shifter >>= 1;
245 247 }
246 } 248
247 249 /* if we found a valid arg earlier, return it now */
248 /* we don't know how to handle any more args, we're done */ 250
249 251 if (hit)
250 return (-1); 252 return (iterator->this_arg_index);
253
254 }
255
256 /* we don't know how to handle any more args, we're done */
257
258 return (-1);
251} 259}