在Linux系统中使用wireshark或tcpdump抓取无线网卡数据包。每个数据帧前面都有一个叫做radiotap的协议头,里面包含信号强度、噪声强度、信道、时间戳等信息。Radiotap比传统的Prism或AVS头更灵活,成为IEEE802.11的事实标准。支持radiotap的系统有很多,比如Linux、FreeBSD、NetBSD、OpenBSD、Windows(需要使用AirPcap)。它的头部定义如下:structieee80211_radiotap_header{u_int8_tit_version;/*设置为0*/u_int8_tit_pad;u_int16_tit_len;/*整个长度*/u_int32_tit_present;/*存在的字段*/}__attribute__((__it_version));:表示版本号,目前为0。it_pad:未使用,仅用于结构对齐。it_len:表示长度,包括radiotap头和数据。如果不需要了解radiotap,可以直接跳到ieee802.11header。it_present:表示radiotap数据的位掩码。radiotap的数据跟在它的头部之后。当位掩码为真时,表示有对应的数据,可以认为每一位代表一种类型。例如bit5为1,表示有信道数据,可以获取信号强度;否则,没有相应的数据。因此,radiotap的长度实际上是不固定的。如果bit31为1,表示有多个it_presents。每一种radiotap都有严格的顺序,数据的字序是littleendian格式(littleendianbyte-order)——包括header中的it_len和it_present。目前广泛使用的分析库是radiotap-library,在horst软件和Linux内核中都有使用。对于每种类型的解释,请参考radiotap.h文件中的ieee80211_radiotap_type注释。设置Ubuntu系统进入监控模式,方法如下:$sudoiwdevwlp5s0interfaceaddmon0typemonitor$sudoiwdevwlp5s0del$sudoiwdevmon0setchannel6$sudoifconfigmon0up然后使用tcpdump抓包:$sudotcpdump-imon0-wtest.pcaptcpdump:listeningonmon0,link-typeIEEE802_11_RADIO(802.11plusradiotapheader),capturesize262144bytes^C2288packetscaptured2344packetsreceivedbyfilter0packetsdroppedbykernel5edwpacketsanalysis收到的包,作为如下图所示:使用radiotap-library库进行分析,示例代码如下:#include#include#include#include#include#include#include"radiotap_iter.h"//radiotap头数据charradiotap_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,0x0x00,0x02,0x85,0x09,0xa0,0x00,0xa8,0x00,0x00,0x00}};#defineIEEE80211_CHAN_A(IEEE80211_CHAN_5GHZ|IEEE80211_CHAN_OFDM)#defineIEEE80211_CHAN_G(IEEE80211_CHAN_2GHZ|IEEE80211_CHAN_OFDM)staticvoidprint_radiotap_namespace(structieee80211_radiotap_iterator*iter){charsignal=0;uint32_tphy_freq=0;switch(iter->this_arg_index){caseIEEE80211_RADIOTAP_TSFT:printf("\tTSFT:%llu\n",le64toh(*(unsignedlonglong*)iter->this_arg));休息;caseIEEE80211_RADIOTAP_FLAGS:printf("\tflags:%02x\n",*iter->this_arg);休息;caseIEEE80211_RADIOTAP_RATE:printf("\trate:%.2fMbit/s\n",(double)*iter->this_arg/2);休息;案例IEEE80211_RADIOTAP_CHANNEL:phy_freq=le16toh(*(uint16_t*)iter->this_arg);//信道iter->this_arg=iter->this_arg+2;//通信信息如2G、5G,等intx=le16toh(*(uint16_t*)iter->this_arg);打印函数("\tfreq:%dtype:",phy_freq);如果((x&IEEE80211_CHAN_A)==IEEE80211_CHAN_A){printf("A\n");}elseif((x&IEEE80211_CHAN_G)==IEEE80211_CHAN_G){printf("G\n");}elseif((x&IEEE80211_CHAN_2GHZ)==IEEE80211_CHAN_2GHZ){printf("B\n");}休息;caseIEEE80211_RADIOTAP_DBM_ANTSIGNAL:signal=*(signedchar*)iter->this_arg;printf("\t信号:%ddBm\n",信号);休息;caseIEEE80211_RADIOTAP_RX_FLAGS:printf("\tRX标志:%#.4x\n",le16toh(*(uint16_t*)iter->this_arg));休息;案例IEEE80211_RADIOTAP_ANTENNA:printf("\tantenna:%x\n",*iter->this_arg);休息;案例IEEE80211_RADIOTAP_RTS_RETRIES:案例IEEE80211_RADIOTAP_DATA_RETRIES:案例IEEE80211_RADIOTAP_FHSS:案例IEEE80211_RADIOTAP_DBM_ANTNOISE:案例IEEE80211_RADIOTAP_LOCK_QUALITY:案例IEEE80211_RADIOTAP_TX_ATNUATION:案例IEEE80211_RADIOTAP_DB_TX_ATTENUATION:案例IEEE80211_RADIOTAP_DBM_TX_POWER:案例IEEE80211_RADIOTAP_DB_ANTSIGNAL:案例IEEE80211_RADIOTAP_DB_ANTNOISE:案例IEEE80211_RADIOTAP_TX_FLAGS:中断;默认值:printf("\t虚假数据\n");休息;}}intmain(intargc,char**argv){结构ieee80211_radiotap_iteratoriter;内部错误;诠释我,j;for(i=0;i