radiotap.c
Go to the documentation of this file.00001
00021 #include "includes.h"
00022
00023 #include "common.h"
00024 #include "radiotap_iter.h"
00025
00026 #define le16_to_cpu le_to_host16
00027 #define le32_to_cpu le_to_host32
00028 #define __le32 uint32_t
00029 #define ulong unsigned long
00030 #define unlikely(cond) (cond)
00031 #define get_unaligned(p) \
00032 ({ \
00033 struct packed_dummy_struct { \
00034 typeof(*(p)) __val; \
00035 } __attribute__((packed)) *__ptr = (void *) (p); \
00036 \
00037 __ptr->__val; \
00038 })
00039
00040
00041
00082 int ieee80211_radiotap_iterator_init(
00083 struct ieee80211_radiotap_iterator *iterator,
00084 struct ieee80211_radiotap_header *radiotap_header,
00085 int max_length)
00086 {
00087
00088 if (radiotap_header->it_version)
00089 return -EINVAL;
00090
00091
00092 if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len)))
00093 return -EINVAL;
00094
00095 iterator->rtheader = radiotap_header;
00096 iterator->max_length = le16_to_cpu(get_unaligned(
00097 &radiotap_header->it_len));
00098 iterator->arg_index = 0;
00099 iterator->bitmap_shifter = le32_to_cpu(get_unaligned(
00100 &radiotap_header->it_present));
00101 iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
00102 iterator->this_arg = NULL;
00103
00104
00105
00106 if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
00107 while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) &
00108 (1<<IEEE80211_RADIOTAP_EXT)) {
00109 iterator->arg += sizeof(u32);
00110
00111
00112
00113
00114
00115
00116
00117 if (((ulong)iterator->arg - (ulong)iterator->rtheader)
00118 > (ulong)iterator->max_length)
00119 return -EINVAL;
00120 }
00121
00122 iterator->arg += sizeof(u32);
00123
00124
00125
00126
00127
00128
00129 }
00130
00131
00132
00133 return 0;
00134 }
00135
00136
00161 int ieee80211_radiotap_iterator_next(
00162 struct ieee80211_radiotap_iterator *iterator)
00163 {
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 static const u8 rt_sizes[] = {
00181 [IEEE80211_RADIOTAP_TSFT] = 0x88,
00182 [IEEE80211_RADIOTAP_FLAGS] = 0x11,
00183 [IEEE80211_RADIOTAP_RATE] = 0x11,
00184 [IEEE80211_RADIOTAP_CHANNEL] = 0x24,
00185 [IEEE80211_RADIOTAP_FHSS] = 0x22,
00186 [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
00187 [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
00188 [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
00189 [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
00190 [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
00191 [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
00192 [IEEE80211_RADIOTAP_ANTENNA] = 0x11,
00193 [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
00194 [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11,
00195 [IEEE80211_RADIOTAP_RX_FLAGS] = 0x22,
00196 [IEEE80211_RADIOTAP_TX_FLAGS] = 0x22,
00197 [IEEE80211_RADIOTAP_RTS_RETRIES] = 0x11,
00198 [IEEE80211_RADIOTAP_DATA_RETRIES] = 0x11,
00199
00200
00201
00202
00203 };
00204
00205
00206
00207
00208
00209
00210 while (iterator->arg_index < (int) sizeof(rt_sizes)) {
00211 int hit = 0;
00212 int pad;
00213
00214 if (!(iterator->bitmap_shifter & 1))
00215 goto next_entry;
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 pad = (((ulong)iterator->arg) -
00238 ((ulong)iterator->rtheader)) &
00239 ((rt_sizes[iterator->arg_index] >> 4) - 1);
00240
00241 if (pad)
00242 iterator->arg +=
00243 (rt_sizes[iterator->arg_index] >> 4) - pad;
00244
00245
00246
00247
00248
00249 iterator->this_arg_index = iterator->arg_index;
00250 iterator->this_arg = iterator->arg;
00251 hit = 1;
00252
00253
00254 iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
00255
00256
00257
00258
00259
00260
00261
00262
00263 if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
00264 (ulong) iterator->max_length)
00265 return -EINVAL;
00266
00267 next_entry:
00268 iterator->arg_index++;
00269 if (unlikely((iterator->arg_index & 31) == 0)) {
00270
00271 if (iterator->bitmap_shifter & 1) {
00272
00273
00274 iterator->bitmap_shifter = le32_to_cpu(
00275 get_unaligned(iterator->next_bitmap));
00276 iterator->next_bitmap++;
00277 } else
00278
00279 iterator->arg_index = sizeof(rt_sizes);
00280 } else
00281 iterator->bitmap_shifter >>= 1;
00282
00283
00284 if (hit)
00285 return 0;
00286 }
00287
00288
00289 return -ENOENT;
00290 }
00291