mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Remove magic identifiers from Ethernet analyzer.
This commit is contained in:
parent
462b1fe3a2
commit
cbdaa53f85
5 changed files with 119 additions and 49 deletions
|
@ -1,4 +1,4 @@
|
||||||
module LL_ETHERNET;
|
module PacketAnalyzer::Ethernet;
|
||||||
|
|
||||||
const DLT_EN10MB : count = 1;
|
const DLT_EN10MB : count = 1;
|
||||||
|
|
||||||
|
@ -15,3 +15,7 @@ redef PacketAnalyzer::config_map += {
|
||||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8864, $analyzer=PacketAnalyzer::ANALYZER_PPPOE),
|
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8864, $analyzer=PacketAnalyzer::ANALYZER_PPPOE),
|
||||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $analyzer=PacketAnalyzer::ANALYZER_DEFAULTANALYZER)
|
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $analyzer=PacketAnalyzer::ANALYZER_DEFAULTANALYZER)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const snap_analyzer: PacketAnalyzer::Tag &redef;
|
||||||
|
const novell_raw_analyzer: PacketAnalyzer::Tag &redef;
|
||||||
|
const llc_analyzer: PacketAnalyzer::Tag &redef;
|
||||||
|
|
|
@ -92,6 +92,49 @@ void Manager::DumpDebug()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnalyzerPtr Manager::GetAnalyzer(EnumVal *val)
|
||||||
|
{
|
||||||
|
auto analyzer_comp = Lookup(val);
|
||||||
|
if ( ! analyzer_comp )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return GetAnalyzer(analyzer_comp->Name());
|
||||||
|
}
|
||||||
|
|
||||||
|
AnalyzerPtr Manager::GetAnalyzer(const std::string& name)
|
||||||
|
{
|
||||||
|
auto analyzer_it = analyzers.find(name);
|
||||||
|
if ( analyzer_it == analyzers.end() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return analyzer_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::ProcessPacket(Packet* packet)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
static size_t counter = 0;
|
||||||
|
DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
|
||||||
|
#endif
|
||||||
|
// Start packet analysis
|
||||||
|
const uint8_t* data = packet->data;
|
||||||
|
|
||||||
|
auto root_analyzer = root_dispatcher.Lookup(packet->link_type);
|
||||||
|
auto analyzer = root_analyzer ? root_analyzer : default_analyzer;
|
||||||
|
if ( !analyzer )
|
||||||
|
{
|
||||||
|
reporter->InternalWarning("No analyzer for link type %#x", packet->link_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = analyzer->Analyze(packet, data);
|
||||||
|
if (result == AnalyzerResult::Terminate)
|
||||||
|
CustomEncapsulationSkip(packet, data);
|
||||||
|
|
||||||
|
// Calculate header size after processing packet layers.
|
||||||
|
packet->hdr_size = static_cast<uint32_t>(data - packet->data);
|
||||||
|
}
|
||||||
|
|
||||||
AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag)
|
AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag)
|
||||||
{
|
{
|
||||||
Component* c = Lookup(tag);
|
Component* c = Lookup(tag);
|
||||||
|
@ -119,7 +162,7 @@ AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag)
|
||||||
if ( tag != a->GetAnalyzerTag() )
|
if ( tag != a->GetAnalyzerTag() )
|
||||||
{
|
{
|
||||||
reporter->InternalError("Mismatch of requested analyzer %s and instantiated analyzer %s. This usually means that the plugin author made a mistake.",
|
reporter->InternalError("Mismatch of requested analyzer %s and instantiated analyzer %s. This usually means that the plugin author made a mistake.",
|
||||||
GetComponentName(tag).c_str(), GetComponentName(a->GetAnalyzerTag()).c_str());
|
GetComponentName(tag).c_str(), GetComponentName(a->GetAnalyzerTag()).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
|
@ -131,31 +174,6 @@ AnalyzerPtr Manager::InstantiateAnalyzer(const std::string& name)
|
||||||
return tag ? InstantiateAnalyzer(tag) : nullptr;
|
return tag ? InstantiateAnalyzer(tag) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::ProcessPacket(Packet* packet)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
static size_t counter = 0;
|
|
||||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
|
|
||||||
#endif
|
|
||||||
// Start packet analysis
|
|
||||||
const uint8_t* data = packet->data;
|
|
||||||
|
|
||||||
auto root_analyzer = root_dispatcher.Lookup(packet->link_type);
|
|
||||||
auto analyzer = root_analyzer ? root_analyzer : default_analyzer;
|
|
||||||
if ( !analyzer )
|
|
||||||
{
|
|
||||||
reporter->InternalWarning("No analyzer for link type %#x", packet->link_type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = analyzer->Analyze(packet, data);
|
|
||||||
if (result == AnalyzerResult::Terminate)
|
|
||||||
CustomEncapsulationSkip(packet, data);
|
|
||||||
|
|
||||||
// Calculate header size after processing packet layers.
|
|
||||||
packet->hdr_size = static_cast<uint32_t>(data - packet->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::CustomEncapsulationSkip(Packet* packet, const uint8_t* data)
|
void Manager::CustomEncapsulationSkip(Packet* packet, const uint8_t* data)
|
||||||
{
|
{
|
||||||
if ( zeek::detail::encap_hdr_size > 0 )
|
if ( zeek::detail::encap_hdr_size > 0 )
|
||||||
|
|
|
@ -44,26 +44,22 @@ public:
|
||||||
void DumpDebug(); // Called after zeek_init() events.
|
void DumpDebug(); // Called after zeek_init() events.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new analyzer instance.
|
* Looks up an analyzer instance.
|
||||||
*
|
*
|
||||||
* @param tag The analyzer's tag.
|
* @param val The analyzer's tag value.
|
||||||
*
|
*
|
||||||
* @return The new analyzer instance. Returns
|
* @return The analyzer instance or nullptr if no instance is found.
|
||||||
* null if tag is invalid, the requested analyzer is disabled, or the
|
|
||||||
* analyzer can't be instantiated.
|
|
||||||
*/
|
*/
|
||||||
AnalyzerPtr InstantiateAnalyzer(const Tag& tag);
|
AnalyzerPtr GetAnalyzer(EnumVal *val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new analyzer.
|
* Looks up an analyzer instance.
|
||||||
*
|
*
|
||||||
* @param name The name of the analyzer.
|
* @param name The name of the analyzer.
|
||||||
*
|
*
|
||||||
* @return The new analyzer instance. Returns
|
* @return The analyzer instance or nullptr if no instance is found.
|
||||||
* null if the name is not known or if the requested analyzer that is
|
|
||||||
* disabled.
|
|
||||||
*/
|
*/
|
||||||
AnalyzerPtr InstantiateAnalyzer(const std::string& name);
|
AnalyzerPtr GetAnalyzer(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a packet by applying the configured packet analyzers.
|
* Processes a packet by applying the configured packet analyzers.
|
||||||
|
@ -73,6 +69,26 @@ public:
|
||||||
void ProcessPacket(Packet* packet);
|
void ProcessPacket(Packet* packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Instantiates a new analyzer instance.
|
||||||
|
*
|
||||||
|
* @param tag The analyzer's tag.
|
||||||
|
*
|
||||||
|
* @return The new analyzer instance. Returns null if tag is invalid, the
|
||||||
|
* requested analyzer is disabled, or the analyzer can't be instantiated.
|
||||||
|
*/
|
||||||
|
AnalyzerPtr InstantiateAnalyzer(const Tag& tag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new analyzer.
|
||||||
|
*
|
||||||
|
* @param name The name of the analyzer.
|
||||||
|
*
|
||||||
|
* @return The new analyzer instance. Returns null if the name is not known
|
||||||
|
* or if the requested analyzer that is disabled.
|
||||||
|
*/
|
||||||
|
AnalyzerPtr InstantiateAnalyzer(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips a fixed amount of packet data that is defined by encap_hdr_size.
|
* Skips a fixed amount of packet data that is defined by encap_hdr_size.
|
||||||
* It is assumed that an IP header follows.
|
* It is assumed that an IP header follows.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Ethernet.h"
|
#include "Ethernet.h"
|
||||||
#include "NetVar.h"
|
#include "NetVar.h"
|
||||||
|
#include "Manager.h"
|
||||||
|
|
||||||
using namespace zeek::packet_analysis::Ethernet;
|
using namespace zeek::packet_analysis::Ethernet;
|
||||||
|
|
||||||
|
@ -10,6 +11,26 @@ EthernetAnalyzer::EthernetAnalyzer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EthernetAnalyzer::Initialize()
|
||||||
|
{
|
||||||
|
SNAPAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::snap_analyzer");
|
||||||
|
NovellRawAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::novell_raw_analyzer");
|
||||||
|
LLCAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::llc_analyzer");
|
||||||
|
}
|
||||||
|
|
||||||
|
zeek::packet_analysis::AnalyzerPtr EthernetAnalyzer::LoadAnalyzer(const std::string &name)
|
||||||
|
{
|
||||||
|
auto& analyzer = zeek::id::find(name);
|
||||||
|
if ( ! analyzer )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto& analyzer_val = analyzer->GetVal();
|
||||||
|
if ( ! analyzer_val )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return packet_mgr->GetAnalyzer(analyzer_val->AsEnumVal());
|
||||||
|
}
|
||||||
|
|
||||||
zeek::packet_analysis::AnalyzerResult EthernetAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
zeek::packet_analysis::AnalyzerResult EthernetAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
|
||||||
{
|
{
|
||||||
auto end_of_data = packet->GetEndOfData();
|
auto end_of_data = packet->GetEndOfData();
|
||||||
|
@ -59,22 +80,25 @@ zeek::packet_analysis::AnalyzerResult EthernetAnalyzer::Analyze(Packet* packet,
|
||||||
return AnalyzerResult::Failed;
|
return AnalyzerResult::Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the following we use undefined EtherTypes to signal uncommon
|
// Let specialized analyzers take over for non Ethernet II frames.
|
||||||
// frame types. This allows specialized analyzers to take over.
|
|
||||||
// Note that pdata remains at the start of the ethernet frame.
|
// Note that pdata remains at the start of the ethernet frame.
|
||||||
//TODO: Lookup the analyzers on startup
|
|
||||||
|
|
||||||
// IEEE 802.2 SNAP
|
AnalyzerPtr eth_analyzer = nullptr;
|
||||||
|
|
||||||
if ( data[14] == 0xAA && data[15] == 0xAA)
|
if ( data[14] == 0xAA && data[15] == 0xAA)
|
||||||
return AnalyzeInnerPacket(packet, data, 1502);
|
// IEEE 802.2 SNAP
|
||||||
|
eth_analyzer = SNAPAnalyzer;
|
||||||
|
else if ( data[14] == 0xFF && data[15] == 0xFF)
|
||||||
|
// Novell raw IEEE 802.3
|
||||||
|
eth_analyzer = NovellRawAnalyzer;
|
||||||
|
else
|
||||||
|
// IEEE 802.2 LLC
|
||||||
|
eth_analyzer = LLCAnalyzer;
|
||||||
|
|
||||||
// Novell raw IEEE 802.3
|
if ( eth_analyzer )
|
||||||
if ( data[14] == 0xFF && data[15] == 0xFF)
|
return eth_analyzer->Analyze(packet, data);
|
||||||
return AnalyzeInnerPacket(packet, data, 1503);
|
|
||||||
|
|
||||||
|
return AnalyzerResult::Terminate;
|
||||||
// IEEE 802.2 LLC
|
|
||||||
return AnalyzeInnerPacket(packet, data, 1501);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undefined (1500 < EtherType < 1536)
|
// Undefined (1500 < EtherType < 1536)
|
||||||
|
|
|
@ -12,12 +12,20 @@ public:
|
||||||
EthernetAnalyzer();
|
EthernetAnalyzer();
|
||||||
~EthernetAnalyzer() override = default;
|
~EthernetAnalyzer() override = default;
|
||||||
|
|
||||||
|
void Initialize() override;
|
||||||
AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) override;
|
AnalyzerResult Analyze(Packet* packet, const uint8_t*& data) override;
|
||||||
|
|
||||||
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
static zeek::packet_analysis::AnalyzerPtr Instantiate()
|
||||||
{
|
{
|
||||||
return std::make_shared<EthernetAnalyzer>();
|
return std::make_shared<EthernetAnalyzer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
AnalyzerPtr SNAPAnalyzer = nullptr;
|
||||||
|
AnalyzerPtr NovellRawAnalyzer = nullptr;
|
||||||
|
AnalyzerPtr LLCAnalyzer = nullptr;
|
||||||
|
|
||||||
|
AnalyzerPtr LoadAnalyzer(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue