1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| /** radiotap头部解析 使用radiotap库,源码地址: https://github.com/radiotap/radiotap-library
*/
#include <unistd.h> #include <stdio.h> #include <stdint.h> #include <endian.h> #include <errno.h> #include <string.h>
#include "radiotap_iter.h"
// 根据wireshark抓包抽取的radiotap头部数据 char radiotap_buf[][18] = { {0x00, 0x00, 0x12, 0x00, 0x2e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x85, 0x09, 0xc0, 0x00, 0xc9, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x12, 0x00, 0x2e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x85, 0x09, 0xa0, 0x00, 0xa8, 0x00, 0x00, 0x00}, };
static void print_radiotap_namespace(struct ieee80211_radiotap_iterator *iter) { char signal = 0; uint32_t phy_freq = 0;
switch (iter->this_arg_index) { case IEEE80211_RADIOTAP_TSFT: printf("\tTSFT: %llu\n", le64toh(*(unsigned long long *)iter->this_arg)); break; case IEEE80211_RADIOTAP_FLAGS: printf("\tflags: %02x\n", *iter->this_arg); break; // 速率? case IEEE80211_RADIOTAP_RATE: printf("\trate: %.2f Mbit/s\n", (double)*iter->this_arg/2); break;
#define IEEE80211_CHAN_A \ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM) #define IEEE80211_CHAN_G \ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM) // 通信信息 case IEEE80211_RADIOTAP_CHANNEL: phy_freq = le16toh(*(uint16_t*)iter->this_arg); // 信道 iter->this_arg = iter->this_arg + 2; // 通道信息如2G、5G,等 int x = le16toh(*(uint16_t*)iter->this_arg); printf("\tfreq: %d type: ", phy_freq); if ((x & IEEE80211_CHAN_A) IEEE80211_CHAN_A) { printf("A\n"); } else if ((x & IEEE80211_CHAN_G) IEEE80211_CHAN_G) { printf("G\n"); } else if ((x & IEEE80211_CHAN_2GHZ) IEEE80211_CHAN_2GHZ) { printf("B\n"); } break; // 信号强度 case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: signal = *(signed char*)iter->this_arg; printf("\tsignal: %d dBm\n", signal); break; break; // 接收标志 case IEEE80211_RADIOTAP_RX_FLAGS: printf("\tRX flags: %#.4x\n", le16toh(*(uint16_t *)iter->this_arg)); break; case IEEE80211_RADIOTAP_ANTENNA: printf("\tantenna: %x\n", *iter->this_arg); break; // 忽略下面的 case IEEE80211_RADIOTAP_RTS_RETRIES: case IEEE80211_RADIOTAP_DATA_RETRIES: case IEEE80211_RADIOTAP_FHSS: case IEEE80211_RADIOTAP_DBM_ANTNOISE: case IEEE80211_RADIOTAP_LOCK_QUALITY: case IEEE80211_RADIOTAP_TX_ATTENUATION: case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: case IEEE80211_RADIOTAP_DBM_TX_POWER: case IEEE80211_RADIOTAP_DB_ANTSIGNAL: case IEEE80211_RADIOTAP_DB_ANTNOISE: case IEEE80211_RADIOTAP_TX_FLAGS: break; default: printf("\tBOGUS DATA\n"); break; } }
int main(void) { struct ieee80211_radiotap_iterator iter; int err; int i, j;
for (i = 0; i < sizeof(radiotap_buf)/sizeof(radiotap_buf[0]); i++) { printf("parsing [%d]\n", i); // 初始化 err = ieee80211_radiotap_iterator_init(&iter, (struct ieee80211_radiotap_header *)radiotap_buf[i], sizeof(radiotap_buf[i]), NULL); if (err) { printf("not valid radiotap...\n"); return -1; } j = 0; /** 遍历时,this_arg_index表示当前索引(如IEEE80211_RADIOTAP_TSFT等), this_arg表示当前索引的值,this_arg_size表示值的大小。 只有flag为true时才会进一步解析。 */ while (!(err = ieee80211_radiotap_iterator_next(&iter))) { printf("next[%d]: index: %d size: %d\n", j, iter.this_arg_index, iter.this_arg_size); if (iter.is_radiotap_ns) // 表示是radiotap的命名空间 { print_radiotap_namespace(&iter); } j++; } printf("\n"); }
return 0; }
|