mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 14:08:20 +00:00
111 lines
2.4 KiB
C++
111 lines
2.4 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#include "IEEE802_11.h"
|
|
#include "NetVar.h"
|
|
|
|
using namespace zeek::packet_analysis::IEEE802_11;
|
|
|
|
IEEE802_11Analyzer::IEEE802_11Analyzer()
|
|
: zeek::packet_analysis::Analyzer("IEEE802_11")
|
|
{
|
|
}
|
|
|
|
bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)
|
|
{
|
|
u_char len_80211 = 24; // minimal length of data frames
|
|
|
|
if ( len_80211 >= len )
|
|
{
|
|
packet->Weird("truncated_802_11_header");
|
|
return false;
|
|
}
|
|
|
|
u_char fc_80211 = data[0]; // Frame Control field
|
|
|
|
// Skip non-data frame types (management & control).
|
|
if ( ! ((fc_80211 >> 2) & 0x02) )
|
|
return false;
|
|
|
|
// Skip subtypes without data.
|
|
if ( (fc_80211 >> 4) & 0x04 )
|
|
return false;
|
|
|
|
// 'To DS' and 'From DS' flags set indicate use of the 4th
|
|
// address field.
|
|
if ( (data[1] & 0x03) == 0x03 )
|
|
len_80211 += packet->L2_ADDR_LEN;
|
|
|
|
// Look for the QoS indicator bit.
|
|
if ( (fc_80211 >> 4) & 0x08 )
|
|
{
|
|
// Skip in case of A-MSDU subframes indicated by QoS
|
|
// control field.
|
|
if ( data[len_80211] & 0x80 )
|
|
return false;
|
|
|
|
len_80211 += 2;
|
|
}
|
|
|
|
if ( len_80211 >= len )
|
|
{
|
|
packet->Weird("truncated_802_11_header");
|
|
return false;
|
|
}
|
|
|
|
// Determine link-layer addresses based
|
|
// on 'To DS' and 'From DS' flags
|
|
switch ( data[1] & 0x03 )
|
|
{
|
|
case 0x00:
|
|
packet->l2_src = data + 10;
|
|
packet->l2_dst = data + 4;
|
|
break;
|
|
|
|
case 0x01:
|
|
packet->l2_src = data + 10;
|
|
packet->l2_dst = data + 16;
|
|
break;
|
|
|
|
case 0x02:
|
|
packet->l2_src = data + 16;
|
|
packet->l2_dst = data + 4;
|
|
break;
|
|
|
|
case 0x03:
|
|
packet->l2_src = data + 24;
|
|
packet->l2_dst = data + 16;
|
|
break;
|
|
}
|
|
|
|
// skip 802.11 data header
|
|
data += len_80211;
|
|
|
|
len_80211 += 8;
|
|
if ( len_80211 >= len )
|
|
{
|
|
packet->Weird("truncated_802_11_header");
|
|
return false;
|
|
}
|
|
|
|
// Check that the DSAP and SSAP are both SNAP and that the control
|
|
// field indicates that this is an unnumbered frame.
|
|
// The organization code (24bits) needs to also be zero to
|
|
// indicate that this is encapsulated ethernet.
|
|
if ( data[0] == 0xAA && data[1] == 0xAA && data[2] == 0x03 &&
|
|
data[3] == 0 && data[4] == 0 && data[5] == 0 )
|
|
{
|
|
data += 6;
|
|
}
|
|
else
|
|
{
|
|
// If this is a logical link control frame without the
|
|
// possibility of having a protocol we care about, we'll
|
|
// just skip it for now.
|
|
return false;
|
|
}
|
|
|
|
uint32_t protocol = (data[0] << 8) + data[1];
|
|
data += 2;
|
|
|
|
return ForwardPacket(len - len_80211, data, packet, protocol);
|
|
}
|