mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Bring back default packet analysis.
Default analyzers can be configured per packet analyzer by omitting the identifier in the ConfigEntry.
This commit is contained in:
parent
d4ff5a236c
commit
462b1fe3a2
9 changed files with 81 additions and 21 deletions
|
@ -5357,8 +5357,9 @@ export {
|
|||
parent : PacketAnalyzer::Tag &optional;
|
||||
|
||||
# A numeric identifier, which can be found in the packet data, that denotes the
|
||||
# encapsulated protocol.
|
||||
identifier : count;
|
||||
# encapsulated protocol. This field is optional. If it is not included, the
|
||||
# configured child analyzer will be used as default analyzer.
|
||||
identifier : count &optional;
|
||||
|
||||
# The analyzer that corresponds to the above identifier.
|
||||
analyzer : PacketAnalyzer::Tag;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#@load base/packet-protocols/default
|
||||
@load base/packet-protocols/default
|
||||
@load base/packet-protocols/ethernet
|
||||
#@load base/packet-protocols/fddi
|
||||
#@load base/packet-protocols/ieee802_11
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module LL_DEFAULT;
|
||||
|
||||
redef PacketAnalyzer::config_map += {
|
||||
PacketAnalyzer::ConfigEntry($analyzer=PacketAnalyzer::ANALYZER_DEFAULTANALYZER),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_DEFAULTANALYZER, $identifier=4, $analyzer=PacketAnalyzer::ANALYZER_IPV4),
|
||||
PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_DEFAULTANALYZER, $identifier=6, $analyzer=PacketAnalyzer::ANALYZER_IPV6)
|
||||
};
|
||||
|
|
|
@ -12,5 +12,6 @@ redef PacketAnalyzer::config_map += {
|
|||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x8100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x88A8, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#PacketAnalyzer::ConfigEntry($parent=PacketAnalyzer::ANALYZER_ETHERNET, $identifier=0x9100, $analyzer=PacketAnalyzer::ANALYZER_VLAN),
|
||||
#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)
|
||||
};
|
||||
|
|
|
@ -47,14 +47,24 @@ bool Analyzer::RegisterAnalyzerMapping(uint32_t identifier, AnalyzerPtr analyzer
|
|||
return dispatcher.Register(identifier, std::move(analyzer));
|
||||
}
|
||||
|
||||
void Analyzer::RegisterDefaultAnalyzer(AnalyzerPtr default_analyzer)
|
||||
{
|
||||
this->default_analyzer = std::move(default_analyzer);
|
||||
}
|
||||
|
||||
AnalyzerPtr Analyzer::Lookup(uint32_t identifier) const
|
||||
{
|
||||
return dispatcher.Lookup(identifier);
|
||||
}
|
||||
|
||||
AnalyzerResult Analyzer::AnalyzeInnerPacket(Packet* packet,
|
||||
const uint8_t*& data, uint32_t identifier) const
|
||||
{
|
||||
auto inner_analyzer = dispatcher.Lookup(identifier);
|
||||
auto inner_analyzer = Lookup(identifier);
|
||||
inner_analyzer = inner_analyzer ? inner_analyzer : default_analyzer;
|
||||
|
||||
if ( inner_analyzer == nullptr )
|
||||
{
|
||||
//TODO: Handle default analysis here
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
|
|
|
@ -74,10 +74,17 @@ public:
|
|||
*
|
||||
* @param identifier The identifier an analyzer should be called for.
|
||||
* @param analyzer The analyzer that should be called.
|
||||
* @return True if the registration was successfull.
|
||||
* @return True if the registration was successful.
|
||||
*/
|
||||
bool RegisterAnalyzerMapping(uint32_t identifier, AnalyzerPtr analyzer);
|
||||
|
||||
/**
|
||||
* Registers a default analyzer.
|
||||
*
|
||||
* @param default_analyzer The analyzer to use as default.
|
||||
*/
|
||||
void RegisterDefaultAnalyzer(AnalyzerPtr default_analyzer);
|
||||
|
||||
/**
|
||||
* Analyzes the given packet. The data reference points to the part of the
|
||||
* raw packet to be analyzed. If the analyzed protocol encapsulates another
|
||||
|
@ -95,6 +102,16 @@ public:
|
|||
protected:
|
||||
friend class Manager;
|
||||
|
||||
/**
|
||||
* Looks up the analyzer for the encapsulated protocol based on the given
|
||||
* identifier.
|
||||
*
|
||||
* @param identifier Identifier for the encapsulated protocol.
|
||||
* @return The analyzer registered for the given identifier. Returns a
|
||||
* nullptr if no analyzer is registered.
|
||||
*/
|
||||
AnalyzerPtr Lookup(uint32_t identifier) const;
|
||||
|
||||
/**
|
||||
* Triggers analysis of the encapsulated packet. The encapsulated protocol
|
||||
* is determined using the given identifier.
|
||||
|
@ -105,12 +122,13 @@ protected:
|
|||
*
|
||||
* @return The outcome of the analysis.
|
||||
*/
|
||||
AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data,
|
||||
virtual AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data,
|
||||
uint32_t identifier) const;
|
||||
|
||||
private:
|
||||
Tag tag;
|
||||
Dispatcher dispatcher;
|
||||
AnalyzerPtr default_analyzer = nullptr;
|
||||
|
||||
void Init(const Tag& tag);
|
||||
};
|
||||
|
|
|
@ -36,9 +36,9 @@ void Manager::InitPostScript()
|
|||
auto* rv = mapping_val->At(i)->AsRecordVal();
|
||||
//TODO: Make that field a string for usability reasons
|
||||
//TODO: Check error handling when fields are omitted
|
||||
auto& parent_tag = rv->GetField("parent");
|
||||
std::string parent_name = parent_tag ? Lookup(parent_tag->AsEnumVal())->Name() : "ROOT";
|
||||
auto identifier = rv->GetField("identifier")->AsCount();
|
||||
auto& parent_val = rv->GetField("parent");
|
||||
std::string parent_name = parent_val ? Lookup(parent_val->AsEnumVal())->Name() : "ROOT";
|
||||
auto& identifier_val = rv->GetField("identifier");
|
||||
auto analyzer_tag = rv->GetField("analyzer")->AsEnumVal();
|
||||
auto analyzer_name = Lookup(analyzer_tag)->Name();
|
||||
|
||||
|
@ -50,7 +50,11 @@ void Manager::InitPostScript()
|
|||
|
||||
if ( parent_name == "ROOT" )
|
||||
{
|
||||
root_dispatcher.Register(identifier, analyzers[analyzer_name]);
|
||||
if ( identifier_val )
|
||||
root_dispatcher.Register(identifier_val->AsCount(),
|
||||
analyzers[analyzer_name]);
|
||||
else
|
||||
default_analyzer = analyzers[analyzer_name];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -61,15 +65,13 @@ void Manager::InitPostScript()
|
|||
}
|
||||
|
||||
auto& parent_analyzer = analyzers[parent_name];
|
||||
parent_analyzer->RegisterAnalyzerMapping(identifier, analyzers[analyzer_name]);
|
||||
if ( identifier_val )
|
||||
parent_analyzer->RegisterAnalyzerMapping(identifier_val->AsCount(),
|
||||
analyzers[analyzer_name]);
|
||||
else
|
||||
parent_analyzer->RegisterDefaultAnalyzer(analyzers[analyzer_name]);
|
||||
}
|
||||
|
||||
// Set default analyzer
|
||||
auto da_it = analyzers.find("DefaultAnalyzer");
|
||||
if ( da_it == analyzers.end() )
|
||||
reporter->InternalError("DefaultAnalyzer not found.");
|
||||
default_analyzer = da_it->second;
|
||||
|
||||
// Initialize all analyzers
|
||||
for ( auto& [name, analyzer] : analyzers )
|
||||
analyzer->Initialize();
|
||||
|
@ -139,7 +141,12 @@ void Manager::ProcessPacket(Packet* packet)
|
|||
const uint8_t* data = packet->data;
|
||||
|
||||
auto root_analyzer = root_dispatcher.Lookup(packet->link_type);
|
||||
auto analyzer = root_analyzer == nullptr ? default_analyzer : root_analyzer;
|
||||
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)
|
||||
|
|
|
@ -24,3 +24,21 @@ zeek::packet_analysis::AnalyzerResult DefaultAnalyzer::Analyze(Packet* packet, c
|
|||
|
||||
return AnalyzeInnerPacket(packet, data, protocol);
|
||||
}
|
||||
|
||||
zeek::packet_analysis::AnalyzerResult DefaultAnalyzer::AnalyzeInnerPacket(Packet* packet,
|
||||
const uint8_t*& data, uint32_t identifier) const
|
||||
{
|
||||
auto inner_analyzer = Lookup(identifier);
|
||||
|
||||
if ( inner_analyzer == nullptr )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Default analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
return AnalyzerResult::Failed;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Default analysis in %s succeeded, next layer identifier is %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
return inner_analyzer->Analyze(packet, data);
|
||||
}
|
|
@ -18,6 +18,10 @@ public:
|
|||
{
|
||||
return std::make_shared<DefaultAnalyzer>();
|
||||
}
|
||||
|
||||
protected:
|
||||
AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data,
|
||||
uint32_t identifier) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue