#ifndef RADIOTAP_FLAGS_H
#define RADIOTAP_FLAGS_H
/* (C) 2014 - 2017 rofl0r
released under the public domain.
*/
#include <stdint.h>
/* prevent redefining the same types when the official radiotap
header is in use too */
#ifndef IEEE80211RADIOTAP_H
struct ieee80211_radiotap_header {
uint8_t it_version;
uint8_t it_pad;
uint16_t it_len;
uint32_t it_present;
};
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TSFT = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
IEEE80211_RADIOTAP_CHANNEL = 3,
IEEE80211_RADIOTAP_FHSS = 4,
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
IEEE80211_RADIOTAP_RX_FLAGS = 14,
IEEE80211_RADIOTAP_TX_FLAGS = 15,
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
IEEE80211_RADIOTAP_XCHANNEL = 18,
IEEE80211_RADIOTAP_MCS = 19,
IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
IEEE80211_RADIOTAP_VHT = 21,
IEEE80211_RADIOTAP_TIMESTAMP = 22,
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
IEEE80211_RADIOTAP_EXT = 31
};
#endif
static const unsigned char ieee80211_radiotap_type_size[] = {
[IEEE80211_RADIOTAP_TSFT] = 8,
[IEEE80211_RADIOTAP_FLAGS] = 1,
[IEEE80211_RADIOTAP_RATE] = 1,
[IEEE80211_RADIOTAP_CHANNEL] = 2*2,
[IEEE80211_RADIOTAP_FHSS] = 2,
[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 1,
[IEEE80211_RADIOTAP_DBM_ANTNOISE] = 1,
[IEEE80211_RADIOTAP_LOCK_QUALITY] = 2,
[IEEE80211_RADIOTAP_TX_ATTENUATION] = 2,
[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 2,
[IEEE80211_RADIOTAP_DBM_TX_POWER] = 1,
[IEEE80211_RADIOTAP_ANTENNA] = 1,
[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 1,
[IEEE80211_RADIOTAP_DB_ANTNOISE] = 1,
[IEEE80211_RADIOTAP_RX_FLAGS] = 2,
[IEEE80211_RADIOTAP_TX_FLAGS] = 2,
[IEEE80211_RADIOTAP_RTS_RETRIES] = 1,
[IEEE80211_RADIOTAP_DATA_RETRIES] = 1,
[IEEE80211_RADIOTAP_MCS] = 1+1+1,
[IEEE80211_RADIOTAP_AMPDU_STATUS] = 4+2+1+1,
[IEEE80211_RADIOTAP_VHT] = 12,
[IEEE80211_RADIOTAP_TIMESTAMP] = 12,
};
static const unsigned char ieee80211_radiotap_type_align[] = {
[IEEE80211_RADIOTAP_TSFT] = 8,
[IEEE80211_RADIOTAP_FLAGS] = 1,
[IEEE80211_RADIOTAP_RATE] = 1,
[IEEE80211_RADIOTAP_CHANNEL] = 2,
[IEEE80211_RADIOTAP_FHSS] = 2,
[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 1,
[IEEE80211_RADIOTAP_DBM_ANTNOISE] = 1,
[IEEE80211_RADIOTAP_LOCK_QUALITY] = 2,
[IEEE80211_RADIOTAP_TX_ATTENUATION] = 2,
[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 2,
[IEEE80211_RADIOTAP_DBM_TX_POWER] = 1,
[IEEE80211_RADIOTAP_ANTENNA] = 1,
[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 1,
[IEEE80211_RADIOTAP_DB_ANTNOISE] = 1,
[IEEE80211_RADIOTAP_RX_FLAGS] = 2,
[IEEE80211_RADIOTAP_TX_FLAGS] = 2,
[IEEE80211_RADIOTAP_RTS_RETRIES] = 1,
[IEEE80211_RADIOTAP_DATA_RETRIES] = 1,
[IEEE80211_RADIOTAP_MCS] = 1,
[IEEE80211_RADIOTAP_AMPDU_STATUS] = 4,
[IEEE80211_RADIOTAP_VHT] = 2,
[IEEE80211_RADIOTAP_TIMESTAMP] = 8,
};
/* get offset of the specified flag, starting from start_off */
static uint32_t rt_get_flag_offset(uint32_t pflags, uint32_t which, uint32_t start_off)
{
unsigned i,c=start_off;
for(i=0;i<which;i++) if(pflags & (1U << i)) {
c+= c & (ieee80211_radiotap_type_align[i]-1);
c+= ieee80211_radiotap_type_size[i];
}
return c;
}
#include <string.h>
#include "utils/endianness.h"
/* get present flags and offset of just after the radiotap header end.
returns 1 on succes, 0 on bogus data */
static int rt_get_presentflags(const void *data, size_t len, uint32_t *pflags, uint32_t *offset)
{
const struct ieee80211_radiotap_header* rh = data;
*offset = sizeof(*rh);
uint32_t fc = *pflags = end_le32toh(rh->it_present);
while(fc & (1U << IEEE80211_RADIOTAP_EXT)) {
if (*offset > len - 4) return 0;
memcpy(&fc, data + *offset, 4);
fc = end_le32toh(fc);
*offset += 4;
}
return 1;
}
#endif