mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Add support for 802.11 A-MSDU aggregates
This commit is contained in:
parent
5b1c6216bd
commit
2d05beac06
8 changed files with 127 additions and 9 deletions
|
@ -3,6 +3,7 @@
|
|||
#include "zeek/TunnelEncapsulation.h"
|
||||
|
||||
#include "zeek/Conn.h"
|
||||
#include "zeek/Reporter.h"
|
||||
#include "zeek/util.h"
|
||||
|
||||
namespace zeek
|
||||
|
@ -56,4 +57,15 @@ bool operator==(const EncapsulationStack& e1, const EncapsulationStack& e2)
|
|||
return true;
|
||||
}
|
||||
|
||||
void EncapsulationStack::Pop()
|
||||
{
|
||||
if ( Depth() == 0 )
|
||||
{
|
||||
reporter->InternalWarning("Attempted to pop from empty EncapsulationStack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
conns->pop_back();
|
||||
}
|
||||
|
||||
} // namespace zeek
|
||||
|
|
|
@ -249,6 +249,11 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops the last element off the encapsulation stack.
|
||||
*/
|
||||
void Pop();
|
||||
|
||||
protected:
|
||||
std::vector<EncapsulatingConn>* conns;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
}
|
||||
|
||||
u_char fc_80211 = data[0]; // Frame Control field
|
||||
bool is_amsdu = false;
|
||||
|
||||
// Skip non-data frame types (management & control).
|
||||
if ( ! ((fc_80211 >> 2) & 0x02) )
|
||||
|
@ -33,9 +34,9 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
// 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;
|
||||
// Store off whether this is an A-MSDU header, which indicates that there are
|
||||
// mulitple packets following the 802.11 header.
|
||||
is_amsdu = (data[len_80211] & 0x80) == 0x80;
|
||||
|
||||
// Check for the protected bit. This means the data is encrypted and we can't
|
||||
// do anything with it.
|
||||
|
@ -75,13 +76,78 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
break;
|
||||
}
|
||||
|
||||
// skip 802.11 data header
|
||||
// skip the 802.11 data header
|
||||
data += len_80211;
|
||||
len -= len_80211;
|
||||
|
||||
len_80211 += 8;
|
||||
if ( len_80211 >= len )
|
||||
if ( ! is_amsdu )
|
||||
{
|
||||
Weird("truncated_802_11_header", packet);
|
||||
return HandleInnerPacket(len, data, packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t amsdu_padding = 0;
|
||||
size_t encap_index = packet->encap ? packet->encap->Depth() : 0;
|
||||
|
||||
while ( len > 0 )
|
||||
{
|
||||
if ( len < 14 )
|
||||
{
|
||||
Weird("truncated_802_11_amsdu_header", packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is the length of everything after the A-MSDU subframe header.
|
||||
size_t amsdu_len = (data[12] << 8) + data[13];
|
||||
if ( len < amsdu_len )
|
||||
{
|
||||
Weird("truncated_802_11_amsdu_packet", packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the A-MSDU subframe header. This should place us at the start of an LLC header.
|
||||
data += 14;
|
||||
len -= 14;
|
||||
|
||||
if ( ! HandleInnerPacket(amsdu_len, data, packet) )
|
||||
{
|
||||
Weird("invalid_802_11_amsdu_inner_packet", packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
data += amsdu_len;
|
||||
len -= amsdu_len;
|
||||
|
||||
// Each A-MSDU subframe is padded by up to 3 bytes to make a multiple of 4. This padding
|
||||
// isn't included in the length field value. The padding also doesn't happen with the
|
||||
// last subframe, so check to see that we can even subtract it. Unfortunately, there
|
||||
// isn't a frame counter in the header so we just have trust that it all works out.
|
||||
amsdu_padding = amsdu_len % 4;
|
||||
if ( len >= amsdu_padding )
|
||||
{
|
||||
data += amsdu_padding;
|
||||
len -= amsdu_padding;
|
||||
}
|
||||
|
||||
// Pop encapsuations back up to the level where we started processing so that the next
|
||||
// subframe gets the same encapsulation stack.
|
||||
if ( packet->encap )
|
||||
{
|
||||
while ( packet->encap->Depth() > encap_index )
|
||||
packet->encap->Pop();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool IEEE802_11Analyzer::HandleInnerPacket(size_t len, const uint8_t* data, Packet* packet) const
|
||||
{
|
||||
// Make sure there's room for an LLC header.
|
||||
if ( len < 8 )
|
||||
{
|
||||
Weird("truncated_802_11_llc_header", packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -92,6 +158,7 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
data[5] == 0 )
|
||||
{
|
||||
data += 6;
|
||||
len -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -100,11 +167,13 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
return false;
|
||||
}
|
||||
|
||||
// Get the protocol and skip the rest of the LLC header.
|
||||
uint32_t protocol = (data[0] << 8) + data[1];
|
||||
data += 2;
|
||||
len -= 2;
|
||||
|
||||
if ( packet->tunnel_type == BifEnum::Tunnel::NONE )
|
||||
return ForwardPacket(len - len_80211, data, packet, protocol);
|
||||
return ForwardPacket(len, data, packet, protocol);
|
||||
else
|
||||
{
|
||||
// For tunneled packets, reset the packet's protocol based on the one in the LLC header.
|
||||
|
@ -114,6 +183,6 @@ bool IEEE802_11Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet*
|
|||
else if ( protocol == 0x86DD )
|
||||
packet->proto = IPPROTO_IPV6;
|
||||
|
||||
return ForwardPacket(len - len_80211, data, packet, packet->proto);
|
||||
return ForwardPacket(len, data, packet, packet->proto);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
{
|
||||
return std::make_shared<IEEE802_11Analyzer>();
|
||||
}
|
||||
|
||||
private:
|
||||
bool HandleInnerPacket(size_t len, const uint8_t* data, Packet* packet) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
11
testing/btest/Baseline/core.tunnels.gre-aruba-amsdu/conn.log
Normal file
11
testing/btest/Baseline/core.tunnels.gre-aruba-amsdu/conn.log
Normal file
|
@ -0,0 +1,11 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path conn
|
||||
#open XXXX-XX-XX-XX-XX-XX
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
|
||||
#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string]
|
||||
XXXXXXXXXX.XXXXXX ClEkJM2Vm5giqnMf4h 157.240.18.16 443 149.159.130.184 49392 tcp - - - - OTH F F 0 D 2 356 0 0 CHhAvVGS1DHFjwGM9
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
|
@ -0,0 +1,11 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
#separator \x09
|
||||
#set_separator ,
|
||||
#empty_field (empty)
|
||||
#unset_field -
|
||||
#path tunnel
|
||||
#open XXXX-XX-XX-XX-XX-XX
|
||||
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p tunnel_type action
|
||||
#types time string addr port addr port enum enum
|
||||
XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 10.226.22.9 0 10.102.16.187 0 Tunnel::GRE Tunnel::DISCOVER
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
BIN
testing/btest/Traces/tunnels/gre-aruba-amsdu.pcap
Normal file
BIN
testing/btest/Traces/tunnels/gre-aruba-amsdu.pcap
Normal file
Binary file not shown.
7
testing/btest/core/tunnels/gre-aruba-amsdu.zeek
Normal file
7
testing/btest/core/tunnels/gre-aruba-amsdu.zeek
Normal file
|
@ -0,0 +1,7 @@
|
|||
# @TEST-DOC: Tests a GRE ARUBA trace that contains IEEE 802.11 QoS A-MSDU headers. This is testing that the tunnel is detected and that the conn byte size contains both A-MSDU subframe packets.
|
||||
# @TEST-EXEC: zeek -C -b -r $TRACES/tunnels/gre-aruba-amsdu.pcap %INPUT
|
||||
# @TEST-EXEC: btest-diff tunnel.log
|
||||
# @TEST-EXEC: btest-diff conn.log
|
||||
|
||||
@load base/protocols/conn
|
||||
@load base/frameworks/tunnels
|
Loading…
Add table
Add a link
Reference in a new issue