Move cur_pos from packet into packet manager loop.

This commit is contained in:
Jan Grashoefer 2020-07-17 18:25:22 +02:00 committed by Tim Wojtulewicz
parent c2500d03d6
commit 96d0e11bb8
39 changed files with 148 additions and 169 deletions

View file

@ -59,17 +59,12 @@ void Packet::Init(int arg_link_type, pkt_timeval *arg_ts, uint32_t arg_caplen,
l3_proto = L3_UNKNOWN; l3_proto = L3_UNKNOWN;
l3_checksummed = false; l3_checksummed = false;
// For packet analyzer: cur_pos points to the next payload.
cur_pos = data;
if ( data ) if ( data )
{ {
// From here we assume that layer 2 is valid. If a packet analyzer encounters // From here we assume that layer 2 is valid. If a packet analyzer encounters
// an issue, it will call Packet::Weird(), which sets l2_valid to false. // an issue, it will call Packet::Weird(), which sets l2_valid to false.
l2_valid = true; l2_valid = true;
packet_mgr->ProcessPacket(this); packet_mgr->ProcessPacket(this);
// Calculate header size after processing lower layers.
hdr_size = cur_pos - data;
} }
} }

View file

@ -159,8 +159,8 @@ public:
/** /**
* Empty layer 2 address to be used as default value. For example, the * Empty layer 2 address to be used as default value. For example, the
* LinuxSLL llanalyzer doesn't have a destination address in the header * LinuxSLL packet analyzer doesn't have a destination address in the
* and thus sets it to this default address. * header and thus sets it to this default address.
*/ */
static constexpr const u_char L2_EMPTY_ADDR[L2_ADDR_LEN] = { 0 }; static constexpr const u_char L2_EMPTY_ADDR[L2_ADDR_LEN] = { 0 };
@ -172,7 +172,6 @@ public:
uint32_t len; /// Actual length on wire uint32_t len; /// Actual length on wire
uint32_t cap_len; /// Captured packet length uint32_t cap_len; /// Captured packet length
uint32_t link_type; /// pcap link_type (DLT_EN10MB, DLT_RAW, etc) uint32_t link_type; /// pcap link_type (DLT_EN10MB, DLT_RAW, etc)
const uint8_t* cur_pos; /// Pointer to the current start of unanalyzed payload data in the raw packet, used by llanalyzers
// These are computed from Layer 2 data. These fields are only valid if // These are computed from Layer 2 data. These fields are only valid if
// Layer2Valid() returns true. // Layer2Valid() returns true.

View file

@ -63,18 +63,19 @@ public:
bool IsAnalyzer(const char* name); bool IsAnalyzer(const char* name);
/** /**
* Analyzes the given packet. The analysis is supposed to start at cur_pos * Analyzes the given packet. The data reference points to the part of the
* of the packet, which points to the so far unanalyzed part of the packet. * raw packet to be analyzed. If the analyzed protocol encapsulates another
* If the analyzed protocol encapsulates another protocol, the packet's * protocol, the data reference should be updated to point to that payload.
* cur_pos should be updated to point to that payload.
* *
* @param packet The packet to analyze. * @param packet The packet to analyze.
* *
* @param data Reference to the payload pointer into the raw packet.
*
* @return A tuple of analysis result and identifier. The result indicates * @return A tuple of analysis result and identifier. The result indicates
* how to proceed. If analysis can continue, the identifier determines the * how to proceed. If analysis can continue, the identifier determines the
* encapsulated protocol. * encapsulated protocol.
*/ */
virtual AnalysisResultTuple Analyze(Packet* packet) = 0; virtual AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) = 0;
protected: protected:
friend class Manager; friend class Manager;

View file

@ -150,6 +150,7 @@ void Manager::ProcessPacket(Packet* packet)
// Dispatch and analyze layers // Dispatch and analyze layers
AnalyzerResult result = AnalyzerResult::Continue; AnalyzerResult result = AnalyzerResult::Continue;
uint32_t next_layer_id = packet->link_type; uint32_t next_layer_id = packet->link_type;
const uint8_t* data = packet->data;
do do
{ {
auto current_analyzer = Dispatch(next_layer_id); auto current_analyzer = Dispatch(next_layer_id);
@ -163,7 +164,7 @@ void Manager::ProcessPacket(Packet* packet)
} }
// Analyze this layer and get identifier of next layer protocol // Analyze this layer and get identifier of next layer protocol
std::tie(result, next_layer_id) = current_analyzer->Analyze(packet); std::tie(result, next_layer_id) = current_analyzer->Analyze(packet, data);
#ifdef DEBUG #ifdef DEBUG
switch ( result ) switch ( result )
@ -183,28 +184,29 @@ void Manager::ProcessPacket(Packet* packet)
} while ( result == AnalyzerResult::Continue ); } while ( result == AnalyzerResult::Continue );
if ( result == AnalyzerResult::Terminate ) if ( result == AnalyzerResult::Terminate )
CustomEncapsulationSkip(packet); CustomEncapsulationSkip(packet, data);
// Processing finished, reset analyzer set state for next packet // Processing finished, reset analyzer set state for next packet
current_state = root_dispatcher; current_state = root_dispatcher;
// Calculate header size after processing packet layers.
packet->hdr_size = data - packet->data;
} }
void Manager::CustomEncapsulationSkip(Packet* packet) void Manager::CustomEncapsulationSkip(Packet* packet, const uint8_t* data)
{ {
if ( zeek::detail::encap_hdr_size > 0 ) if ( zeek::detail::encap_hdr_size > 0 )
{ {
auto pdata = packet->cur_pos;
// Blanket encapsulation. We assume that what remains is IP. // Blanket encapsulation. We assume that what remains is IP.
if ( pdata + zeek::detail::encap_hdr_size + sizeof(struct ip) >= packet->GetEndOfData() ) if ( data + zeek::detail::encap_hdr_size + sizeof(struct ip) >= packet->GetEndOfData() )
{ {
packet->Weird("no_ip_left_after_encap"); packet->Weird("no_ip_left_after_encap");
return; return;
} }
pdata += zeek::detail::encap_hdr_size; data += zeek::detail::encap_hdr_size;
auto ip = (const struct ip*)pdata; auto ip = (const struct ip*)data;
switch ( ip->ip_v ) switch ( ip->ip_v )
{ {

View file

@ -94,8 +94,10 @@ private:
* It is assumed that an IP header follows. * It is assumed that an IP header follows.
* *
* @param packet The packet to adapt. * @param packet The packet to adapt.
*
* @param data Pointer to remaining payload.
*/ */
void CustomEncapsulationSkip(Packet* packet); void CustomEncapsulationSkip(Packet* packet, const uint8_t* data);
AnalyzerPtr Dispatch(uint32_t identifier); AnalyzerPtr Dispatch(uint32_t identifier);

View file

@ -9,7 +9,7 @@ ARPAnalyzer::ARPAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple ARPAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple ARPAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
// TODO: Make ARP analyzer a native packet analyzer // TODO: Make ARP analyzer a native packet analyzer
packet->l3_proto = L3_ARP; packet->l3_proto = L3_ARP;

View file

@ -12,7 +12,7 @@ public:
ARPAnalyzer(); ARPAnalyzer();
~ARPAnalyzer() override = default; ~ARPAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,18 +10,16 @@ DefaultAnalyzer::DefaultAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple DefaultAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple DefaultAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
// Assume we're pointing at IP. Just figure out which version. // Assume we're pointing at IP. Just figure out which version.
if ( pdata + sizeof(struct ip) >= packet->GetEndOfData() ) if ( data + sizeof(struct ip) >= packet->GetEndOfData() )
{ {
packet->Weird("packet_analyzer_truncated_header"); packet->Weird("packet_analyzer_truncated_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
auto ip = (const struct ip *)pdata; auto ip = (const struct ip *)data;
uint32_t protocol = ip->ip_v; uint32_t protocol = ip->ip_v;
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };

View file

@ -12,7 +12,7 @@ public:
DefaultAnalyzer(); DefaultAnalyzer();
~DefaultAnalyzer() override = default; ~DefaultAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,51 +10,50 @@ EthernetAnalyzer::EthernetAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
// Make sure that we actually got an entire ethernet header before trying // Make sure that we actually got an entire ethernet header before trying
// to pull bytes out of it. // to pull bytes out of it.
if ( pdata + 16 >= end_of_data ) if ( data + 16 >= end_of_data )
{ {
packet->Weird("truncated_ethernet_frame"); packet->Weird("truncated_ethernet_frame");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
// Skip past Cisco FabricPath to encapsulated ethernet frame. // Skip past Cisco FabricPath to encapsulated ethernet frame.
if ( pdata[12] == 0x89 && pdata[13] == 0x03 ) if ( data[12] == 0x89 && data[13] == 0x03 )
{ {
auto constexpr cfplen = 16; auto constexpr cfplen = 16;
if ( pdata + cfplen + 14 >= end_of_data ) if ( data + cfplen + 14 >= end_of_data )
{ {
packet->Weird("truncated_link_header_cfp"); packet->Weird("truncated_link_header_cfp");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
pdata += cfplen; data += cfplen;
} }
// Get protocol being carried from the ethernet frame. // Get protocol being carried from the ethernet frame.
uint32_t protocol = (pdata[12] << 8) + pdata[13]; uint32_t protocol = (data[12] << 8) + data[13];
packet->eth_type = protocol; packet->eth_type = protocol;
packet->l2_dst = pdata; packet->l2_dst = data;
packet->l2_src = pdata + 6; packet->l2_src = data + 6;
// Ethernet II frames // Ethernet II frames
if ( protocol >= 1536 ) if ( protocol >= 1536 )
{ {
pdata += 14; data += 14;
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }
// Other ethernet frame types // Other ethernet frame types
if ( protocol <= 1500 ) if ( protocol <= 1500 )
{ {
if ( pdata + 16 >= end_of_data ) if ( data + 16 >= end_of_data )
{ {
packet->Weird("truncated_ethernet_frame"); packet->Weird("truncated_ethernet_frame");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
@ -65,11 +64,11 @@ zeek::packet_analysis::AnalysisResultTuple EthernetAnalyzer::Analyze(Packet* pac
// Note that pdata remains at the start of the ethernet frame. // Note that pdata remains at the start of the ethernet frame.
// IEEE 802.2 SNAP // IEEE 802.2 SNAP
if ( pdata[14] == 0xAA && pdata[15] == 0xAA) if ( data[14] == 0xAA && data[15] == 0xAA)
return { AnalyzerResult::Continue, 1502 }; return { AnalyzerResult::Continue, 1502 };
// Novell raw IEEE 802.3 // Novell raw IEEE 802.3
if ( pdata[14] == 0xFF && pdata[15] == 0xFF) if ( data[14] == 0xFF && data[15] == 0xFF)
return { AnalyzerResult::Continue, 1503 }; return { AnalyzerResult::Continue, 1503 };

View file

@ -12,7 +12,7 @@ public:
EthernetAnalyzer(); EthernetAnalyzer();
~EthernetAnalyzer() override = default; ~EthernetAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,18 +10,17 @@ FDDIAnalyzer::FDDIAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple FDDIAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple FDDIAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
auto hdr_size = 13 + 8; // FDDI header + LLC auto hdr_size = 13 + 8; // FDDI header + LLC
if ( pdata + hdr_size >= packet->GetEndOfData() ) if ( data + hdr_size >= packet->GetEndOfData() )
{ {
packet->Weird("FDDI_analyzer_failed"); packet->Weird("FDDI_analyzer_failed");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
// We just skip the header and hope for default analysis // We just skip the header and hope for default analysis
pdata += hdr_size; data += hdr_size;
return { AnalyzerResult::Continue, -1 }; return { AnalyzerResult::Continue, -1 };
} }

View file

@ -12,7 +12,7 @@ public:
FDDIAnalyzer(); FDDIAnalyzer();
~FDDIAnalyzer() override = default; ~FDDIAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,20 +10,19 @@ IEEE802_11Analyzer::IEEE802_11Analyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
u_char len_80211 = 24; // minimal length of data frames u_char len_80211 = 24; // minimal length of data frames
if ( pdata + len_80211 >= end_of_data ) if ( data + len_80211 >= end_of_data )
{ {
packet->Weird("truncated_802_11_header"); packet->Weird("truncated_802_11_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
u_char fc_80211 = pdata[0]; // Frame Control field u_char fc_80211 = data[0]; // Frame Control field
// Skip non-data frame types (management & control). // Skip non-data frame types (management & control).
if ( ! ((fc_80211 >> 2) & 0x02) ) if ( ! ((fc_80211 >> 2) & 0x02) )
@ -35,7 +34,7 @@ zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* p
// 'To DS' and 'From DS' flags set indicate use of the 4th // 'To DS' and 'From DS' flags set indicate use of the 4th
// address field. // address field.
if ( (pdata[1] & 0x03) == 0x03 ) if ( (data[1] & 0x03) == 0x03 )
len_80211 += packet->L2_ADDR_LEN; len_80211 += packet->L2_ADDR_LEN;
// Look for the QoS indicator bit. // Look for the QoS indicator bit.
@ -43,13 +42,13 @@ zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* p
{ {
// Skip in case of A-MSDU subframes indicated by QoS // Skip in case of A-MSDU subframes indicated by QoS
// control field. // control field.
if ( pdata[len_80211] & 0x80 ) if ( data[len_80211] & 0x80 )
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
len_80211 += 2; len_80211 += 2;
} }
if ( pdata + len_80211 >= end_of_data ) if ( data + len_80211 >= end_of_data )
{ {
packet->Weird("truncated_802_11_header"); packet->Weird("truncated_802_11_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
@ -57,33 +56,33 @@ zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* p
// 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 ( data[1] & 0x03 )
{ {
case 0x00: case 0x00:
packet->l2_src = pdata + 10; packet->l2_src = data + 10;
packet->l2_dst = pdata + 4; packet->l2_dst = data + 4;
break; break;
case 0x01: case 0x01:
packet->l2_src = pdata + 10; packet->l2_src = data + 10;
packet->l2_dst = pdata + 16; packet->l2_dst = data + 16;
break; break;
case 0x02: case 0x02:
packet->l2_src = pdata + 16; packet->l2_src = data + 16;
packet->l2_dst = pdata + 4; packet->l2_dst = data + 4;
break; break;
case 0x03: case 0x03:
packet->l2_src = pdata + 24; packet->l2_src = data + 24;
packet->l2_dst = pdata + 16; packet->l2_dst = data + 16;
break; break;
} }
// skip 802.11 data header // skip 802.11 data header
pdata += len_80211; data += len_80211;
if ( pdata + 8 >= end_of_data ) if ( data + 8 >= end_of_data )
{ {
packet->Weird("truncated_802_11_header"); packet->Weird("truncated_802_11_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
@ -93,10 +92,10 @@ zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* p
// field indicates that this is an unnumbered frame. // field indicates that this is an unnumbered frame.
// The organization code (24bits) needs to also be zero to // The organization code (24bits) needs to also be zero to
// indicate that this is encapsulated ethernet. // indicate that this is encapsulated ethernet.
if ( pdata[0] == 0xAA && pdata[1] == 0xAA && pdata[2] == 0x03 && if ( data[0] == 0xAA && data[1] == 0xAA && data[2] == 0x03 &&
pdata[3] == 0 && pdata[4] == 0 && pdata[5] == 0 ) data[3] == 0 && data[4] == 0 && data[5] == 0 )
{ {
pdata += 6; data += 6;
} }
else else
{ {
@ -106,8 +105,8 @@ zeek::packet_analysis::AnalysisResultTuple IEEE802_11Analyzer::Analyze(Packet* p
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
uint32_t protocol = (pdata[0] << 8) + pdata[1]; uint32_t protocol = (data[0] << 8) + data[1];
pdata += 2; data += 2;
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
IEEE802_11Analyzer(); IEEE802_11Analyzer();
~IEEE802_11Analyzer() override = default; ~IEEE802_11Analyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -12,27 +12,26 @@ IEEE802_11_RadioAnalyzer::IEEE802_11_RadioAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple IEEE802_11_RadioAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple IEEE802_11_RadioAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
if ( pdata + 3 >= end_of_data ) if ( data + 3 >= end_of_data )
{ {
packet->Weird("truncated_radiotap_header"); packet->Weird("truncated_radiotap_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
// Skip over the RadioTap header // Skip over the RadioTap header
int rtheader_len = (pdata[3] << 8) + pdata[2]; int rtheader_len = (data[3] << 8) + data[2];
if ( pdata + rtheader_len >= end_of_data ) if ( data + rtheader_len >= end_of_data )
{ {
packet->Weird("truncated_radiotap_header"); packet->Weird("truncated_radiotap_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
packet->cur_pos += rtheader_len; data += rtheader_len;
return { AnalyzerResult::Continue, DLT_IEEE802_11 }; return { AnalyzerResult::Continue, DLT_IEEE802_11 };
} }

View file

@ -12,7 +12,7 @@ public:
IEEE802_11_RadioAnalyzer(); IEEE802_11_RadioAnalyzer();
~IEEE802_11_RadioAnalyzer() override = default; ~IEEE802_11_RadioAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -9,7 +9,7 @@ IPv4Analyzer::IPv4Analyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple IPv4Analyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple IPv4Analyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
packet->l3_proto = L3_IPV4; packet->l3_proto = L3_IPV4;

View file

@ -12,7 +12,7 @@ public:
IPv4Analyzer(); IPv4Analyzer();
~IPv4Analyzer() override = default; ~IPv4Analyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -9,7 +9,7 @@ IPv6Analyzer::IPv6Analyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple IPv6Analyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple IPv6Analyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
packet->l3_proto = L3_IPV6; packet->l3_proto = L3_IPV6;

View file

@ -12,7 +12,7 @@ public:
IPv6Analyzer(); IPv6Analyzer();
~IPv6Analyzer() override = default; ~IPv6Analyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static AnalyzerPtr Instantiate() static AnalyzerPtr Instantiate()
{ {

View file

@ -9,18 +9,16 @@ LinuxSLLAnalyzer::LinuxSLLAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple LinuxSLLAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple LinuxSLLAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos; if ( data + sizeof(SLLHeader) >= packet->GetEndOfData() )
if ( pdata + sizeof(SLLHeader) >= packet->GetEndOfData() )
{ {
packet->Weird("truncated_Linux_SLL_header"); packet->Weird("truncated_Linux_SLL_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
//TODO: Handle different ARPHRD_types //TODO: Handle different ARPHRD_types
auto hdr = (const SLLHeader*)pdata; auto hdr = (const SLLHeader*)data;
uint32_t protocol = ntohs(hdr->protocol_type); uint32_t protocol = ntohs(hdr->protocol_type);
packet->l2_src = (u_char*) &(hdr->addr); packet->l2_src = (u_char*) &(hdr->addr);
@ -29,6 +27,6 @@ zeek::packet_analysis::AnalysisResultTuple LinuxSLLAnalyzer::Analyze(Packet* pac
// here will cause crashes elsewhere. // here will cause crashes elsewhere.
packet->l2_dst = Packet::L2_EMPTY_ADDR; packet->l2_dst = Packet::L2_EMPTY_ADDR;
pdata += sizeof(SLLHeader); data += sizeof(SLLHeader);
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
LinuxSLLAnalyzer(); LinuxSLLAnalyzer();
~LinuxSLLAnalyzer() override = default; ~LinuxSLLAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -9,9 +9,8 @@ MPLSAnalyzer::MPLSAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple MPLSAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple MPLSAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
// Skip the MPLS label stack. // Skip the MPLS label stack.
@ -19,25 +18,25 @@ zeek::packet_analysis::AnalysisResultTuple MPLSAnalyzer::Analyze(Packet* packet)
while ( ! end_of_stack ) while ( ! end_of_stack )
{ {
if ( pdata + 4 >= end_of_data ) if ( data + 4 >= end_of_data )
{ {
packet->Weird("truncated_link_header"); packet->Weird("truncated_link_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
end_of_stack = *(pdata + 2u) & 0x01; end_of_stack = *(data + 2u) & 0x01;
pdata += 4; data += 4;
} }
// According to RFC3032 the encapsulated protocol is not encoded. // According to RFC3032 the encapsulated protocol is not encoded.
// We assume that what remains is IP. // We assume that what remains is IP.
if ( pdata + sizeof(struct ip) >= end_of_data ) if ( data + sizeof(struct ip) >= end_of_data )
{ {
packet->Weird("no_ip_in_mpls_payload"); packet->Weird("no_ip_in_mpls_payload");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
auto ip = (const struct ip*)pdata; auto ip = (const struct ip*)data;
if ( ip->ip_v == 4 ) if ( ip->ip_v == 4 )
packet->l3_proto = L3_IPV4; packet->l3_proto = L3_IPV4;
@ -50,6 +49,6 @@ zeek::packet_analysis::AnalysisResultTuple MPLSAnalyzer::Analyze(Packet* packet)
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
packet->hdr_size = (pdata - packet->data); packet->hdr_size = (data - packet->data);
return { AnalyzerResult::Terminate, 0 }; return { AnalyzerResult::Terminate, 0 };
} }

View file

@ -12,7 +12,7 @@ public:
MPLSAnalyzer(); MPLSAnalyzer();
~MPLSAnalyzer() override = default; ~MPLSAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,13 +10,12 @@ NFLogAnalyzer::NFLogAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple NFLogAnalyzer::Analyze(Packet* packet) { zeek::packet_analysis::AnalysisResultTuple NFLogAnalyzer::Analyze(Packet* packet, const uint8_t*& data) {
auto& pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
// See https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html // See https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
uint32_t protocol = pdata[0]; uint32_t protocol = data[0];
uint8_t version = pdata[1]; uint8_t version = data[1];
if ( version != 0 ) if ( version != 0 )
{ {
@ -25,14 +24,14 @@ zeek::packet_analysis::AnalysisResultTuple NFLogAnalyzer::Analyze(Packet* packet
} }
// Skip to TLVs. // Skip to TLVs.
pdata += 4; data += 4;
uint16_t tlv_len; uint16_t tlv_len;
uint16_t tlv_type; uint16_t tlv_type;
while ( true ) while ( true )
{ {
if ( pdata + 4 >= end_of_data ) if ( data + 4 >= end_of_data )
{ {
packet->Weird("nflog_no_pcap_payload"); packet->Weird("nflog_no_pcap_payload");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
@ -41,15 +40,15 @@ zeek::packet_analysis::AnalysisResultTuple NFLogAnalyzer::Analyze(Packet* packet
// TLV Type and Length values are specified in host byte order // TLV Type and Length values are specified in host byte order
// (libpcap should have done any needed byteswapping already). // (libpcap should have done any needed byteswapping already).
tlv_len = *(reinterpret_cast<const uint16_t*>(pdata)); tlv_len = *(reinterpret_cast<const uint16_t*>(data));
tlv_type = *(reinterpret_cast<const uint16_t*>(pdata + 2)); tlv_type = *(reinterpret_cast<const uint16_t*>(data + 2));
auto constexpr nflog_type_payload = 9; auto constexpr nflog_type_payload = 9;
if ( tlv_type == nflog_type_payload ) if ( tlv_type == nflog_type_payload )
{ {
// The raw packet payload follows this TLV. // The raw packet payload follows this TLV.
pdata += 4; data += 4;
break; break;
} }
else else
@ -72,7 +71,7 @@ zeek::packet_analysis::AnalysisResultTuple NFLogAnalyzer::Analyze(Packet* packet
tlv_len += 4 - rem; tlv_len += 4 - rem;
} }
pdata += tlv_len; data += tlv_len;
} }
} }

View file

@ -12,7 +12,7 @@ public:
NFLogAnalyzer(); NFLogAnalyzer();
~NFLogAnalyzer() override = default; ~NFLogAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static AnalyzerPtr Instantiate() static AnalyzerPtr Instantiate()
{ {

View file

@ -10,18 +10,16 @@ NullAnalyzer::NullAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple NullAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple NullAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos; if ( data + 4 >= packet->GetEndOfData() )
if ( pdata + 4 >= packet->GetEndOfData() )
{ {
packet->Weird("null_analyzer_failed"); packet->Weird("null_analyzer_failed");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
uint32_t protocol = (pdata[3] << 24) + (pdata[2] << 16) + (pdata[1] << 8) + pdata[0]; uint32_t protocol = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0];
pdata += 4; // skip link header data += 4; // skip link header
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
NullAnalyzer(); NullAnalyzer();
~NullAnalyzer() override = default; ~NullAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,13 +10,11 @@ PPPSerialAnalyzer::PPPSerialAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple PPPSerialAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple PPPSerialAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
// Extract protocol identifier // Extract protocol identifier
uint32_t protocol = (pdata[2] << 8) + pdata[3]; uint32_t protocol = (data[2] << 8) + data[3];
pdata += 4; // skip link header data += 4; // skip link header
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
PPPSerialAnalyzer(); PPPSerialAnalyzer();
~PPPSerialAnalyzer() override = default; ~PPPSerialAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,19 +10,17 @@ PPPoEAnalyzer::PPPoEAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple PPPoEAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple PPPoEAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos; if ( data + 8 >= packet->GetEndOfData() )
if ( pdata + 8 >= packet->GetEndOfData() )
{ {
packet->Weird("truncated_pppoe_header"); packet->Weird("truncated_pppoe_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
// Extract protocol identifier // Extract protocol identifier
uint32_t protocol = (pdata[6] << 8u) + pdata[7]; uint32_t protocol = (data[6] << 8u) + data[7];
pdata += 8; // Skip the PPPoE session and PPP header data += 8; // Skip the PPPoE session and PPP header
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
PPPoEAnalyzer(); PPPoEAnalyzer();
~PPPoEAnalyzer() override = default; ~PPPoEAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,22 +10,20 @@ VLANAnalyzer::VLANAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple VLANAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple VLANAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos; if ( data + 4 >= packet->GetEndOfData() )
if ( pdata + 4 >= packet->GetEndOfData() )
{ {
packet->Weird("truncated_VLAN_header"); packet->Weird("truncated_VLAN_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
auto& vlan_ref = packet->vlan != 0 ? packet->inner_vlan : packet->vlan; auto& vlan_ref = packet->vlan != 0 ? packet->inner_vlan : packet->vlan;
vlan_ref = ((pdata[0] << 8u) + pdata[1]) & 0xfff; vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff;
uint32_t protocol = ((pdata[2] << 8u) + pdata[3]); uint32_t protocol = ((data[2] << 8u) + data[3]);
packet->eth_type = protocol; packet->eth_type = protocol;
pdata += 4; // Skip the VLAN header data += 4; // Skip the VLAN header
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
VLANAnalyzer(); VLANAnalyzer();
~VLANAnalyzer() override = default; ~VLANAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,38 +10,37 @@ WrapperAnalyzer::WrapperAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
// Unfortunately some packets on the link might have MPLS labels // Unfortunately some packets on the link might have MPLS labels
// while others don't. That means we need to ask the link-layer if // while others don't. That means we need to ask the link-layer if
// labels are in place. // labels are in place.
bool have_mpls = false; bool have_mpls = false;
auto pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
// Skip past Cisco FabricPath to encapsulated ethernet frame. // Skip past Cisco FabricPath to encapsulated ethernet frame.
if ( pdata[12] == 0x89 && pdata[13] == 0x03 ) if ( data[12] == 0x89 && data[13] == 0x03 )
{ {
auto constexpr cfplen = 16; auto constexpr cfplen = 16;
if ( pdata + cfplen + 14 >= end_of_data ) if ( data + cfplen + 14 >= end_of_data )
{ {
packet->Weird("truncated_link_header_cfp"); packet->Weird("truncated_link_header_cfp");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
pdata += cfplen; data += cfplen;
} }
// Extract protocol identifier // Extract protocol identifier
uint32_t protocol = (pdata[12] << 8u) + pdata[13]; uint32_t protocol = (data[12] << 8u) + data[13];
packet->eth_type = protocol; packet->eth_type = protocol;
packet->l2_dst = pdata; packet->l2_dst = data;
packet->l2_src = pdata + 6; packet->l2_src = data + 6;
pdata += 14; data += 14;
bool saw_vlan = false; bool saw_vlan = false;
@ -55,16 +54,16 @@ zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* pack
case 0x8100: case 0x8100:
case 0x9100: case 0x9100:
{ {
if ( pdata + 4 >= end_of_data ) if ( data + 4 >= end_of_data )
{ {
packet->Weird("truncated_link_header"); packet->Weird("truncated_link_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan; auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan;
vlan_ref = ((pdata[0] << 8u) + pdata[1]) & 0xfff; vlan_ref = ((data[0] << 8u) + data[1]) & 0xfff;
protocol = ((pdata[2] << 8u) + pdata[3]); protocol = ((data[2] << 8u) + data[3]);
pdata += 4; // Skip the vlan header data += 4; // Skip the vlan header
saw_vlan = true; saw_vlan = true;
packet->eth_type = protocol; packet->eth_type = protocol;
} }
@ -73,14 +72,14 @@ zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* pack
// PPPoE carried over the ethernet frame. // PPPoE carried over the ethernet frame.
case 0x8864: case 0x8864:
{ {
if ( pdata + 8 >= end_of_data ) if ( data + 8 >= end_of_data )
{ {
packet->Weird("truncated_link_header"); packet->Weird("truncated_link_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
protocol = (pdata[6] << 8u) + pdata[7]; protocol = (data[6] << 8u) + data[7];
pdata += 8; // Skip the PPPoE session and PPP header data += 8; // Skip the PPPoE session and PPP header
if ( protocol == 0x0021 ) if ( protocol == 0x0021 )
packet->l3_proto = L3_IPV4; packet->l3_proto = L3_IPV4;
@ -125,24 +124,24 @@ zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* pack
while ( ! end_of_stack ) while ( ! end_of_stack )
{ {
if ( pdata + 4 >= end_of_data ) if ( data + 4 >= end_of_data )
{ {
packet->Weird("truncated_link_header"); packet->Weird("truncated_link_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
end_of_stack = *(pdata + 2u) & 0x01; end_of_stack = *(data + 2u) & 0x01;
pdata += 4; data += 4;
} }
// We assume that what remains is IP // We assume that what remains is IP
if ( pdata + sizeof(struct ip) >= end_of_data ) if ( data + sizeof(struct ip) >= end_of_data )
{ {
packet->Weird("no_ip_in_mpls_payload"); packet->Weird("no_ip_in_mpls_payload");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
const struct ip* ip = (const struct ip*)pdata; const struct ip* ip = (const struct ip*)data;
if ( ip->ip_v == 4 ) if ( ip->ip_v == 4 )
packet->l3_proto = L3_IPV4; packet->l3_proto = L3_IPV4;
@ -157,7 +156,7 @@ zeek::packet_analysis::AnalysisResultTuple WrapperAnalyzer::Analyze(Packet* pack
} }
// Calculate how much header we've used up. // Calculate how much header we've used up.
packet->hdr_size = (pdata - packet->data); packet->hdr_size = (data - packet->data);
return { AnalyzerResult::Continue, protocol }; return { AnalyzerResult::Continue, protocol };
} }

View file

@ -12,7 +12,7 @@ public:
WrapperAnalyzer(); WrapperAnalyzer();
~WrapperAnalyzer() override = default; ~WrapperAnalyzer() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static zeek::packet_analysis::AnalyzerPtr Instantiate() static zeek::packet_analysis::AnalyzerPtr Instantiate()
{ {

View file

@ -10,21 +10,20 @@ Bar::Bar()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple Bar::Analyze(Packet* packet) zeek::packet_analysis::AnalysisResultTuple Bar::Analyze(Packet* packet, const uint8_t*& data)
{ {
auto& pdata = packet->cur_pos;
auto end_of_data = packet->GetEndOfData(); auto end_of_data = packet->GetEndOfData();
// Rudimentary parsing of 802.2 LLC // Rudimentary parsing of 802.2 LLC
if ( pdata + 17 >= end_of_data ) if ( data + 17 >= end_of_data )
{ {
packet->Weird("truncated_llc_header"); packet->Weird("truncated_llc_header");
return { AnalyzerResult::Failed, 0 }; return { AnalyzerResult::Failed, 0 };
} }
auto dsap = pdata[14]; auto dsap = data[14];
auto ssap = pdata[15]; auto ssap = data[15];
auto control = pdata[16]; auto control = data[16];
mgr.Enqueue(bar_message, mgr.Enqueue(bar_message,
val_mgr->Count(dsap), val_mgr->Count(dsap),

View file

@ -10,7 +10,7 @@ public:
Bar(); Bar();
~Bar() override = default; ~Bar() override = default;
AnalysisResultTuple Analyze(Packet* packet) override; AnalysisResultTuple Analyze(Packet* packet, const uint8_t*& data) override;
static AnalyzerPtr Instantiate() static AnalyzerPtr Instantiate()
{ {