Merge ProtocolAnalyzerSet into Manager, remove AnalyzerSet base class

This commit is contained in:
Tim Wojtulewicz 2020-07-13 17:14:12 -04:00
parent 1e0e8e35af
commit 1c3ded7dd5
6 changed files with 142 additions and 222 deletions

View file

@ -1,13 +1,15 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "Manager.h"
#include <list>
#include <pcap.h>
#include "Config.h"
#include "Manager.h"
#include "NetVar.h"
#include "ProtocolAnalyzerSet.h"
#include "plugin/Manager.h"
#include "Analyzer.h"
#include "dispatchers/VectorDispatcher.h"
using namespace zeek::packet_analysis;
@ -18,7 +20,17 @@ Manager::Manager()
Manager::~Manager()
{
delete analyzer_set;
bool delete_default = default_analyzer != nullptr;
for ( const auto& current : analyzers )
{
if ( current.second == default_analyzer )
delete_default = false;
delete current.second;
}
if ( delete_default )
delete default_analyzer;
}
void Manager::InitPostScript()
@ -43,7 +55,38 @@ void Manager::InitPostScript()
configuration.AddMapping(parent_name, identifier, Lookup(analyzer)->Name());
}
analyzer_set = new ProtocolAnalyzerSet(configuration, "DefaultAnalyzer");
// Instantiate objects for all analyzers
for ( const auto& current_dispatcher_config : configuration.GetDispatchers() )
{
for ( const auto& current_mapping : current_dispatcher_config.GetMappings() )
{
// Check if already instantiated
if ( analyzers.count(current_mapping.second) != 0 )
continue;
// Check if analyzer exists
if ( Analyzer* newAnalyzer = InstantiateAnalyzer(current_mapping.second) )
analyzers.emplace(current_mapping.second, newAnalyzer);
}
}
// Generate Dispatchers, starting at root
root_dispatcher = GetDispatcher(configuration, "ROOT");
if ( root_dispatcher == nullptr )
reporter->InternalError("No dispatching configuration for ROOT of packet_analysis set.");
// Set up default analysis
auto it = analyzers.find("DefaultAnalyzer");
if ( it != analyzers.end() )
default_analyzer = it->second;
else
default_analyzer = InstantiateAnalyzer("DefaultAnalyzer");
default_dispatcher = nullptr;
if ( default_analyzer != nullptr )
default_dispatcher = GetDispatcher(configuration, "DefaultAnalyzer");
current_state = root_dispatcher;
}
void Manager::Done()
@ -59,9 +102,12 @@ void Manager::DumpDebug()
DBG_LOG(DBG_PACKET_ANALYSIS, " %s (%s)", current->Name().c_str(), IsEnabled(current->Tag()) ? "enabled" : "disabled");
}
// Dump Analyzer Set
if (analyzer_set)
analyzer_set->DumpDebug();
DBG_LOG(DBG_PACKET_ANALYSIS, "ProtocolAnalyzerSet FSM:");
for ( const auto& current : dispatchers )
{
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher (%p): %s", current.second, current.first.c_str());
current.second->DumpDebug();
}
#endif
}
@ -204,15 +250,12 @@ void Manager::ProcessPacket(Packet* packet)
DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
#endif
if ( ! analyzer_set )
return;
// Dispatch and analyze layers
AnalyzerResult result = AnalyzerResult::Continue;
identifier_t next_layer_id = packet->link_type;
do
{
auto current_analyzer = analyzer_set->Dispatch(next_layer_id);
auto current_analyzer = Dispatch(next_layer_id);
// Analyzer not found
if ( current_analyzer == nullptr )
@ -246,7 +289,7 @@ void Manager::ProcessPacket(Packet* packet)
CustomEncapsulationSkip(packet);
// Processing finished, reset analyzer set state for next packet
analyzer_set->Reset();
Reset();
}
void Manager::CustomEncapsulationSkip(Packet* packet)
@ -283,3 +326,72 @@ void Manager::CustomEncapsulationSkip(Packet* packet)
}
}
}
Analyzer* Manager::Dispatch(identifier_t identifier)
{
// Because leaf nodes (aka no more dispatching) can still have an existing analyzer that returns more identifiers,
// current_state needs to be checked to be not null. In this case there would have been an analyzer dispatched
// in the last layer, but no dispatcher for it (end of FSM)
const Value* result = nullptr;
if ( current_state )
result = current_state->Lookup(identifier);
if ( result == nullptr )
{
if ( current_state != default_dispatcher )
{
// Switch to default analysis once
current_state = default_dispatcher;
return default_analyzer;
}
return nullptr;
}
else
{
current_state = result->dispatcher;
return result->analyzer;
}
}
void Manager::Reset()
{
current_state = root_dispatcher;
}
Dispatcher* Manager::GetDispatcher(Config& configuration, const std::string& dispatcher_name)
{
// Is it already created?
if ( dispatchers.count(dispatcher_name) != 0 )
return dispatchers[dispatcher_name];
// Create new dispatcher from config
std::optional<std::reference_wrapper<DispatcherConfig>> dispatcher_config =
configuration.GetDispatcherConfig(dispatcher_name);
if ( ! dispatcher_config )
// No such dispatcher found, this is therefore implicitly a leaf
return nullptr;
const auto& mappings = dispatcher_config->get().GetMappings();
Dispatcher* dispatcher = new VectorDispatcher();
dispatchers.emplace(dispatcher_name, dispatcher);
for ( const auto& current_mapping : mappings )
{
// No analyzer with this name. Report warning and ignore.
if ( analyzers.count(current_mapping.second) == 0 )
{
reporter->InternalWarning("No analyzer %s found for dispatching identifier %#x of %s, ignoring.",
current_mapping.second.c_str(),
current_mapping.first,
dispatcher_name.c_str());
continue;
}
dispatcher->Register(current_mapping.first, analyzers.at(current_mapping.second),
GetDispatcher(configuration, current_mapping.second));
}
return dispatcher;
}