我建议你仔细研究这个页面:http ://www.radiotap.org/Radiotap
标头的it_present
字段指示标头后面的字段。存在的字段按其位数从低到高排列。因此,例如,如果第一个非零位it_present
是第 3 位,则标题后面的第一个字段将是通道。
该协议相当复杂,必须遵守许多规则。例如,如果it_present
设置了第 31 位,那么首先会有更多的存在位,而不是紧跟在标头之后的字段。您还必须注意字段的对齐方式。字段之间可能存在填充,以便 32 位字段在 4 字节边界上对齐,64 位字段在 8 字节边界上对齐,依此类推。
编辑:让我们假设它packet
指向 radiotap 标头的开头,即pkt_len
字节数。你可以这样开始:
pkt_len = hdr.length;
if ( pkt_len >= sizeof(ieee80211_radiotap_header) )
{
u_int16_t it_len;
u_int32_t it_present;
u_int32_t tmpMask;
u_int32_t* pExtraMask;
u_int32_t* pNextMask;
u_int32_t uMask;
int iFldNum;
ieee80211_radiotap_header* pPktHdr = (ieee80211_radiotap_header*) packet;
pkt_len -= sizeof(ieee80211_radiotap_header);
packet += sizeof(ieee80211_radiotap_header);
it_len = le16_to_cpu(pPktHdr->it_len); // Get radiotap packet length from header
it_present = le32_to_cpu(pPktHdr->it_present); // Get present field bitmask
// Find end of radiotap header
tmpMask = it_present;
pExtraMask = pNextMask = (u_int32_t*) packet;
while ( (tmpMask & 0x80000000) && (pkt_len >= sizeof(u_int32_t)) )
{
tmpMask = le32_to_cpu(*pNextMask++);
pkt_len -= sizeof(u_int32_t);
packet += sizeof(u_int32_t);
}
// packet should now point to the first field
for ( iFldNum = 0, uMask = 1; (iFldNum < 31) && pkt_len; ++iFldNum, uMask <<= 1 )
{
if ( (it_present & uMask) )
{
u_int16_t uFldLen;
// We have a non-zero bit in the mask, iFldNum is the field number
// Call function to extract the field at packet and return number of bytes used
// process_field() is responsible for data alignment and preventing buffer overrun
uFldLen = process_field(packet, pkt_len, iFldNum);
pkt_len -= uFldLen;
packet += uFldLen;
}
}
// Here you would check if it_present had bit 31 set
// If so, process additional masks starting at pExtraMask
}
如您所见,它可能会有点毛茸茸。