Further simplified the packet analysis API.

This is still WIP and includes the following changes:
* Dispatchers are now part of analyzers (moving dispatching logic from
  the manager to the analyzers)
* All available analyzers are instantiated on start up
* Removal of configuration class
This commit is contained in:
Jan Grashoefer 2020-08-20 18:40:37 +02:00 committed by Tim Wojtulewicz
parent 9feda100b9
commit d4ff5a236c
12 changed files with 104 additions and 340 deletions

View file

@ -1,6 +1,5 @@
// See the file "COPYING" in the main distribution directory for copyright. // See the file "COPYING" in the main distribution directory for copyright.
#include <algorithm>
#include "Analyzer.h" #include "Analyzer.h"
namespace zeek::packet_analysis { namespace zeek::packet_analysis {
@ -20,7 +19,6 @@ Analyzer::Analyzer(const Tag& tag)
Init(tag); Init(tag);
} }
/* PRIVATE */
void Analyzer::Init(const Tag& _tag) void Analyzer::Init(const Tag& _tag)
{ {
tag = _tag; tag = _tag;
@ -41,13 +39,18 @@ const char* Analyzer::GetAnalyzerName() const
bool Analyzer::IsAnalyzer(const char* name) bool Analyzer::IsAnalyzer(const char* name)
{ {
assert(tag); assert(tag);
return packet_mgr->GetComponentName(tag).compare(name) == 0; return packet_mgr->GetComponentName(tag) == name;
}
bool Analyzer::RegisterAnalyzerMapping(uint32_t identifier, AnalyzerPtr analyzer)
{
return dispatcher.Register(identifier, std::move(analyzer));
} }
AnalyzerResult Analyzer::AnalyzeInnerPacket(Packet* packet, AnalyzerResult Analyzer::AnalyzeInnerPacket(Packet* packet,
const uint8_t*& data, uint32_t identifier) const const uint8_t*& data, uint32_t identifier) const
{ {
auto inner_analyzer = packet_mgr->Dispatch(identifier); auto inner_analyzer = dispatcher.Lookup(identifier);
if ( inner_analyzer == nullptr ) if ( inner_analyzer == nullptr )
{ {

View file

@ -10,9 +10,9 @@ namespace zeek::packet_analysis {
/** /**
* Result of packet analysis. * Result of packet analysis.
*/ */
//TODO: Replace with bool?
enum class AnalyzerResult { enum class AnalyzerResult {
Failed, // Analysis failed Failed, // Analysis failed
Continue, // Analysis succeeded and an encapsulated protocol was determined
Terminate // Analysis succeeded and there is no further analysis to do Terminate // Analysis succeeded and there is no further analysis to do
}; };
@ -41,6 +41,13 @@ public:
*/ */
virtual ~Analyzer() = default; virtual ~Analyzer() = default;
/**
* Initialize the analyzer. This method is called after the configuration
* was read. Derived classes can override this method to implement custom
* initialization.
*/
virtual void Initialize() { };
/** /**
* Returns the tag associated with the analyzer's type. * Returns the tag associated with the analyzer's type.
*/ */
@ -62,6 +69,15 @@ public:
*/ */
bool IsAnalyzer(const char* name); 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.
* @return True if the registration was successfull.
*/
bool RegisterAnalyzerMapping(uint32_t identifier, AnalyzerPtr analyzer);
/** /**
* Analyzes the given packet. The data reference points to the part of the * Analyzes the given packet. The data reference points to the part of the
* raw packet to be analyzed. If the analyzed protocol encapsulates another * raw packet to be analyzed. If the analyzed protocol encapsulates another
@ -90,9 +106,11 @@ protected:
* @return The outcome of the analysis. * @return The outcome of the analysis.
*/ */
AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data, AnalyzerResult AnalyzeInnerPacket(Packet* packet, const uint8_t*& data,
uint32_t identifier) const; uint32_t identifier) const;
private: private:
Tag tag; Tag tag;
Dispatcher dispatcher;
void Init(const Tag& tag); void Init(const Tag& tag);
}; };

View file

@ -13,7 +13,6 @@ set(llanalyzer_SRCS
Manager.cc Manager.cc
Component.cc Component.cc
Tag.cc Tag.cc
Config.cc
) )
bro_add_subdir_library(llanalyzer ${llanalyzer_SRCS}) bro_add_subdir_library(llanalyzer ${llanalyzer_SRCS})

View file

@ -1,87 +0,0 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include "Config.h"
#include "Reporter.h"
#include "DebugLogger.h"
namespace zeek::packet_analysis {
// ##############################
// ####### DispatcherConfig #####
// ##############################
const std::string& DispatcherConfig::GetName() const
{
return name;
}
const std::map<uint32_t, std::string>& DispatcherConfig::GetMappings() const
{
return mappings;
}
void DispatcherConfig::AddMapping(uint32_t identifier,
const std::string& analyzer_name)
{
DBG_LOG(DBG_PACKET_ANALYSIS, "Adding configuration mapping: %s -> %#x -> %s",
name.c_str(), identifier, analyzer_name.c_str());
if ( mappings.count(identifier) )
reporter->InternalError("Invalid config, identifier %#x already exists "
"for dispatcher set %s.",
identifier, name.c_str());
mappings.emplace(identifier, analyzer_name);
}
bool DispatcherConfig::operator==(const DispatcherConfig& rhs) const
{
return name == rhs.name;
}
bool DispatcherConfig::operator!=(const DispatcherConfig& rhs) const
{
return ! (rhs == *this);
}
// ##############################
// ########### Config ###########
// ##############################
std::optional<std::reference_wrapper<DispatcherConfig>>
Config::GetDispatcherConfig(const std::string& name)
{
auto it = std::find_if(
dispatchers.begin(), dispatchers.end(),
[&](const DispatcherConfig& conf) {
return conf.GetName() == name;
});
if ( it == dispatchers.end() )
return {};
else
return {std::ref(*it)};
}
const std::vector<DispatcherConfig>& Config::GetDispatchers() const
{
return dispatchers;
}
DispatcherConfig& Config::AddDispatcherConfig(const std::string& name)
{
return dispatchers.emplace_back(name);
}
void Config::AddMapping(const std::string& name, uint32_t identifier,
const std::string& analyzer_name)
{
// Create dispatcher config if it does not exist yet
std::optional<std::reference_wrapper<DispatcherConfig>> dispatch_config =
GetDispatcherConfig(name);
if ( ! dispatch_config )
AddDispatcherConfig(name).AddMapping(identifier, analyzer_name);
else
dispatch_config->get().AddMapping(identifier, analyzer_name);
}
} // namespace packet_analysis

View file

@ -1,42 +0,0 @@
// See the file "COPYING" in the main distribution directory for copyright.
#pragma once
#include <algorithm>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace zeek::packet_analysis {
class DispatcherConfig {
public:
explicit DispatcherConfig(const std::string name) : name(std::move(name)) { }
const std::string& GetName() const;
const std::map<uint32_t, std::string>& GetMappings() const;
void AddMapping(uint32_t identifier, const std::string& analyzer_name);
bool operator==(const DispatcherConfig& rhs) const;
bool operator!=(const DispatcherConfig& rhs) const;
private:
const std::string name;
std::map<uint32_t, std::string> mappings;
};
class Config {
public:
const std::vector<DispatcherConfig>& GetDispatchers() const;
std::optional<std::reference_wrapper<DispatcherConfig>> GetDispatcherConfig(const std::string& name);
DispatcherConfig& AddDispatcherConfig(const std::string& name);
void AddMapping(const std::string& name, uint32_t identifier, const std::string& analyzer_name);
private:
std::vector<DispatcherConfig> dispatchers;
};
}

View file

@ -3,6 +3,8 @@
#include <algorithm> #include <algorithm>
#include "Dispatcher.h" #include "Dispatcher.h"
#include "Analyzer.h"
#include "DebugLogger.h"
namespace zeek::packet_analysis { namespace zeek::packet_analysis {
@ -11,12 +13,12 @@ Dispatcher::~Dispatcher()
FreeValues(); FreeValues();
} }
bool Dispatcher::Register(uint32_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher) bool Dispatcher::Register(uint32_t identifier, AnalyzerPtr analyzer)
{ {
// If the table has size 1 and the entry is nullptr, there was nothing added yet. Just add it. // If the table has size 1 and the entry is nullptr, there was nothing added yet. Just add it.
if ( table.size() == 1 && table[0] == nullptr ) if ( table.size() == 1 && table[0] == nullptr )
{ {
table[0] = std::make_shared<Value>(analyzer, dispatcher); table[0] = analyzer;
lowest_identifier = identifier; lowest_identifier = identifier;
return true; return true;
} }
@ -48,7 +50,7 @@ bool Dispatcher::Register(uint32_t identifier, AnalyzerPtr analyzer, DispatcherP
int64_t index = identifier - lowest_identifier; int64_t index = identifier - lowest_identifier;
if ( table[index] == nullptr ) if ( table[index] == nullptr )
{ {
table[index] = std::make_shared<Value>(analyzer, dispatcher); table[index] = analyzer;
return true; return true;
} }
@ -65,19 +67,19 @@ void Dispatcher::Register(const register_map& data)
}); });
// Register lowest first in order to do shifting only once // Register lowest first in order to do shifting only once
Register(lowest_new->first, lowest_new->second.first, lowest_new->second.second); Register(lowest_new->first, lowest_new->second);
for ( auto i = data.begin(); i != data.end(); i++ ) for ( auto i = data.begin(); i != data.end(); i++ )
{ {
// Already added if i == lowest_new // Already added if i == lowest_new
if ( i == lowest_new ) if ( i == lowest_new )
continue; continue;
if ( ! Register(i->first, i->second.first, i->second.second) ) if ( ! Register(i->first, i->second) )
throw std::invalid_argument("Analyzer already registered!"); throw std::invalid_argument("Analyzer already registered!");
} }
} }
ValuePtr Dispatcher::Lookup(uint32_t identifier) const AnalyzerPtr Dispatcher::Lookup(uint32_t identifier) const
{ {
int64_t index = identifier - lowest_identifier; int64_t index = identifier - lowest_identifier;
if ( index >= 0 && index < static_cast<int64_t>(table.size()) && table[index] != nullptr ) if ( index >= 0 && index < static_cast<int64_t>(table.size()) && table[index] != nullptr )
@ -88,7 +90,7 @@ ValuePtr Dispatcher::Lookup(uint32_t identifier) const
size_t Dispatcher::Size() const size_t Dispatcher::Size() const
{ {
return std::count_if(table.begin(), table.end(), [](ValuePtr v) { return v != nullptr; }); return std::count_if(table.begin(), table.end(), [](AnalyzerPtr a) { return a != nullptr; });
} }
void Dispatcher::Clear() void Dispatcher::Clear()
@ -111,7 +113,7 @@ void Dispatcher::DumpDebug() const
for ( size_t i = 0; i < table.size(); i++ ) for ( size_t i = 0; i < table.size(); i++ )
{ {
if ( table[i] != nullptr ) if ( table[i] != nullptr )
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8lx => %s, %p", i+lowest_identifier, table[i]->analyzer->GetAnalyzerName(), table[i]->dispatcher.get()); DBG_LOG(DBG_PACKET_ANALYSIS, " %#8lx => %s", i+lowest_identifier, table[i]->GetAnalyzerName());
} }
#endif #endif
} }

View file

@ -2,43 +2,31 @@
#pragma once #pragma once
#include <utility> #include <memory>
#include <map>
#include <cstdint>
#include <vector> #include <vector>
#include "Analyzer.h"
namespace zeek::packet_analysis { namespace zeek::packet_analysis {
class Dispatcher; // Forward decl for Value class Analyzer; // Forward declaration for Value
using DispatcherPtr = std::shared_ptr<Dispatcher>; using AnalyzerPtr = std::shared_ptr<zeek::packet_analysis::Analyzer>;
using register_pair = std::pair<uint32_t, std::pair<AnalyzerPtr, DispatcherPtr>>; using register_pair = std::pair<uint32_t, AnalyzerPtr>;
using register_map = std::map<uint32_t, std::pair<AnalyzerPtr, DispatcherPtr>>; using register_map = std::map<uint32_t, AnalyzerPtr>;
class Value {
public:
AnalyzerPtr analyzer;
DispatcherPtr dispatcher;
Value(AnalyzerPtr analyzer, DispatcherPtr dispatcher)
: analyzer(analyzer), dispatcher(dispatcher)
{
}
};
using ValuePtr = std::shared_ptr<Value>;
class Dispatcher { class Dispatcher {
public: public:
Dispatcher() Dispatcher()
: table(std::vector<ValuePtr>(1, nullptr)) : table(std::vector<AnalyzerPtr>(1, nullptr))
{ } { }
~Dispatcher(); ~Dispatcher();
bool Register(uint32_t identifier, AnalyzerPtr analyzer, DispatcherPtr dispatcher); bool Register(uint32_t identifier, AnalyzerPtr analyzer);
void Register(const register_map& data); void Register(const register_map& data);
ValuePtr Lookup(uint32_t identifier) const; AnalyzerPtr Lookup(uint32_t identifier) const;
size_t Size() const; size_t Size() const;
void Clear(); void Clear();
@ -46,7 +34,7 @@ public:
private: private:
uint32_t lowest_identifier = 0; uint32_t lowest_identifier = 0;
std::vector<ValuePtr> table; std::vector<AnalyzerPtr> table;
void FreeValues(); void FreeValues();

View file

@ -2,12 +2,7 @@
#include "Manager.h" #include "Manager.h"
#include <list>
#include <pcap.h>
#include "Config.h"
#include "NetVar.h" #include "NetVar.h"
#include "plugin/Manager.h"
#include "Analyzer.h" #include "Analyzer.h"
#include "Dispatcher.h" #include "Dispatcher.h"
@ -18,13 +13,17 @@ Manager::Manager()
{ {
} }
Manager::~Manager()
{
}
void Manager::InitPostScript() void Manager::InitPostScript()
{ {
auto analyzer_mapping = zeek::id::find("PacketAnalyzer::config_map"); // Instantiate objects for all available analyzers
for ( const auto& analyzerComponent : GetComponents() )
{
if ( AnalyzerPtr newAnalyzer = InstantiateAnalyzer(analyzerComponent->Tag()) )
analyzers.emplace(analyzerComponent->Name(), newAnalyzer);
}
// Read in analyzer map and create dispatchers
auto& analyzer_mapping = zeek::id::find("PacketAnalyzer::config_map");
if ( ! analyzer_mapping ) if ( ! analyzer_mapping )
return; return;
@ -32,50 +31,48 @@ void Manager::InitPostScript()
if ( mapping_val->Size() == 0 ) if ( mapping_val->Size() == 0 )
return; return;
Config configuration;
for (unsigned int i = 0; i < mapping_val->Size(); i++) for (unsigned int i = 0; i < mapping_val->Size(); i++)
{ {
auto* rv = mapping_val->At(i)->AsRecordVal(); auto* rv = mapping_val->At(i)->AsRecordVal();
auto parent = rv->GetField("parent"); //TODO: Make that field a string for usability reasons
std::string parent_name = parent ? Lookup(parent->AsEnumVal())->Name() : "ROOT"; //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 identifier = rv->GetField("identifier")->AsCount();
auto analyzer = rv->GetField("analyzer")->AsEnumVal(); auto analyzer_tag = rv->GetField("analyzer")->AsEnumVal();
auto analyzer_name = Lookup(analyzer_tag)->Name();
configuration.AddMapping(parent_name, identifier, Lookup(analyzer)->Name()); if ( analyzers.find(analyzer_name) == analyzers.end() )
}
// 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 reporter->InternalWarning("Mapped analyzer %s not found.", analyzer_name.c_str());
if ( analyzers.count(current_mapping.second) != 0 ) continue;
continue;
// Check if analyzer exists
if ( AnalyzerPtr newAnalyzer = InstantiateAnalyzer(current_mapping.second) )
analyzers.emplace(current_mapping.second, newAnalyzer);
} }
if ( parent_name == "ROOT" )
{
root_dispatcher.Register(identifier, analyzers[analyzer_name]);
continue;
}
if ( analyzers.find(parent_name) == analyzers.end() )
{
reporter->InternalWarning("Parent analyzer %s not found.", parent_name.c_str());
continue;
}
auto& parent_analyzer = analyzers[parent_name];
parent_analyzer->RegisterAnalyzerMapping(identifier, analyzers[analyzer_name]);
} }
// Generate Dispatchers, starting at root // Set default analyzer
root_dispatcher = GetDispatcher(configuration, "ROOT"); auto da_it = analyzers.find("DefaultAnalyzer");
if ( root_dispatcher == nullptr ) if ( da_it == analyzers.end() )
reporter->InternalError("No dispatching configuration for ROOT of packet_analysis set."); reporter->InternalError("DefaultAnalyzer not found.");
default_analyzer = da_it->second;
// Set up default analysis // Initialize all analyzers
auto it = analyzers.find("DefaultAnalyzer"); for ( auto& [name, analyzer] : analyzers )
if ( it != analyzers.end() ) analyzer->Initialize();
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() void Manager::Done()
@ -90,13 +87,6 @@ void Manager::DumpDebug()
{ {
DBG_LOG(DBG_PACKET_ANALYSIS, " %s", current->Name().c_str()); DBG_LOG(DBG_PACKET_ANALYSIS, " %s", current->Name().c_str());
} }
DBG_LOG(DBG_PACKET_ANALYSIS, "ProtocolAnalyzerSet FSM:");
for ( const auto& current : dispatchers )
{
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher (%p): %s", current.second.get(), current.first.c_str());
current.second->DumpDebug();
}
#endif #endif
} }
@ -128,7 +118,6 @@ AnalyzerPtr Manager::InstantiateAnalyzer(const Tag& tag)
{ {
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 nullptr;
} }
return a; return a;
@ -146,29 +135,18 @@ void Manager::ProcessPacket(Packet* packet)
static size_t counter = 0; static size_t counter = 0;
DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time); DBG_LOG(DBG_PACKET_ANALYSIS, "Analyzing packet %ld, ts=%.3f...", ++counter, packet->time);
#endif #endif
// Start packet analysis // Start packet analysis
const uint8_t* data = packet->data; const uint8_t* data = packet->data;
auto root_analyzer = Dispatch(packet->link_type); auto root_analyzer = root_dispatcher.Lookup(packet->link_type);
if ( root_analyzer == nullptr ) auto analyzer = root_analyzer == nullptr ? default_analyzer : root_analyzer;
{
DBG_LOG(DBG_PACKET_ANALYSIS, "No analyzer for link type: %#x.", packet->link_type);
packet->Weird("no_suitable_analyzer_found");
}
else
{
auto result = root_analyzer->Analyze(packet, data);
if (result == AnalyzerResult::Terminate) auto result = analyzer->Analyze(packet, data);
CustomEncapsulationSkip(packet, data); if (result == AnalyzerResult::Terminate)
} CustomEncapsulationSkip(packet, data);
// Processing finished, reset analyzer set state for next packet
current_state = root_dispatcher;
// Calculate header size after processing packet layers. // Calculate header size after processing packet layers.
packet->hdr_size = data - packet->data; 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)
@ -203,67 +181,3 @@ void Manager::CustomEncapsulationSkip(Packet* packet, const uint8_t* data)
} }
} }
} }
AnalyzerPtr Manager::Dispatch(uint32_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)
ValuePtr 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;
}
}
DispatcherPtr 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();
DispatcherPtr dispatcher = std::make_shared<Dispatcher>();
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;
}

View file

@ -2,23 +2,16 @@
#pragma once #pragma once
#include <queue>
#include <vector>
#include "Config.h"
#include "Tag.h" #include "Tag.h"
#include "Component.h" #include "Component.h"
#include "plugin/ComponentManager.h" #include "plugin/ComponentManager.h"
#include "iosource/Packet.h" #include "iosource/Packet.h"
#include "Dict.h" #include "Dispatcher.h"
#include "net_util.h"
namespace zeek::packet_analysis { namespace zeek::packet_analysis {
class Analyzer; class Analyzer;
class Dispatcher;
using AnalyzerPtr = std::shared_ptr<Analyzer>; using AnalyzerPtr = std::shared_ptr<Analyzer>;
using DispatcherPtr = std::shared_ptr<Dispatcher>;
class Manager : public plugin::ComponentManager<Tag, Component> { class Manager : public plugin::ComponentManager<Tag, Component> {
public: public:
@ -30,7 +23,7 @@ public:
/** /**
* Destructor. * Destructor.
*/ */
~Manager(); ~Manager() = default;
/** /**
* Second-stage initialization of the manager. This is called late * Second-stage initialization of the manager. This is called late
@ -50,14 +43,6 @@ public:
*/ */
void DumpDebug(); // Called after zeek_init() events. void DumpDebug(); // Called after zeek_init() events.
/**
* Returns the tag associated with an analyer name, or the tag
* associated with an error if no such analyzer exists.
*
* @param name The canonical analyzer name to check.
*/
Tag GetAnalyzerTag(const char* name);
/** /**
* Instantiates a new analyzer instance. * Instantiates a new analyzer instance.
* *
@ -87,18 +72,7 @@ public:
*/ */
void ProcessPacket(Packet* packet); void ProcessPacket(Packet* packet);
/**
* Looks up a packet analyzer by identifier considering the context
* as given by current_state.
*
* @param identifier The identifier to look up.
*
* @return The analyzer corresponding to the identifier.
*/
AnalyzerPtr Dispatch(uint32_t identifier);
private: private:
/** /**
* 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.
@ -109,13 +83,8 @@ private:
*/ */
void CustomEncapsulationSkip(Packet* packet, const uint8_t* data); void CustomEncapsulationSkip(Packet* packet, const uint8_t* data);
DispatcherPtr GetDispatcher(Config& configuration, const std::string& dispatcher_name);
std::map<std::string, AnalyzerPtr> analyzers; std::map<std::string, AnalyzerPtr> analyzers;
std::map<std::string, DispatcherPtr> dispatchers; Dispatcher root_dispatcher;
DispatcherPtr root_dispatcher = nullptr;
DispatcherPtr default_dispatcher = nullptr;
DispatcherPtr current_state = nullptr;
AnalyzerPtr default_analyzer = nullptr; AnalyzerPtr default_analyzer = nullptr;
}; };

View file

@ -1,5 +1,5 @@
#add_subdirectory(default) add_subdirectory(default)
#
#add_subdirectory(wrapper) #add_subdirectory(wrapper)
#add_subdirectory(null) #add_subdirectory(null)
add_subdirectory(ethernet) add_subdirectory(ethernet)

View file

@ -10,17 +10,17 @@ DefaultAnalyzer::DefaultAnalyzer()
{ {
} }
zeek::packet_analysis::AnalysisResultTuple DefaultAnalyzer::Analyze(Packet* packet, const uint8_t*& data) zeek::packet_analysis::AnalyzerResult DefaultAnalyzer::Analyze(Packet* packet, const uint8_t*& data)
{ {
// Assume we're pointing at IP. Just figure out which version. // Assume we're pointing at IP. Just figure out which version.
if ( data + 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;
} }
auto ip = (const struct ip *)data; auto ip = (const struct ip *)data;
uint32_t protocol = ip->ip_v; uint32_t protocol = ip->ip_v;
return { AnalyzerResult::Continue, protocol }; return AnalyzeInnerPacket(packet, data, protocol);
} }

View file

@ -12,7 +12,7 @@ public:
DefaultAnalyzer(); DefaultAnalyzer();
~DefaultAnalyzer() override = default; ~DefaultAnalyzer() override = default;
AnalysisResultTuple 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()
{ {