Simplify packet analyzer config.

This commit is contained in:
Jan Grashoefer 2020-09-07 20:46:14 +02:00 committed by Tim Wojtulewicz
parent efa262a229
commit 7ede4f48bd
28 changed files with 233 additions and 213 deletions

View file

@ -29,14 +29,37 @@ void Analyzer::Init(const Tag& _tag)
void Analyzer::Initialize()
{
std::string ns = util::fmt("PacketAnalyzer::%s::", GetAnalyzerName());
default_analyzer = LoadAnalyzer("default_analyzer");
default_analyzer = LoadAnalyzer(ns +"default_analyzer");
// Create dispatcher based on configuration
auto& mapping_id = zeek::id::find(GetModuleName() + "dispatch_map");
if ( ! mapping_id )
return;
auto mapping_val = mapping_id->GetVal()->AsTableVal();
auto mapping_tbl = mapping_val->AsTable();
auto c = mapping_tbl->InitForIteration();
zeek::detail::HashKey* k = nullptr;
TableEntryVal* v;
while ( (v = mapping_tbl->NextEntry(k, c)) )
{
auto key = mapping_val->RecreateIndex(*k);
delete k;
auto identifier = key->Idx(0)->AsCount();
auto config_entry_val = v->GetVal()->AsRecordVal();
auto mapped_tag = config_entry_val->GetField("analyzer")->AsEnumVal();
auto mapped_analyzer = packet_mgr->GetAnalyzer(mapped_tag);
dispatcher.Register(identifier, std::move(mapped_analyzer));
}
}
zeek::packet_analysis::AnalyzerPtr Analyzer::LoadAnalyzer(const std::string &name)
{
auto& analyzer = zeek::id::find(name);
auto& analyzer = zeek::id::find(GetModuleName() + name);
if ( ! analyzer )
return nullptr;
@ -65,16 +88,6 @@ bool Analyzer::IsAnalyzer(const char* name)
return packet_mgr->GetComponentName(tag) == name;
}
void Analyzer::RegisterAnalyzerMapping(uint32_t identifier, AnalyzerPtr analyzer)
{
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);
@ -114,7 +127,7 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) co
void Analyzer::DumpDebug() const
{
#ifdef DEBUG
DBG_LOG(DBG_PACKET_ANALYSIS, "Debug info for %s", this->GetAnalyzerName());
DBG_LOG(DBG_PACKET_ANALYSIS, "Dispatcher for %s", this->GetAnalyzerName());
dispatcher.DumpDebug();
#endif
}

View file

@ -63,21 +63,6 @@ public:
*/
bool IsAnalyzer(const char* name);
/**
* Registers an analyzer to be dispatched for the given identifier.
*
* @param identifier The identifier an analyzer should be called for.
* @param analyzer The analyzer that should be called.
*/
void 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. A common case is that the analyzed protocol
* encapsulates another protocol, which can be determined by an identifier
@ -119,6 +104,15 @@ protected:
*/
AnalyzerPtr LoadAnalyzer(const std::string& name);
/**
* Returns the module name corresponding to the analyzer, i.e. its script-land
* namespace. Configuration values for the analyzer are expected in this module.
* @return Analyzer's module name.
*/
std::string GetModuleName() const {
return util::fmt("PacketAnalyzer::%s::", GetAnalyzerName());
};
/**
* Triggers analysis of the encapsulated packet. The encapsulated protocol
* is determined using the given identifier.

View file

@ -21,48 +21,6 @@ void Manager::InitPostScript()
analyzers.emplace(analyzerComponent->Name(), newAnalyzer);
}
// Read in analyzer map and create dispatchers
auto& analyzer_mapping = zeek::id::find("PacketAnalyzer::config_map");
if ( ! analyzer_mapping )
return;
auto mapping_val = analyzer_mapping->GetVal()->AsVectorVal();
if ( mapping_val->Size() == 0 )
return;
for ( unsigned int i = 0; i < mapping_val->Size(); i++ )
{
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_val = rv->GetField("parent");
std::string parent_name = Lookup(parent_val->AsEnumVal())->Name();
auto& identifier_val = rv->GetField("identifier");
auto analyzer_tag = rv->GetField("analyzer")->AsEnumVal();
auto analyzer_name = Lookup(analyzer_tag)->Name();
auto analyzer_it = analyzers.find(analyzer_name);
if ( analyzer_it == analyzers.end() )
{
reporter->InternalWarning("Mapped analyzer %s not found.", analyzer_name.c_str());
continue;
}
auto& analyzer = analyzer_it->second;
auto parent_analyzer_it = analyzers.find(parent_name);
if ( parent_analyzer_it == analyzers.end() )
{
reporter->InternalWarning("Parent analyzer %s not found.", parent_name.c_str());
continue;
}
auto& parent_analyzer = parent_analyzer_it->second;
if ( identifier_val )
parent_analyzer->RegisterAnalyzerMapping(identifier_val->AsCount(), analyzer);
else
parent_analyzer->RegisterDefaultAnalyzer(analyzer);
}
// Initialize all analyzers
for ( auto& [name, analyzer] : analyzers )
analyzer->Initialize();
@ -79,12 +37,11 @@ void Manager::DumpDebug()
#ifdef DEBUG
DBG_LOG(DBG_PACKET_ANALYSIS, "Available packet analyzers after zeek_init():");
for ( auto& current : GetComponents() )
{
DBG_LOG(DBG_PACKET_ANALYSIS, " %s", current->Name().c_str());
}
DBG_LOG(DBG_PACKET_ANALYSIS, "Root dispatcher:");
root_analyzer->DumpDebug();
DBG_LOG(DBG_PACKET_ANALYSIS, "Packet analyzer debug information:");
for ( auto& [name, analyzer] : analyzers )
analyzer->DumpDebug();
#endif
}

View file

@ -15,9 +15,9 @@ void EthernetAnalyzer::Initialize()
{
Analyzer::Initialize();
SNAPAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::snap_analyzer");
NovellRawAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::novell_raw_analyzer");
LLCAnalyzer = LoadAnalyzer("PacketAnalyzer::Ethernet::llc_analyzer");
SNAPAnalyzer = LoadAnalyzer("snap_analyzer");
NovellRawAnalyzer = LoadAnalyzer("novell_raw_analyzer");
LLCAnalyzer = LoadAnalyzer("llc_analyzer");
}
bool EthernetAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet)