Improved handling of 802.11 headers.

Frame types except data and frames subtypes without payload are skipped.
Header length is determined based on presence of QoS and flags
indicating the use of the 4th address field. Handling of aggregated
MSDUs is explicitly prevented.
This commit is contained in:
Jan Grashoefer 2016-06-14 17:52:34 +02:00
parent 151f9d6ced
commit 75849f8fe2

View file

@ -276,21 +276,33 @@ void Packet::ProcessLayer2()
} }
pdata += rtheader_len; pdata += rtheader_len;
u_char len_80211 = 0; u_char len_80211 = 0; // Frame header length
int type_80211 = pdata[0]; u_char fc_80211 = pdata[0]; // Frame Control field
if ( (type_80211 >> 4) & 0x04 ) // Skip non data frame types (management & control).
{ if ( !((fc_80211 >> 2) & 0x02) )
//identified a null frame (we ignore for now). no weird.
return; return;
}
len_80211 = 24; // minimal length of data frames
// Skip subtypes without data.
if ( (fc_80211 >> 4) & 0x04 )
return;
// 'To DS' and 'From DS' flags set indicate
// use of the 4th address field
if ( (pdata[1] & 0x03) == 0x03 )
len_80211 += l2_addr_len;
// Look for the QoS indicator bit. // Look for the QoS indicator bit.
if ( (fc_80211 >> 4) & 0x08 )
if ( (type_80211 >> 4) & 0x08 ) {
len_80211 = 26; // Skip in case of A-MSDU subframes
else // indicated by QoS control field
len_80211 = 24; if ( pdata[len_80211] & 0x80)
return;
len_80211 += 2;
}
if ( pdata + len_80211 >= end_of_data ) if ( pdata + len_80211 >= end_of_data )
{ {
@ -298,15 +310,12 @@ void Packet::ProcessLayer2()
return; return;
} }
// Look for data frames
if ( type_80211 & 0x08 )
{
// Determine link-layer addresses based // Determine link-layer addresses based
// on 'To DS' and 'From DS' flags // on 'To DS' and 'From DS' flags
switch ( pdata[1] & 0x03 ) { switch ( pdata[1] & 0x03 ) {
case 0x00: case 0x00:
l2_dst = pdata + 4;
l2_src = pdata + 10; l2_src = pdata + 10;
l2_dst = pdata + 4;
break; break;
case 0x01: case 0x01:
@ -320,17 +329,10 @@ void Packet::ProcessLayer2()
break; break;
case 0x03: case 0x03:
// TODO: We should integrate this
// test into the length check above.
if ( pdata + 24 + l2_addr_len >= end_of_data )
{
l2_dst = pdata + 16;
l2_src = pdata + 24; l2_src = pdata + 24;
} l2_dst = pdata + 16;
break; break;
} }
}
// skip 802.11 data header // skip 802.11 data header
pdata += len_80211; pdata += len_80211;