mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 17:48:21 +00:00
Renamed LL-Analyzers to Packet Analyzers.
This commit is contained in:
parent
b2e6c9ac9a
commit
e53ec46c23
148 changed files with 587 additions and 587 deletions
47
src/packet_analysis/Analyzer.cc
Normal file
47
src/packet_analysis/Analyzer.cc
Normal file
|
@ -0,0 +1,47 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <algorithm>
|
||||
#include "Analyzer.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
Analyzer::Analyzer(std::string name)
|
||||
{
|
||||
Tag t = packet_mgr->GetComponentTag(name);
|
||||
|
||||
if ( ! t )
|
||||
reporter->InternalError("unknown packet_analysis name %s", name.c_str());
|
||||
|
||||
Init(t);
|
||||
}
|
||||
|
||||
Analyzer::Analyzer(const Tag& tag)
|
||||
{
|
||||
Init(tag);
|
||||
}
|
||||
|
||||
/* PRIVATE */
|
||||
void Analyzer::Init(const Tag& _tag)
|
||||
{
|
||||
tag = _tag;
|
||||
}
|
||||
|
||||
const Tag Analyzer::GetAnalyzerTag() const
|
||||
{
|
||||
assert(tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
const char* Analyzer::GetAnalyzerName() const
|
||||
{
|
||||
assert(tag);
|
||||
return packet_mgr->GetComponentName(tag).c_str();
|
||||
}
|
||||
|
||||
bool Analyzer::IsAnalyzer(const char* name)
|
||||
{
|
||||
assert(tag);
|
||||
return packet_mgr->GetComponentName(tag).compare(name) == 0;
|
||||
}
|
||||
|
||||
}
|
89
src/packet_analysis/Analyzer.h
Normal file
89
src/packet_analysis/Analyzer.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
#pragma once
|
||||
|
||||
#include "Defines.h"
|
||||
#include "Manager.h"
|
||||
#include "Tag.h"
|
||||
#include <iosource/Packet.h>
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
/**
|
||||
* Result of packet analysis.
|
||||
*/
|
||||
enum class AnalyzerResult {
|
||||
Failed, // Analysis failed
|
||||
Continue, // Analysis succeeded and an encapsulated protocol was determined
|
||||
Terminate // Analysis succeeded and there is no further analysis to do
|
||||
};
|
||||
|
||||
using AnalysisResultTuple = std::tuple<AnalyzerResult, identifier_t>;
|
||||
|
||||
class Analyzer {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param name The name for the type of analyzer. The name must match
|
||||
* the one the corresponding Component registers.
|
||||
*/
|
||||
explicit Analyzer(std::string name);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param tag The tag for the type of analyzer. The tag must map to
|
||||
* the name the corresponding Component registers.
|
||||
*/
|
||||
explicit Analyzer(const Tag& tag);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Analyzer() = default;
|
||||
|
||||
/**
|
||||
* Returns the tag associated with the analyzer's type.
|
||||
*/
|
||||
const Tag GetAnalyzerTag() const;
|
||||
|
||||
/**
|
||||
* Returns a textual description of the analyzer's type. This is
|
||||
* what's passed to the constructor and usually corresponds to the
|
||||
* protocol name, e.g., "ARP".
|
||||
*/
|
||||
const char* GetAnalyzerName() const;
|
||||
|
||||
/**
|
||||
* Returns true if this analyzer's type matches the name passes in.
|
||||
* This is shortcut for comparing GetAnalyzerName() with the given
|
||||
* name.
|
||||
*
|
||||
* @param name The name to check.
|
||||
*/
|
||||
bool IsAnalyzer(const char* name);
|
||||
|
||||
/**
|
||||
* Analyzes the given packet. The analysis is supposed to start at cur_pos
|
||||
* of the packet, which points to the so far unanalyzed part of the packet.
|
||||
* If the analyzed protocol encapsulates another protocol, the packet's
|
||||
* cur_pos should be updated to point to that payload.
|
||||
*
|
||||
* @param packet The packet to analyze.
|
||||
*
|
||||
* @return A tuple of analysis result and identifier. The result indicates
|
||||
* how to proceed. If analysis can continue, the identifier determines the
|
||||
* encapsulated protocol.
|
||||
*/
|
||||
virtual std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) = 0;
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
private:
|
||||
Tag tag;
|
||||
|
||||
void Init(const Tag& tag);
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/AnalyzerSet.h
Normal file
24
src/packet_analysis/AnalyzerSet.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "Defines.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class Analyzer;
|
||||
|
||||
class AnalyzerSet {
|
||||
public:
|
||||
virtual ~AnalyzerSet() = default;
|
||||
virtual Analyzer* Dispatch(identifier_t identifier) = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
virtual void DumpDebug() const = 0;
|
||||
};
|
||||
|
||||
}
|
21
src/packet_analysis/CMakeLists.txt
Normal file
21
src/packet_analysis/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
include(ZeekSubdir)
|
||||
|
||||
include_directories(BEFORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
add_subdirectory(protocol)
|
||||
add_subdirectory(dispatchers)
|
||||
|
||||
set(llanalyzer_SRCS
|
||||
Analyzer.cc
|
||||
ProtocolAnalyzerSet.cc
|
||||
Manager.cc
|
||||
Component.cc
|
||||
Tag.cc
|
||||
Config.cc
|
||||
)
|
||||
|
||||
bro_add_subdir_library(llanalyzer ${llanalyzer_SRCS})
|
||||
add_dependencies(bro_llanalyzer generate_outputs)
|
33
src/packet_analysis/Component.cc
Normal file
33
src/packet_analysis/Component.cc
Normal file
|
@ -0,0 +1,33 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Component.h"
|
||||
#include "Desc.h"
|
||||
#include "Manager.h"
|
||||
|
||||
using namespace zeek::packet_analysis;
|
||||
|
||||
Component::Component(const std::string& name, factory_callback arg_factory, Tag::subtype_t arg_subtype, bool arg_enabled)
|
||||
: plugin::Component(plugin::component::PACKET_ANALYZER, name),
|
||||
plugin::TaggedComponent<packet_analysis::Tag>(arg_subtype)
|
||||
{
|
||||
factory = arg_factory;
|
||||
enabled = arg_enabled;
|
||||
}
|
||||
|
||||
void Component::Initialize()
|
||||
{
|
||||
InitializeTag();
|
||||
packet_mgr->RegisterComponent(this, "ANALYZER_");
|
||||
}
|
||||
|
||||
void Component::DoDescribe(ODesc* d) const
|
||||
{
|
||||
if ( factory )
|
||||
{
|
||||
d->Add("ANALYZER_");
|
||||
d->Add(CanonicalName());
|
||||
d->Add(", ");
|
||||
}
|
||||
|
||||
d->Add(enabled ? "enabled" : "disabled");
|
||||
}
|
61
src/packet_analysis/Component.h
Normal file
61
src/packet_analysis/Component.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "zeek-config.h"
|
||||
#include "util.h"
|
||||
#include "Tag.h"
|
||||
|
||||
#include "plugin/Component.h"
|
||||
#include "plugin/TaggedComponent.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class Analyzer;
|
||||
|
||||
class Component : public plugin::Component,
|
||||
public plugin::TaggedComponent<packet_analysis::Tag> {
|
||||
public:
|
||||
typedef Analyzer* (*factory_callback)();
|
||||
|
||||
Component(const std::string& name, factory_callback factory, Tag::subtype_t subtype = 0, bool enabled = true);
|
||||
~Component() override = default;
|
||||
|
||||
/**
|
||||
* Initialization function. This function has to be called before any
|
||||
* plugin component functionality is used; it is used to add the
|
||||
* plugin component to the list of components and to initialize tags
|
||||
*/
|
||||
void Initialize() override;
|
||||
|
||||
/**
|
||||
* Returns the analyzer's factory function.
|
||||
*/
|
||||
factory_callback Factory() const { return factory; }
|
||||
|
||||
/**
|
||||
* Returns true if the analyzer is currently enabled and hence
|
||||
* available for use.
|
||||
*/
|
||||
bool Enabled() const { return enabled; }
|
||||
|
||||
/**
|
||||
* Enables or disables this analyzer.
|
||||
*
|
||||
* @param arg_enabled True to enabled, false to disable.
|
||||
*
|
||||
*/
|
||||
void SetEnabled(bool arg_enabled) { enabled = arg_enabled; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Overriden from plugin::Component.
|
||||
*/
|
||||
void DoDescribe(ODesc* d) const override;
|
||||
|
||||
private:
|
||||
factory_callback factory; // The analyzer's factory callback.
|
||||
bool enabled; // True if the analyzer is enabled.
|
||||
};
|
||||
|
||||
}
|
87
src/packet_analysis/Config.cc
Normal file
87
src/packet_analysis/Config.cc
Normal file
|
@ -0,0 +1,87 @@
|
|||
// 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<identifier_t, std::string>& DispatcherConfig::GetMappings() const
|
||||
{
|
||||
return mappings;
|
||||
}
|
||||
|
||||
void DispatcherConfig::AddMapping(identifier_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, identifier_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
|
44
src/packet_analysis/Config.h
Normal file
44
src/packet_analysis/Config.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Defines.h"
|
||||
|
||||
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<identifier_t, std::string>& GetMappings() const;
|
||||
|
||||
void AddMapping(identifier_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<identifier_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, identifier_t identifier, const std::string& analyzer_name);
|
||||
|
||||
private:
|
||||
std::vector<DispatcherConfig> dispatchers;
|
||||
};
|
||||
|
||||
}
|
11
src/packet_analysis/Defines.h
Normal file
11
src/packet_analysis/Defines.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
using identifier_t = uint32_t;
|
||||
|
||||
}
|
285
src/packet_analysis/Manager.cc
Normal file
285
src/packet_analysis/Manager.cc
Normal file
|
@ -0,0 +1,285 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <list>
|
||||
#include <pcap.h>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Manager.h"
|
||||
#include "NetVar.h"
|
||||
#include "ProtocolAnalyzerSet.h"
|
||||
#include "plugin/Manager.h"
|
||||
|
||||
using namespace zeek::packet_analysis;
|
||||
|
||||
Manager::Manager()
|
||||
: plugin::ComponentManager<packet_analysis::Tag, packet_analysis::Component>("PacketAnalyzer", "Tag")
|
||||
{
|
||||
}
|
||||
|
||||
Manager::~Manager()
|
||||
{
|
||||
delete analyzer_set;
|
||||
}
|
||||
|
||||
void Manager::InitPostScript()
|
||||
{
|
||||
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;
|
||||
|
||||
Config configuration;
|
||||
for (unsigned int i = 0; i < mapping_val->Size(); i++)
|
||||
{
|
||||
auto* rv = mapping_val->At(i)->AsRecordVal();
|
||||
auto parent = rv->GetField("parent");
|
||||
std::string parent_name = parent ? Lookup(parent->AsEnumVal())->Name() : "ROOT";
|
||||
auto identifier = rv->GetField("identifier")->AsCount();
|
||||
auto analyzer = rv->GetField("analyzer")->AsEnumVal();
|
||||
|
||||
configuration.AddMapping(parent_name, identifier, Lookup(analyzer)->Name());
|
||||
}
|
||||
|
||||
analyzer_set = new ProtocolAnalyzerSet(configuration, "DefaultAnalyzer");
|
||||
}
|
||||
|
||||
void Manager::Done()
|
||||
{
|
||||
}
|
||||
|
||||
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 (%s)", current->Name().c_str(), IsEnabled(current->Tag()) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
// Dump Analyzer Set
|
||||
if (analyzer_set)
|
||||
analyzer_set->DumpDebug();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Manager::EnableAnalyzer(const Tag& tag)
|
||||
{
|
||||
Component* p = Lookup(tag);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Enabling analyzer %s", p->Name().c_str());
|
||||
p->SetEnabled(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Manager::EnableAnalyzer(EnumVal* val)
|
||||
{
|
||||
Component* p = Lookup(val);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Enabling analyzer %s", p->Name().c_str());
|
||||
p->SetEnabled(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Manager::DisableAnalyzer(const Tag& tag)
|
||||
{
|
||||
Component* p = Lookup(tag);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Disabling analyzer %s", p->Name().c_str());
|
||||
p->SetEnabled(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Manager::DisableAnalyzer(EnumVal* val)
|
||||
{
|
||||
Component* p = Lookup(val);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Disabling analyzer %s", p->Name().c_str());
|
||||
p->SetEnabled(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Manager::DisableAllAnalyzers()
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Disabling all analyzers");
|
||||
|
||||
std::list<Component*> all_analyzers = GetComponents();
|
||||
for ( const auto& analyzer : all_analyzers )
|
||||
analyzer->SetEnabled(false);
|
||||
}
|
||||
|
||||
zeek::packet_analysis::Tag Manager::GetAnalyzerTag(const char* name)
|
||||
{
|
||||
return GetComponentTag(name);
|
||||
}
|
||||
|
||||
bool Manager::IsEnabled(Tag tag)
|
||||
{
|
||||
if ( ! tag )
|
||||
return false;
|
||||
|
||||
Component* p = Lookup(tag);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
return p->Enabled();
|
||||
}
|
||||
|
||||
bool Manager::IsEnabled(EnumVal* val)
|
||||
{
|
||||
Component* p = Lookup(val);
|
||||
|
||||
if ( ! p )
|
||||
return false;
|
||||
|
||||
return p->Enabled();
|
||||
}
|
||||
|
||||
Analyzer* Manager::InstantiateAnalyzer(const Tag& tag)
|
||||
{
|
||||
Component* c = Lookup(tag);
|
||||
|
||||
if ( ! c )
|
||||
{
|
||||
reporter->InternalWarning("request to instantiate unknown packet_analysis");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( ! c->Enabled() )
|
||||
return nullptr;
|
||||
|
||||
if ( ! c->Factory() )
|
||||
{
|
||||
reporter->InternalWarning("analyzer %s cannot be instantiated dynamically", GetComponentName(tag).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Analyzer* a = c->Factory()();
|
||||
|
||||
if ( ! a )
|
||||
{
|
||||
reporter->InternalWarning("analyzer instantiation failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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.",
|
||||
GetComponentName(tag).c_str(), GetComponentName(a->GetAnalyzerTag()).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
Analyzer* Manager::InstantiateAnalyzer(const std::string& name)
|
||||
{
|
||||
Tag tag = GetComponentTag(name);
|
||||
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
|
||||
|
||||
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);
|
||||
|
||||
// Analyzer not found
|
||||
if ( current_analyzer == nullptr )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Could not find analyzer for identifier %#x", next_layer_id);
|
||||
packet->Weird("no_suitable_analyzer_found");
|
||||
break;
|
||||
}
|
||||
|
||||
// Analyze this layer and get identifier of next layer protocol
|
||||
std::tie(result, next_layer_id) = current_analyzer->Analyze(packet);
|
||||
|
||||
#ifdef DEBUG
|
||||
switch ( result )
|
||||
{
|
||||
case AnalyzerResult::Continue:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||
current_analyzer->GetAnalyzerName(), next_layer_id);
|
||||
break;
|
||||
case AnalyzerResult::Terminate:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Done, last found layer identifier was %#x.", next_layer_id);
|
||||
break;
|
||||
case AnalyzerResult::Failed:
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis failed in %s", current_analyzer->GetAnalyzerName());
|
||||
}
|
||||
#endif
|
||||
|
||||
} while ( result == AnalyzerResult::Continue );
|
||||
|
||||
if ( result == AnalyzerResult::Terminate )
|
||||
CustomEncapsulationSkip(packet);
|
||||
|
||||
// Processing finished, reset analyzer set state for next packet
|
||||
analyzer_set->Reset();
|
||||
}
|
||||
|
||||
void Manager::CustomEncapsulationSkip(Packet* packet)
|
||||
{
|
||||
if ( zeek::detail::encap_hdr_size > 0 )
|
||||
{
|
||||
auto pdata = packet->cur_pos;
|
||||
|
||||
// Blanket encapsulation. We assume that what remains is IP.
|
||||
if ( pdata + zeek::detail::encap_hdr_size + sizeof(struct ip) >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("no_ip_left_after_encap");
|
||||
return;
|
||||
}
|
||||
|
||||
pdata += zeek::detail::encap_hdr_size;
|
||||
|
||||
auto ip = (const struct ip*)pdata;
|
||||
|
||||
switch ( ip->ip_v )
|
||||
{
|
||||
case 4:
|
||||
packet->l3_proto = L3_IPV4;
|
||||
break;
|
||||
case 6:
|
||||
packet->l3_proto = L3_IPV6;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Neither IPv4 nor IPv6.
|
||||
packet->Weird("no_ip_in_encap");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
167
src/packet_analysis/Manager.h
Normal file
167
src/packet_analysis/Manager.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "Tag.h"
|
||||
#include "Analyzer.h"
|
||||
#include "Component.h"
|
||||
#include "AnalyzerSet.h"
|
||||
#include "plugin/ComponentManager.h"
|
||||
#include "iosource/Packet.h"
|
||||
|
||||
#include "../Dict.h"
|
||||
#include "../net_util.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class AnalyzerSet;
|
||||
|
||||
class Manager : public plugin::ComponentManager<Tag, Component> {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
Manager();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Manager();
|
||||
|
||||
/**
|
||||
* Second-stage initialization of the manager. This is called late
|
||||
* during Zeek's initialization after any scripts are processed.
|
||||
*/
|
||||
void InitPostScript();
|
||||
|
||||
/**
|
||||
* Finished the manager's operations.
|
||||
*/
|
||||
void Done();
|
||||
|
||||
/**
|
||||
* Dumps out the state of all registered analyzers to the \c analyzer
|
||||
* debug stream. Should be called only after any \c zeek_init events
|
||||
* have executed to ensure that any of their changes are applied.
|
||||
*/
|
||||
void DumpDebug(); // Called after zeek_init() events.
|
||||
|
||||
/**
|
||||
* Enables an analyzer type. Only enabled analyzers will be
|
||||
* instantiated for new connections.
|
||||
*
|
||||
* @param tag The analyzer's tag.
|
||||
*
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool EnableAnalyzer(const Tag& tag);
|
||||
|
||||
/**
|
||||
* Enables an analyzer type. Only enabled analyzers will be
|
||||
* instantiated for new connections.
|
||||
*
|
||||
* @param tag The analyzer's tag as an enum of script type \c
|
||||
* Analyzer::Tag.
|
||||
*
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool EnableAnalyzer(EnumVal* tag);
|
||||
|
||||
/**
|
||||
* Enables an analyzer type. Disabled analyzers will not be
|
||||
* instantiated for new connections.
|
||||
*
|
||||
* @param tag The analyzer's tag.
|
||||
*
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool DisableAnalyzer(const Tag& tag);
|
||||
|
||||
/**
|
||||
* Disables an analyzer type. Disabled analyzers will not be
|
||||
* instantiated for new connections.
|
||||
*
|
||||
* @param tag The analyzer's tag as an enum of script type \c
|
||||
* Analyzer::Tag.
|
||||
*
|
||||
* @return True if successful.
|
||||
*/
|
||||
bool DisableAnalyzer(EnumVal* tag);
|
||||
|
||||
/**
|
||||
* Disables all currently registered analyzers.
|
||||
*/
|
||||
void DisableAllAnalyzers();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Returns true if an analyzer is enabled.
|
||||
*
|
||||
* @param tag The analyzer's tag.
|
||||
*/
|
||||
bool IsEnabled(Tag tag);
|
||||
|
||||
/**
|
||||
* Returns true if an analyzer is enabled.
|
||||
*
|
||||
* @param tag The analyzer's tag as an enum of script type \c
|
||||
* Analyzer::Tag.
|
||||
*/
|
||||
bool IsEnabled(EnumVal* tag);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Analyzer* 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.
|
||||
*/
|
||||
Analyzer* InstantiateAnalyzer(const std::string& name);
|
||||
|
||||
/**
|
||||
* Processes a packet by applying the configured low layer analyzers.
|
||||
*
|
||||
* @param packet The packet to process.
|
||||
*/
|
||||
void ProcessPacket(Packet* packet);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Skips a fixed amount of packet data that is defined by encap_hdr_size.
|
||||
* It is assumed that an IP header follows.
|
||||
*
|
||||
* @param packet The packet to adapt.
|
||||
*/
|
||||
void CustomEncapsulationSkip(Packet* packet);
|
||||
|
||||
private:
|
||||
AnalyzerSet* analyzer_set = nullptr;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
extern zeek::packet_analysis::Manager* packet_mgr;
|
137
src/packet_analysis/ProtocolAnalyzerSet.cc
Normal file
137
src/packet_analysis/ProtocolAnalyzerSet.cc
Normal file
|
@ -0,0 +1,137 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "ProtocolAnalyzerSet.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
ProtocolAnalyzerSet::ProtocolAnalyzerSet(Config& configuration, const std::string& default_analyzer_name)
|
||||
{
|
||||
// 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 = packet_mgr->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(default_analyzer_name);
|
||||
if ( it != analyzers.end() )
|
||||
default_analyzer = it->second;
|
||||
else
|
||||
default_analyzer = packet_mgr->InstantiateAnalyzer(default_analyzer_name);
|
||||
|
||||
default_dispatcher = nullptr;
|
||||
if ( default_analyzer != nullptr )
|
||||
default_dispatcher = GetDispatcher(configuration, default_analyzer_name);
|
||||
|
||||
current_state = root_dispatcher;
|
||||
}
|
||||
|
||||
ProtocolAnalyzerSet::~ProtocolAnalyzerSet()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Analyzer* ProtocolAnalyzerSet::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 ProtocolAnalyzerSet::Reset()
|
||||
{
|
||||
current_state = root_dispatcher;
|
||||
}
|
||||
|
||||
void ProtocolAnalyzerSet::DumpDebug() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
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
|
||||
}
|
||||
|
||||
Dispatcher* ProtocolAnalyzerSet::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 dispatcher_impl();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
39
src/packet_analysis/ProtocolAnalyzerSet.h
Normal file
39
src/packet_analysis/ProtocolAnalyzerSet.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AnalyzerSet.h"
|
||||
#include "Config.h"
|
||||
#include "dispatchers/Dispatcher.h"
|
||||
#include "dispatchers/UniversalDispatcher.h"
|
||||
#include "dispatchers/VectorDispatcher.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class ProtocolAnalyzerSet : public AnalyzerSet {
|
||||
|
||||
public:
|
||||
explicit ProtocolAnalyzerSet(Config& configuration, const std::string& default_analyzer_name);
|
||||
~ProtocolAnalyzerSet() override;
|
||||
|
||||
Analyzer* Dispatch(identifier_t identifier) override;
|
||||
void Reset() override;
|
||||
|
||||
protected:
|
||||
void DumpDebug() const override;
|
||||
|
||||
private:
|
||||
using dispatcher_impl = VectorDispatcher;
|
||||
//using dispatcher_impl = UniversalDispatcher;
|
||||
|
||||
std::map<std::string, Analyzer*> analyzers;
|
||||
std::map<std::string, Dispatcher*> dispatchers;
|
||||
Dispatcher* root_dispatcher = nullptr;
|
||||
Dispatcher* default_dispatcher = nullptr;
|
||||
Dispatcher* current_state = nullptr;
|
||||
Analyzer* default_analyzer = nullptr;
|
||||
|
||||
Dispatcher* GetDispatcher(Config& configuration, const std::string& dispatcher_name);
|
||||
};
|
||||
|
||||
}
|
41
src/packet_analysis/Tag.cc
Normal file
41
src/packet_analysis/Tag.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Tag.h"
|
||||
#include "Manager.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
Tag Tag::Error;
|
||||
|
||||
Tag::Tag(type_t type, subtype_t subtype)
|
||||
: zeek::Tag(packet_mgr->GetTagType(), type, subtype)
|
||||
{
|
||||
}
|
||||
|
||||
Tag& Tag::operator=(const Tag& other)
|
||||
{
|
||||
zeek::Tag::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const IntrusivePtr<EnumVal>& Tag::AsVal() const
|
||||
{
|
||||
return zeek::Tag::AsVal(packet_mgr->GetTagType());
|
||||
}
|
||||
|
||||
EnumVal* Tag::AsEnumVal() const
|
||||
{
|
||||
return AsVal().get();
|
||||
}
|
||||
|
||||
Tag::Tag(IntrusivePtr<EnumVal> val)
|
||||
: zeek::Tag(std::move(val))
|
||||
{
|
||||
}
|
||||
|
||||
Tag::Tag(EnumVal* val)
|
||||
: zeek::Tag({NewRef {}, val})
|
||||
{
|
||||
}
|
||||
|
||||
}
|
130
src/packet_analysis/Tag.h
Normal file
130
src/packet_analysis/Tag.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "zeek-config.h"
|
||||
#include "../Tag.h"
|
||||
|
||||
namespace zeek::plugin {
|
||||
template <class T> class TaggedComponent;
|
||||
template <class T, class C> class ComponentManager;
|
||||
}
|
||||
namespace plugin {
|
||||
template <class T>
|
||||
using TaggedComponent [[deprecated("Remove in v4.1. Use zeek::plugin::TaggedComponent instead.")]] =
|
||||
zeek::plugin::TaggedComponent<T>;
|
||||
template <class T, class C>
|
||||
using ComponentManager [[deprecated("Remove in v4.1. Use zeek::plugin::ComponentManager instead.")]] =
|
||||
zeek::plugin::ComponentManager<T, C>;
|
||||
}
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class Manager;
|
||||
class Component;
|
||||
|
||||
/**
|
||||
* Class to identify a protocol analyzer type.
|
||||
*/
|
||||
class Tag : public zeek::Tag {
|
||||
public:
|
||||
/*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Tag(const Tag& other) : zeek::Tag(other) { }
|
||||
|
||||
/**
|
||||
* Default constructor. This initializes the tag with an error value
|
||||
* that will make \c operator \c bool return false.
|
||||
*/
|
||||
Tag() : zeek::Tag() { }
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Tag() = default;
|
||||
|
||||
/**
|
||||
* Returns false if the tag represents an error value rather than a
|
||||
* legal analyzer type.
|
||||
*/
|
||||
explicit operator bool() const { return *this != Tag(); }
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
*/
|
||||
Tag& operator=(const Tag& other);
|
||||
|
||||
/**
|
||||
* Compares two tags for equality.
|
||||
*/
|
||||
bool operator==(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator==(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two tags for inequality.
|
||||
*/
|
||||
bool operator!=(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator!=(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two tags for less-than relationship.
|
||||
*/
|
||||
bool operator<(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator<(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the \c Analyzer::Tag enum that corresponds to this tag.
|
||||
* The returned value does not have its ref-count increased.
|
||||
*
|
||||
* @param etype the script-layer enum type associated with the tag.
|
||||
*/
|
||||
const IntrusivePtr<EnumVal>& AsVal() const;
|
||||
|
||||
/**
|
||||
* Returns the \c Analyzer::Tag enum that corresponds to this tag.
|
||||
* The returned value does not have its ref-count increased.
|
||||
*
|
||||
* @param etype the script-layer enum type associated with the tag.
|
||||
*/
|
||||
[[deprecated("Remove in v4.1. Use AsVal() instead.")]]
|
||||
EnumVal* AsEnumVal() const;
|
||||
|
||||
static Tag Error;
|
||||
|
||||
protected:
|
||||
|
||||
friend class packet_analysis::Manager;
|
||||
friend class plugin::ComponentManager<Tag, Component>;
|
||||
friend class plugin::TaggedComponent<Tag>;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param type The main type. Note that the \a llanalyzer::Manager
|
||||
* manages the value space internally, so noone else should assign
|
||||
* any main types.
|
||||
*
|
||||
* @param subtype The sub type, which is left to an analyzer for
|
||||
* interpretation. By default it's set to zero.
|
||||
*/
|
||||
explicit Tag(type_t type, subtype_t subtype = 0);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param val An enum value of script type \c Analyzer::Tag.
|
||||
*/
|
||||
explicit Tag(IntrusivePtr<EnumVal> val);
|
||||
|
||||
[[deprecated("Remove in v4.1. Construct from IntrusivePtr instead")]]
|
||||
explicit Tag(EnumVal* val);
|
||||
};
|
||||
|
||||
}
|
13
src/packet_analysis/dispatchers/CMakeLists.txt
Normal file
13
src/packet_analysis/dispatchers/CMakeLists.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
include(ZeekSubdir)
|
||||
|
||||
include_directories(BEFORE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
set(dispatcher_SRCS
|
||||
UniversalDispatcher.cc
|
||||
VectorDispatcher.cc
|
||||
)
|
||||
|
||||
bro_add_subdir_library(llanalyzer_dispatcher ${dispatcher_SRCS})
|
47
src/packet_analysis/dispatchers/Dispatcher.h
Normal file
47
src/packet_analysis/dispatchers/Dispatcher.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "Analyzer.h"
|
||||
#include "Defines.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class Dispatcher; // Forward decl for Value
|
||||
using register_pair = std::pair<identifier_t, std::pair<Analyzer*, Dispatcher*>>;
|
||||
using register_map = std::map<identifier_t, std::pair<Analyzer*, Dispatcher*>>;
|
||||
|
||||
class Value {
|
||||
public:
|
||||
Analyzer* analyzer;
|
||||
Dispatcher* dispatcher;
|
||||
|
||||
Value(Analyzer* analyzer, Dispatcher* dispatcher)
|
||||
: analyzer(analyzer), dispatcher(dispatcher)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class Dispatcher {
|
||||
public:
|
||||
virtual ~Dispatcher() = default;
|
||||
|
||||
virtual bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) = 0;
|
||||
virtual void Register(const register_map& data)
|
||||
{
|
||||
for ( auto& current : data )
|
||||
Register(current.first, current.second.first, current.second.second);
|
||||
}
|
||||
|
||||
virtual const Value* Lookup(identifier_t identifier) const = 0;
|
||||
|
||||
virtual size_t Size() const = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual void DumpDebug() const = 0;
|
||||
};
|
||||
|
||||
}
|
210
src/packet_analysis/dispatchers/UniversalDispatcher.cc
Normal file
210
src/packet_analysis/dispatchers/UniversalDispatcher.cc
Normal file
|
@ -0,0 +1,210 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "UniversalDispatcher.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
UniversalDispatcher::UniversalDispatcher() : generator(rd())
|
||||
{
|
||||
SetBins(2);
|
||||
|
||||
table = std::vector<pair_t>(ONE << m, {0, nullptr});
|
||||
|
||||
// Initialize random engine
|
||||
distribution_a = std::uniform_int_distribution<uint64_t>(1, ~static_cast<uint64_t>(0));
|
||||
distribution_b = std::uniform_int_distribution<uint64_t>(0, (ONE << w_minus_m) - ONE);
|
||||
|
||||
// Initialize random parameters
|
||||
RandomizeAB();
|
||||
}
|
||||
|
||||
UniversalDispatcher::~UniversalDispatcher()
|
||||
{
|
||||
FreeValues();
|
||||
}
|
||||
|
||||
bool UniversalDispatcher::Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher)
|
||||
{
|
||||
#if DEBUG > 1
|
||||
std::shared_ptr<void> deferred(nullptr, [=](...) {
|
||||
std::cout << "Inserted " << identifier << std::endl;
|
||||
});
|
||||
#endif
|
||||
|
||||
uint64_t hashed_id = Hash(identifier);
|
||||
if ( table[hashed_id].second == nullptr )
|
||||
{
|
||||
// Free bin, insert the value
|
||||
table[hashed_id] = std::make_pair(identifier, new Value(analyzer, dispatcher));
|
||||
return true;
|
||||
}
|
||||
else if ( table[hashed_id].first != identifier )
|
||||
{
|
||||
// The bin is not empty, but the content isn't the to-be-inserted identifier --> resolve collision
|
||||
|
||||
// Create intermediate representation with the new element in it, then rehash with that data
|
||||
std::vector<pair_t> intermediate = CreateIntermediate();
|
||||
intermediate.emplace_back(identifier, new Value(analyzer, dispatcher));
|
||||
|
||||
// Try increasing the #bins until it works or it can't get any larger.
|
||||
Rehash(intermediate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Analyzer with this ID is already registered.
|
||||
return false;
|
||||
}
|
||||
|
||||
void UniversalDispatcher::Register(const register_map& data)
|
||||
{
|
||||
// Analyzer already registered
|
||||
for ( const auto& current : data )
|
||||
{
|
||||
if ( table[Hash(current.first)].second != nullptr )
|
||||
throw std::invalid_argument("Analyzer " + std::to_string(current.first) + " already registered!");
|
||||
}
|
||||
|
||||
// Create intermediate representation of current analyzer set, then add all new ones
|
||||
std::vector<pair_t> intermediate = CreateIntermediate();
|
||||
for ( const auto& current : data )
|
||||
intermediate.emplace_back(current.first, new Value(current.second.first, current.second.second));
|
||||
|
||||
Rehash(intermediate);
|
||||
}
|
||||
|
||||
Value* UniversalDispatcher::Lookup(identifier_t identifier) const
|
||||
{
|
||||
uint64_t hashed_id = Hash(identifier);
|
||||
|
||||
// The hashed_id can't be larger than the number of bins
|
||||
assert(hashed_id < table.size() && "Hashed ID is outside of the hash table range!");
|
||||
|
||||
pair_t entry = table[hashed_id];
|
||||
if ( entry.second != nullptr && entry.first == identifier )
|
||||
return entry.second;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t UniversalDispatcher::Size() const
|
||||
{
|
||||
size_t result = 0;
|
||||
for ( const auto& current : table )
|
||||
{
|
||||
if ( current.second != nullptr )
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void UniversalDispatcher::Clear()
|
||||
{
|
||||
// Free all analyzers
|
||||
FreeValues();
|
||||
|
||||
SetBins(2);
|
||||
table = std::vector<pair_t>(ONE << m, {0, nullptr});
|
||||
RandomizeAB();
|
||||
}
|
||||
|
||||
size_t UniversalDispatcher::BucketCount()
|
||||
{
|
||||
return table.size();
|
||||
}
|
||||
|
||||
void UniversalDispatcher::Rehash()
|
||||
{
|
||||
// Intermediate representation is just the current table without nulls
|
||||
Rehash(CreateIntermediate());
|
||||
}
|
||||
|
||||
void UniversalDispatcher::DumpDebug() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher elements (used/total): %lu/%lu", Size(), table.size());
|
||||
for ( size_t i = 0; i < table.size(); i++ )
|
||||
{
|
||||
if ( table[i].second != nullptr )
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8x => %s, %p", table[i].first, table[i].second->analyzer->GetAnalyzerName(), table[i].second->dispatcher);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// #######################
|
||||
// ####### PRIVATE #######
|
||||
// #######################
|
||||
|
||||
void UniversalDispatcher::FreeValues()
|
||||
{
|
||||
for ( auto& current : table )
|
||||
{
|
||||
delete current.second;
|
||||
current.second = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UniversalDispatcher::Rehash(const std::vector<pair_t>& intermediate)
|
||||
{
|
||||
while ( ! FindCollisionFreeHashFunction(intermediate) )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Rehashing did not work. Increasing #bins to %" PRIu64 " (%" PRIu64 " bit).", (uint64_t)std::pow(2, m + 1), m + 1);
|
||||
SetBins(m + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool UniversalDispatcher::FindCollisionFreeHashFunction(const std::vector<pair_t>& intermediate)
|
||||
{
|
||||
// Don't even try if the number of values is larger than the number of buckets
|
||||
if ( ONE << m < intermediate.size() )
|
||||
return false;
|
||||
|
||||
// Remember the hash function parameters to not break the table if rehashing doesn't work
|
||||
uint64_t stored_a = a;
|
||||
uint64_t stored_b = b;
|
||||
|
||||
// Because the hash function hashes all values in the universe uniformly to m bins with probability 1/m
|
||||
// we should at least try a multiple of #bins times.
|
||||
for ( size_t i = 1; i <= (ONE << m); i++ )
|
||||
{
|
||||
// Step 1: Re-randomize hash function parameters
|
||||
RandomizeAB();
|
||||
|
||||
// Step 2: Create new table
|
||||
std::vector<pair_t> new_table(ONE << m, {0, nullptr});
|
||||
|
||||
// Step 3: Try to insert all elements into the new table with the new hash function
|
||||
bool finished = true;
|
||||
for ( const auto& current : intermediate )
|
||||
{
|
||||
uint64_t hashed_id = Hash(current.first);
|
||||
assert(hashed_id < new_table.size());
|
||||
if ( new_table[hashed_id].second == nullptr )
|
||||
{
|
||||
// Free bin, insert the value
|
||||
new_table[hashed_id] = current;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The bin is not empty which means there is a collision
|
||||
// (there are no duplicates in the intermediate representation so that can't be the case)
|
||||
finished = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: If the inserting finished without collisions, overwrite the previous table and exit
|
||||
if ( finished )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Took %lu rehash(es) to resolve.", i);
|
||||
table = new_table;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Finding a collision free hash function failed. Revert the hash function parameters.
|
||||
a = stored_a;
|
||||
b = stored_b;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
108
src/packet_analysis/dispatchers/UniversalDispatcher.h
Normal file
108
src/packet_analysis/dispatchers/UniversalDispatcher.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <random>
|
||||
#include "Dispatcher.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class UniversalDispatcher : public Dispatcher {
|
||||
public:
|
||||
UniversalDispatcher();
|
||||
~UniversalDispatcher() override;
|
||||
|
||||
bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) override;
|
||||
void Register(const register_map& data) override;
|
||||
Value* Lookup(identifier_t identifier) const override;
|
||||
size_t Size() const override;
|
||||
void Clear() override;
|
||||
|
||||
void DumpDebug() const override;
|
||||
size_t BucketCount();
|
||||
|
||||
// Rehashes the hash table including re-randomization of the hash function.
|
||||
void Rehash();
|
||||
|
||||
private:
|
||||
using pair_t = std::pair<identifier_t, Value*>;
|
||||
static const uint64_t ONE = 1u;
|
||||
|
||||
// Chosen random constants for the currently selected collision free random hash function
|
||||
uint64_t a = 0; // Needs to be a random odd positive value < 2^(sizeof(uint64_t) * 8)
|
||||
uint64_t b = 0; // Needs to be a random non-negative value < 2^(((sizeof(uint64_t) * 8) - M)
|
||||
|
||||
// Current bits that define the number of bins. Initially 2 which means there are 2^2 = 4 bins.
|
||||
uint64_t m = 2;
|
||||
|
||||
// Current shift value which is the number of bits that are "insignificant" because of the universe size.
|
||||
uint64_t w_minus_m = 0;
|
||||
|
||||
// RNG
|
||||
std::random_device rd;
|
||||
std::mt19937_64 generator;
|
||||
std::uniform_int_distribution<uint64_t> distribution_a;
|
||||
std::uniform_int_distribution<uint64_t> distribution_b;
|
||||
|
||||
// Debug
|
||||
#if DEBUG > 0
|
||||
size_t nptr_counter = 0;
|
||||
size_t mismatch_counter = 0;
|
||||
size_t all_counter = 0;
|
||||
#endif
|
||||
|
||||
std::vector<pair_t> table;
|
||||
|
||||
void FreeValues();
|
||||
|
||||
void Rehash(const std::vector<pair_t>& intermediate);
|
||||
|
||||
/**
|
||||
* Tries to find a collision free hash function with the current number of buckets.
|
||||
*
|
||||
* @param intermediate The key-value set to store in the hashtable.
|
||||
* @return true, iff it found a collision-free hash function.
|
||||
*/
|
||||
bool FindCollisionFreeHashFunction(const std::vector<pair_t>& intermediate);
|
||||
|
||||
[[nodiscard]] inline uint64_t Hash(const uint64_t value) const
|
||||
{
|
||||
return (a * value + b) >> w_minus_m;
|
||||
}
|
||||
|
||||
inline void RandomizeAB()
|
||||
{
|
||||
do {
|
||||
a = distribution_a(generator);
|
||||
} while ( a % 2 == 0 );
|
||||
|
||||
b = distribution_b(generator);
|
||||
}
|
||||
|
||||
inline void SetBins(uint64_t new_m)
|
||||
{
|
||||
if ( new_m > (sizeof(uint64_t) * 8) )
|
||||
throw std::runtime_error("Number of bits for bin count too large.");
|
||||
|
||||
m = new_m;
|
||||
w_minus_m = sizeof(uint64_t) * 8 - m;
|
||||
distribution_b = std::uniform_int_distribution<uint64_t>(0, ((uint64_t)(1u) << w_minus_m) - (uint64_t)(1u));
|
||||
}
|
||||
|
||||
inline std::vector<pair_t> CreateIntermediate()
|
||||
{
|
||||
std::vector<pair_t> intermediate;
|
||||
for ( const auto& current : table )
|
||||
{
|
||||
if ( current.second != nullptr )
|
||||
{
|
||||
assert(current.second->analyzer != nullptr);
|
||||
intermediate.emplace_back(current.first, current.second);
|
||||
}
|
||||
}
|
||||
return intermediate;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
122
src/packet_analysis/dispatchers/VectorDispatcher.cc
Normal file
122
src/packet_analysis/dispatchers/VectorDispatcher.cc
Normal file
|
@ -0,0 +1,122 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "VectorDispatcher.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
VectorDispatcher::~VectorDispatcher()
|
||||
{
|
||||
FreeValues();
|
||||
}
|
||||
|
||||
bool VectorDispatcher::Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher)
|
||||
{
|
||||
// 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 )
|
||||
{
|
||||
table[0] = new Value(analyzer, dispatcher);
|
||||
lowest_identifier = identifier;
|
||||
return true;
|
||||
}
|
||||
|
||||
// If highestIdentifier == identifier, overwrite would happen -> no check needed, will return false
|
||||
if ( GetHighestIdentifier() < identifier )
|
||||
{
|
||||
table.resize(table.size() + (identifier - GetHighestIdentifier()), nullptr);
|
||||
}
|
||||
else if ( identifier < lowest_identifier )
|
||||
{
|
||||
// Lower than the lowest registered identifier. Shift up by lowerBound - identifier
|
||||
identifier_t distance = lowest_identifier - identifier;
|
||||
table.resize(table.size() + distance, nullptr);
|
||||
|
||||
// Shift values
|
||||
for ( ssize_t i = table.size() - 1; i >= 0; i-- )
|
||||
{
|
||||
if ( table[i] != nullptr )
|
||||
{
|
||||
table.at(i + distance) = table.at(i);
|
||||
table.at(i) = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
lowest_identifier = identifier;
|
||||
}
|
||||
|
||||
int64_t index = identifier - lowest_identifier;
|
||||
if ( table[index] == nullptr )
|
||||
{
|
||||
table[index] = new Value(analyzer, dispatcher);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VectorDispatcher::Register(const register_map& data)
|
||||
{
|
||||
// Search smallest and largest identifier and resize vector
|
||||
const auto& lowest_new =
|
||||
std::min_element(data.begin(), data.end(),
|
||||
[](const register_pair& a, const register_pair& b) {
|
||||
return a.first < b.first;
|
||||
});
|
||||
|
||||
// Register lowest first in order to do shifting only once
|
||||
Register(lowest_new->first, lowest_new->second.first, lowest_new->second.second);
|
||||
for ( auto i = data.begin(); i != data.end(); i++ )
|
||||
{
|
||||
// Already added if i == lowest_new
|
||||
if ( i == lowest_new )
|
||||
continue;
|
||||
|
||||
if ( ! Register(i->first, i->second.first, i->second.second) )
|
||||
throw std::invalid_argument("Analyzer already registered!");
|
||||
}
|
||||
}
|
||||
|
||||
const Value* VectorDispatcher::Lookup(identifier_t identifier) const
|
||||
{
|
||||
int64_t index = identifier - lowest_identifier;
|
||||
if ( index >= 0 && index < static_cast<int64_t>(table.size()) && table[index] != nullptr )
|
||||
return table[index];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t VectorDispatcher::Size() const
|
||||
{
|
||||
return std::count_if(table.begin(), table.end(), [](const auto* v) { return v != nullptr; });
|
||||
}
|
||||
|
||||
void VectorDispatcher::Clear()
|
||||
{
|
||||
FreeValues();
|
||||
table.clear();
|
||||
}
|
||||
|
||||
void VectorDispatcher::FreeValues()
|
||||
{
|
||||
for ( auto& current : table )
|
||||
{
|
||||
delete current;
|
||||
current = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void VectorDispatcher::DumpDebug() const
|
||||
{
|
||||
#ifdef DEBUG
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, " Dispatcher elements (used/total): %lu/%lu", Size(), table.size());
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "TABLE SIZE %lu", table.size());
|
||||
for ( size_t i = 0; i < table.size(); i++ )
|
||||
{
|
||||
if ( table[i] != nullptr )
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, " %#8lx => %s, %p", i+lowest_identifier, table[i]->analyzer->GetAnalyzerName(), table[i]->dispatcher);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
41
src/packet_analysis/dispatchers/VectorDispatcher.h
Normal file
41
src/packet_analysis/dispatchers/VectorDispatcher.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include "Dispatcher.h"
|
||||
|
||||
namespace zeek::packet_analysis {
|
||||
|
||||
class VectorDispatcher : public Dispatcher {
|
||||
public:
|
||||
VectorDispatcher()
|
||||
: table(std::vector<Value*>(1, nullptr))
|
||||
{ }
|
||||
|
||||
~VectorDispatcher() override;
|
||||
|
||||
bool Register(identifier_t identifier, Analyzer* analyzer, Dispatcher* dispatcher) override;
|
||||
void Register(const register_map& data) override;
|
||||
|
||||
const Value* Lookup(identifier_t identifier) const override;
|
||||
|
||||
size_t Size() const override;
|
||||
void Clear() override;
|
||||
|
||||
protected:
|
||||
void DumpDebug() const override;
|
||||
|
||||
private:
|
||||
identifier_t lowest_identifier = 0;
|
||||
std::vector<Value*> table;
|
||||
|
||||
void FreeValues();
|
||||
|
||||
inline identifier_t GetHighestIdentifier() const
|
||||
{
|
||||
return lowest_identifier + table.size() - 1;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
18
src/packet_analysis/protocol/CMakeLists.txt
Normal file
18
src/packet_analysis/protocol/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
add_subdirectory(default)
|
||||
|
||||
add_subdirectory(wrapper)
|
||||
add_subdirectory(null)
|
||||
add_subdirectory(ethernet)
|
||||
add_subdirectory(vlan)
|
||||
add_subdirectory(pppoe)
|
||||
add_subdirectory(ppp_serial)
|
||||
add_subdirectory(ieee802_11)
|
||||
add_subdirectory(ieee802_11_radio)
|
||||
add_subdirectory(fddi)
|
||||
add_subdirectory(nflog)
|
||||
add_subdirectory(mpls)
|
||||
add_subdirectory(linux_sll)
|
||||
|
||||
add_subdirectory(arp)
|
||||
add_subdirectory(ipv4)
|
||||
add_subdirectory(ipv6)
|
19
src/packet_analysis/protocol/arp/ARP.cc
Normal file
19
src/packet_analysis/protocol/arp/ARP.cc
Normal file
|
@ -0,0 +1,19 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "ARP.h"
|
||||
|
||||
using namespace zeek::packet_analysis::ARP;
|
||||
|
||||
ARPAnalyzer::ARPAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("ARP")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> ARPAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
// TODO: Make ARP analyzer a native LL analyzer
|
||||
packet->l3_proto = L3_ARP;
|
||||
|
||||
// Leave LL analyzer land
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
}
|
23
src/packet_analysis/protocol/arp/ARP.h
Normal file
23
src/packet_analysis/protocol/arp/ARP.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::ARP {
|
||||
|
||||
class ARPAnalyzer : public Analyzer {
|
||||
public:
|
||||
ARPAnalyzer();
|
||||
~ARPAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new ARPAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/arp/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/arp/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer ARP)
|
||||
zeek_plugin_cc(ARP.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
24
src/packet_analysis/protocol/arp/Plugin.cc
Normal file
24
src/packet_analysis/protocol/arp/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "plugin/Plugin.h"
|
||||
#include "ARP.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_ARP {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("ARP",
|
||||
zeek::packet_analysis::ARP::ARPAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::ARP";
|
||||
config.description = "ARP packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/default/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/default/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer Default)
|
||||
zeek_plugin_cc(Default.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
28
src/packet_analysis/protocol/default/Default.cc
Normal file
28
src/packet_analysis/protocol/default/Default.cc
Normal file
|
@ -0,0 +1,28 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Default.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::Default;
|
||||
|
||||
DefaultAnalyzer::DefaultAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("DefaultAnalyzer")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> DefaultAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
// Assume we're pointing at IP. Just figure out which version.
|
||||
if ( pdata + sizeof(struct ip) >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("default_ll_analyser_failed");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
auto ip = (const struct ip *)pdata;
|
||||
identifier_t protocol = ip->ip_v;
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/default/Default.h
Normal file
23
src/packet_analysis/protocol/default/Default.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::Default {
|
||||
|
||||
class DefaultAnalyzer : public Analyzer {
|
||||
public:
|
||||
DefaultAnalyzer();
|
||||
~DefaultAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new DefaultAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/default/Plugin.cc
Normal file
24
src/packet_analysis/protocol/default/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Default.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_Default {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("DefaultAnalyzer",
|
||||
zeek::packet_analysis::Default::DefaultAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::DefaultAnalyzer";
|
||||
config.description = "Default packet analyzer for IP fallback";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/ethernet/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/ethernet/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer Ethernet)
|
||||
zeek_plugin_cc(Ethernet.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
75
src/packet_analysis/protocol/ethernet/Ethernet.cc
Normal file
75
src/packet_analysis/protocol/ethernet/Ethernet.cc
Normal file
|
@ -0,0 +1,75 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Ethernet.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::Ethernet;
|
||||
|
||||
EthernetAnalyzer::EthernetAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("Ethernet")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> EthernetAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
// Skip past Cisco FabricPath to encapsulated ethernet frame.
|
||||
if ( pdata[12] == 0x89 && pdata[13] == 0x03 )
|
||||
{
|
||||
auto constexpr cfplen = 16;
|
||||
|
||||
if ( pdata + cfplen + 14 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header_cfp");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
pdata += cfplen;
|
||||
}
|
||||
|
||||
// Get protocol being carried from the ethernet frame.
|
||||
identifier_t protocol = (pdata[12] << 8) + pdata[13];
|
||||
|
||||
packet->eth_type = protocol;
|
||||
packet->l2_dst = pdata;
|
||||
packet->l2_src = pdata + 6;
|
||||
|
||||
// Ethernet II frames
|
||||
if ( protocol >= 1536 )
|
||||
{
|
||||
pdata += 14;
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
||||
|
||||
// Other ethernet frame types
|
||||
if ( protocol <= 1500 )
|
||||
{
|
||||
if ( pdata + 16 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_ethernet_frame");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// In the following we use undefined EtherTypes to signal uncommon
|
||||
// frame types. This allows specialized analyzers to take over.
|
||||
// Note that pdata remains at the start of the ethernet frame.
|
||||
|
||||
// IEEE 802.2 SNAP
|
||||
if ( pdata[14] == 0xAA && pdata[15] == 0xAA)
|
||||
return { AnalyzerResult::Continue, 1502 };
|
||||
|
||||
// Novell raw IEEE 802.3
|
||||
if ( pdata[14] == 0xFF && pdata[15] == 0xFF)
|
||||
return { AnalyzerResult::Continue, 1503 };
|
||||
|
||||
|
||||
// IEEE 802.2 LLC
|
||||
return { AnalyzerResult::Continue, 1501 };
|
||||
}
|
||||
|
||||
// Undefined (1500 < EtherType < 1536)
|
||||
packet->Weird("undefined_ether_type");
|
||||
return { AnalyzerResult::Failed, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/ethernet/Ethernet.h
Normal file
23
src/packet_analysis/protocol/ethernet/Ethernet.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::Ethernet {
|
||||
|
||||
class EthernetAnalyzer : public Analyzer {
|
||||
public:
|
||||
EthernetAnalyzer();
|
||||
~EthernetAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new EthernetAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/ethernet/Plugin.cc
Normal file
24
src/packet_analysis/protocol/ethernet/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Ethernet.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_Ethernet {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("Ethernet",
|
||||
zeek::packet_analysis::Ethernet::EthernetAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::Ethernet";
|
||||
config.description = "Ethernet packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/fddi/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/fddi/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer FDDI)
|
||||
zeek_plugin_cc(FDDI.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
27
src/packet_analysis/protocol/fddi/FDDI.cc
Normal file
27
src/packet_analysis/protocol/fddi/FDDI.cc
Normal file
|
@ -0,0 +1,27 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "FDDI.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::FDDI;
|
||||
|
||||
FDDIAnalyzer::FDDIAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("FDDI")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> FDDIAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
auto hdr_size = 13 + 8; // FDDI header + LLC
|
||||
|
||||
if ( pdata + hdr_size >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("FDDI_analyzer_failed");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// We just skip the header and hope for default analysis
|
||||
pdata += hdr_size;
|
||||
return { AnalyzerResult::Continue, -1 };
|
||||
}
|
23
src/packet_analysis/protocol/fddi/FDDI.h
Normal file
23
src/packet_analysis/protocol/fddi/FDDI.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::FDDI {
|
||||
|
||||
class FDDIAnalyzer : public zeek::packet_analysis::Analyzer {
|
||||
public:
|
||||
FDDIAnalyzer();
|
||||
~FDDIAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static zeek::packet_analysis::Analyzer* Instantiate()
|
||||
{
|
||||
return new FDDIAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/fddi/Plugin.cc
Normal file
24
src/packet_analysis/protocol/fddi/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "FDDI.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_FDDI {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("FDDI",
|
||||
zeek::packet_analysis::FDDI::FDDIAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::FDDI";
|
||||
config.description = "FDDI packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/ieee802_11/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/ieee802_11/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer IEEE802_11)
|
||||
zeek_plugin_cc(IEEE802_11.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
113
src/packet_analysis/protocol/ieee802_11/IEEE802_11.cc
Normal file
113
src/packet_analysis/protocol/ieee802_11/IEEE802_11.cc
Normal file
|
@ -0,0 +1,113 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IEEE802_11.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::IEEE802_11;
|
||||
|
||||
IEEE802_11Analyzer::IEEE802_11Analyzer()
|
||||
: zeek::packet_analysis::Analyzer("IEEE802_11")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> IEEE802_11Analyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
u_char len_80211 = 24; // minimal length of data frames
|
||||
|
||||
if ( pdata + len_80211 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_802_11_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
u_char fc_80211 = pdata[0]; // Frame Control field
|
||||
|
||||
// Skip non-data frame types (management & control).
|
||||
if ( ! ((fc_80211 >> 2) & 0x02) )
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
|
||||
// Skip subtypes without data.
|
||||
if ( (fc_80211 >> 4) & 0x04 )
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
|
||||
// 'To DS' and 'From DS' flags set indicate use of the 4th
|
||||
// address field.
|
||||
if ( (pdata[1] & 0x03) == 0x03 )
|
||||
len_80211 += packet->L2_ADDR_LEN;
|
||||
|
||||
// Look for the QoS indicator bit.
|
||||
if ( (fc_80211 >> 4) & 0x08 )
|
||||
{
|
||||
// Skip in case of A-MSDU subframes indicated by QoS
|
||||
// control field.
|
||||
if ( pdata[len_80211] & 0x80 )
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
|
||||
len_80211 += 2;
|
||||
}
|
||||
|
||||
if ( pdata + len_80211 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_802_11_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// Determine link-layer addresses based
|
||||
// on 'To DS' and 'From DS' flags
|
||||
switch ( pdata[1] & 0x03 )
|
||||
{
|
||||
case 0x00:
|
||||
packet->l2_src = pdata + 10;
|
||||
packet->l2_dst = pdata + 4;
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
packet->l2_src = pdata + 10;
|
||||
packet->l2_dst = pdata + 16;
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
packet->l2_src = pdata + 16;
|
||||
packet->l2_dst = pdata + 4;
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
packet->l2_src = pdata + 24;
|
||||
packet->l2_dst = pdata + 16;
|
||||
break;
|
||||
}
|
||||
|
||||
// skip 802.11 data header
|
||||
pdata += len_80211;
|
||||
|
||||
if ( pdata + 8 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_802_11_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// Check that the DSAP and SSAP are both SNAP and that the control
|
||||
// field indicates that this is an unnumbered frame.
|
||||
// The organization code (24bits) needs to also be zero to
|
||||
// indicate that this is encapsulated ethernet.
|
||||
if ( pdata[0] == 0xAA && pdata[1] == 0xAA && pdata[2] == 0x03 &&
|
||||
pdata[3] == 0 && pdata[4] == 0 && pdata[5] == 0 )
|
||||
{
|
||||
pdata += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If this is a logical link control frame without the
|
||||
// possibility of having a protocol we care about, we'll
|
||||
// just skip it for now.
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
identifier_t protocol = (pdata[0] << 8) + pdata[1];
|
||||
pdata += 2;
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/ieee802_11/IEEE802_11.h
Normal file
23
src/packet_analysis/protocol/ieee802_11/IEEE802_11.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::IEEE802_11 {
|
||||
|
||||
class IEEE802_11Analyzer : public Analyzer {
|
||||
public:
|
||||
IEEE802_11Analyzer();
|
||||
~IEEE802_11Analyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new IEEE802_11Analyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/ieee802_11/Plugin.cc
Normal file
24
src/packet_analysis/protocol/ieee802_11/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IEEE802_11.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_IEEE802_11 {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("IEEE802_11",
|
||||
zeek::packet_analysis::IEEE802_11::IEEE802_11Analyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::IEEE802_11";
|
||||
config.description = "IEEE 802.11 packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer IEEE802_11_Radio)
|
||||
zeek_plugin_cc(IEEE802_11_Radio.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
|
@ -0,0 +1,38 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "IEEE802_11_Radio.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::IEEE802_11_Radio;
|
||||
|
||||
IEEE802_11_RadioAnalyzer::IEEE802_11_RadioAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("IEEE802_11_Radio")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> IEEE802_11_RadioAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
if ( pdata + 3 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_radiotap_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// Skip over the RadioTap header
|
||||
int rtheader_len = (pdata[3] << 8) + pdata[2];
|
||||
|
||||
if ( pdata + rtheader_len >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_radiotap_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
packet->cur_pos += rtheader_len;
|
||||
|
||||
return { AnalyzerResult::Continue, DLT_IEEE802_11 };
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::IEEE802_11_Radio {
|
||||
|
||||
class IEEE802_11_RadioAnalyzer : public Analyzer {
|
||||
public:
|
||||
IEEE802_11_RadioAnalyzer();
|
||||
~IEEE802_11_RadioAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new IEEE802_11_RadioAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
23
src/packet_analysis/protocol/ieee802_11_radio/Plugin.cc
Normal file
23
src/packet_analysis/protocol/ieee802_11_radio/Plugin.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IEEE802_11_Radio.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_IEEE802_11_Radio {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("IEEE802_11_Radio",
|
||||
zeek::packet_analysis::IEEE802_11_Radio::IEEE802_11_RadioAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::IEEE802_11_Radio";
|
||||
config.description = "IEEE 802.11 Radiotap packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
}
|
8
src/packet_analysis/protocol/ipv4/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/ipv4/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer IPv4)
|
||||
zeek_plugin_cc(IPv4.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
18
src/packet_analysis/protocol/ipv4/IPv4.cc
Normal file
18
src/packet_analysis/protocol/ipv4/IPv4.cc
Normal file
|
@ -0,0 +1,18 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IPv4.h"
|
||||
|
||||
using namespace zeek::packet_analysis::IPv4;
|
||||
|
||||
IPv4Analyzer::IPv4Analyzer()
|
||||
: zeek::packet_analysis::Analyzer("IPv4")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> IPv4Analyzer::Analyze(Packet* packet)
|
||||
{
|
||||
packet->l3_proto = L3_IPV4;
|
||||
|
||||
// Leave LL analyzer land
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
}
|
23
src/packet_analysis/protocol/ipv4/IPv4.h
Normal file
23
src/packet_analysis/protocol/ipv4/IPv4.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::IPv4 {
|
||||
|
||||
class IPv4Analyzer : public Analyzer {
|
||||
public:
|
||||
IPv4Analyzer();
|
||||
~IPv4Analyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new IPv4Analyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/ipv4/Plugin.cc
Normal file
24
src/packet_analysis/protocol/ipv4/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IPv4.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_IPv4 {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("IPv4",
|
||||
zeek::packet_analysis::IPv4::IPv4Analyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::IPv4";
|
||||
config.description = "IPv4 packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/ipv6/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/ipv6/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer IPv6)
|
||||
zeek_plugin_cc(IPv6.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
18
src/packet_analysis/protocol/ipv6/IPv6.cc
Normal file
18
src/packet_analysis/protocol/ipv6/IPv6.cc
Normal file
|
@ -0,0 +1,18 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "IPv6.h"
|
||||
|
||||
using namespace zeek::packet_analysis::IPv6;
|
||||
|
||||
IPv6Analyzer::IPv6Analyzer()
|
||||
: zeek::packet_analysis::Analyzer("IPv6")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> IPv6Analyzer::Analyze(Packet* packet)
|
||||
{
|
||||
packet->l3_proto = L3_IPV6;
|
||||
|
||||
// Leave LL analyzer land
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
}
|
23
src/packet_analysis/protocol/ipv6/IPv6.h
Normal file
23
src/packet_analysis/protocol/ipv6/IPv6.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::IPv6 {
|
||||
|
||||
class IPv6Analyzer : public Analyzer {
|
||||
public:
|
||||
IPv6Analyzer();
|
||||
~IPv6Analyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new IPv6Analyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
23
src/packet_analysis/protocol/ipv6/Plugin.cc
Normal file
23
src/packet_analysis/protocol/ipv6/Plugin.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "plugin/Plugin.h"
|
||||
#include "IPv6.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_IPv6 {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("IPv6",
|
||||
zeek::packet_analysis::IPv6::IPv6Analyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::IPv6";
|
||||
config.description = "IPv6 packet analyzer";
|
||||
return config;
|
||||
}
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/linux_sll/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/linux_sll/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer LinuxSLL)
|
||||
zeek_plugin_cc(LinuxSLL.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
34
src/packet_analysis/protocol/linux_sll/LinuxSLL.cc
Normal file
34
src/packet_analysis/protocol/linux_sll/LinuxSLL.cc
Normal file
|
@ -0,0 +1,34 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "LinuxSLL.h"
|
||||
|
||||
using namespace zeek::packet_analysis::LinuxSLL;
|
||||
|
||||
LinuxSLLAnalyzer::LinuxSLLAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("LinuxSLL")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> LinuxSLLAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
if ( pdata + sizeof(SLLHeader) >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("truncated_Linux_SLL_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
//TODO: Handle different ARPHRD_types
|
||||
auto hdr = (const SLLHeader*)pdata;
|
||||
|
||||
identifier_t protocol = ntohs(hdr->protocol_type);
|
||||
packet->l2_src = (u_char*) &(hdr->addr);
|
||||
|
||||
// SLL doesn't include a destination address in the header, but not setting l2_dst to something
|
||||
// here will cause crashes elsewhere.
|
||||
packet->l2_dst = Packet::L2_EMPTY_ADDR;
|
||||
|
||||
pdata += sizeof(SLLHeader);
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
35
src/packet_analysis/protocol/linux_sll/LinuxSLL.h
Normal file
35
src/packet_analysis/protocol/linux_sll/LinuxSLL.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::LinuxSLL {
|
||||
|
||||
class LinuxSLLAnalyzer : public Analyzer {
|
||||
public:
|
||||
LinuxSLLAnalyzer();
|
||||
~LinuxSLLAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new LinuxSLLAnalyzer();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Structure layout is based on https://www.tcpdump.org/linktypes/LINKTYPE_LINUX_SLL.html
|
||||
struct SLLHeader
|
||||
{
|
||||
uint16_t packet_type;
|
||||
uint16_t arphrd_type;
|
||||
uint16_t addr_len;
|
||||
uint64_t addr;
|
||||
uint16_t protocol_type;
|
||||
} __attribute__((__packed__));
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/linux_sll/Plugin.cc
Normal file
24
src/packet_analysis/protocol/linux_sll/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "plugin/Plugin.h"
|
||||
#include "LinuxSLL.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_LinuxSLL {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("LinuxSLL",
|
||||
zeek::packet_analysis::LinuxSLL::LinuxSLLAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::LinuxSLL";
|
||||
config.description = "Linux cooked capture (SLL) packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/mpls/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/mpls/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer MPLS)
|
||||
zeek_plugin_cc(MPLS.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
55
src/packet_analysis/protocol/mpls/MPLS.cc
Normal file
55
src/packet_analysis/protocol/mpls/MPLS.cc
Normal file
|
@ -0,0 +1,55 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "MPLS.h"
|
||||
|
||||
using namespace zeek::packet_analysis::MPLS;
|
||||
|
||||
MPLSAnalyzer::MPLSAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("MPLS")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> MPLSAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
// Skip the MPLS label stack.
|
||||
bool end_of_stack = false;
|
||||
|
||||
while ( ! end_of_stack )
|
||||
{
|
||||
if ( pdata + 4 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
end_of_stack = *(pdata + 2u) & 0x01;
|
||||
pdata += 4;
|
||||
}
|
||||
|
||||
// According to RFC3032 the encapsulated protocol is not encoded.
|
||||
// We assume that what remains is IP.
|
||||
if ( pdata + sizeof(struct ip) >= end_of_data )
|
||||
{
|
||||
packet->Weird("no_ip_in_mpls_payload");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
auto ip = (const struct ip*)pdata;
|
||||
|
||||
if ( ip->ip_v == 4 )
|
||||
packet->l3_proto = L3_IPV4;
|
||||
else if ( ip->ip_v == 6 )
|
||||
packet->l3_proto = L3_IPV6;
|
||||
else
|
||||
{
|
||||
// Neither IPv4 nor IPv6.
|
||||
packet->Weird("no_ip_in_mpls_payload");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
packet->hdr_size = (pdata - packet->data);
|
||||
return { AnalyzerResult::Terminate, 0 };
|
||||
}
|
23
src/packet_analysis/protocol/mpls/MPLS.h
Normal file
23
src/packet_analysis/protocol/mpls/MPLS.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::MPLS {
|
||||
|
||||
class MPLSAnalyzer : public zeek::packet_analysis::Analyzer {
|
||||
public:
|
||||
MPLSAnalyzer();
|
||||
~MPLSAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static zeek::packet_analysis::Analyzer* Instantiate()
|
||||
{
|
||||
return new MPLSAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/mpls/Plugin.cc
Normal file
24
src/packet_analysis/protocol/mpls/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "MPLS.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_MPLS {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("MPLS",
|
||||
zeek::packet_analysis::MPLS::MPLSAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::MPLS";
|
||||
config.description = "MPLS packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/nflog/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/nflog/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer NFLog)
|
||||
zeek_plugin_cc(NFLog.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
80
src/packet_analysis/protocol/nflog/NFLog.cc
Normal file
80
src/packet_analysis/protocol/nflog/NFLog.cc
Normal file
|
@ -0,0 +1,80 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "NFLog.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::NFLog;
|
||||
|
||||
NFLogAnalyzer::NFLogAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("NFLog")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> NFLogAnalyzer::Analyze(Packet* packet) {
|
||||
auto& pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
// See https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
|
||||
identifier_t protocol = pdata[0];
|
||||
uint8_t version = pdata[1];
|
||||
|
||||
if ( version != 0 )
|
||||
{
|
||||
packet->Weird("unknown_nflog_version");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// Skip to TLVs.
|
||||
pdata += 4;
|
||||
|
||||
uint16_t tlv_len;
|
||||
uint16_t tlv_type;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( pdata + 4 >= end_of_data )
|
||||
{
|
||||
packet->Weird("nflog_no_pcap_payload");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// TLV Type and Length values are specified in host byte order
|
||||
// (libpcap should have done any needed byteswapping already).
|
||||
|
||||
tlv_len = *(reinterpret_cast<const uint16_t*>(pdata));
|
||||
tlv_type = *(reinterpret_cast<const uint16_t*>(pdata + 2));
|
||||
|
||||
auto constexpr nflog_type_payload = 9;
|
||||
|
||||
if ( tlv_type == nflog_type_payload )
|
||||
{
|
||||
// The raw packet payload follows this TLV.
|
||||
pdata += 4;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Length value includes the 4 octets for the Type and
|
||||
// Length values, but TLVs are also implicitly padded to
|
||||
// 32-bit alignments (that padding may not be included in
|
||||
// the Length value).
|
||||
|
||||
if ( tlv_len < 4 )
|
||||
{
|
||||
packet->Weird("nflog_bad_tlv_len");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rem = tlv_len % 4;
|
||||
|
||||
if ( rem != 0 )
|
||||
tlv_len += 4 - rem;
|
||||
}
|
||||
|
||||
pdata += tlv_len;
|
||||
}
|
||||
}
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/nflog/NFLog.h
Normal file
23
src/packet_analysis/protocol/nflog/NFLog.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::NFLog {
|
||||
|
||||
class NFLogAnalyzer : public Analyzer {
|
||||
public:
|
||||
NFLogAnalyzer();
|
||||
~NFLogAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new NFLogAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
23
src/packet_analysis/protocol/nflog/Plugin.cc
Normal file
23
src/packet_analysis/protocol/nflog/Plugin.cc
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "NFLog.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_NFLog {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("NFLog",
|
||||
zeek::packet_analysis::NFLog::NFLogAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::NFLog";
|
||||
config.description = "NFLog packet analyzer";
|
||||
return config;
|
||||
}
|
||||
} plugin;
|
||||
|
||||
}
|
7
src/packet_analysis/protocol/null/CMakeLists.txt
Normal file
7
src/packet_analysis/protocol/null/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE $ {CMAKE_CURRENT_SOURCE_DIR} $ {CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer Null)
|
||||
zeek_plugin_cc(Null.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
27
src/packet_analysis/protocol/null/Null.cc
Normal file
27
src/packet_analysis/protocol/null/Null.cc
Normal file
|
@ -0,0 +1,27 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Null.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::Null;
|
||||
|
||||
NullAnalyzer::NullAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("Null")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> NullAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
if ( pdata + 4 >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("null_analyzer_failed");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
identifier_t protocol = (pdata[3] << 24) + (pdata[2] << 16) + (pdata[1] << 8) + pdata[0];
|
||||
pdata += 4; // skip link header
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/null/Null.h
Normal file
23
src/packet_analysis/protocol/null/Null.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::Null {
|
||||
|
||||
class NullAnalyzer : public Analyzer {
|
||||
public:
|
||||
NullAnalyzer();
|
||||
~NullAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new NullAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/null/Plugin.cc
Normal file
24
src/packet_analysis/protocol/null/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "plugin/Plugin.h"
|
||||
#include "Null.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_Null {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("Null",
|
||||
zeek::packet_analysis::Null::NullAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::Null";
|
||||
config.description = "Null packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/ppp_serial/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/ppp_serial/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer PPPSerial)
|
||||
zeek_plugin_cc(PPPSerial.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
22
src/packet_analysis/protocol/ppp_serial/PPPSerial.cc
Normal file
22
src/packet_analysis/protocol/ppp_serial/PPPSerial.cc
Normal file
|
@ -0,0 +1,22 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "PPPSerial.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::PPPSerial;
|
||||
|
||||
PPPSerialAnalyzer::PPPSerialAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("PPPSerial")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> PPPSerialAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
// Extract protocol identifier
|
||||
identifier_t protocol = (pdata[2] << 8) + pdata[3];
|
||||
pdata += 4; // skip link header
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/ppp_serial/PPPSerial.h
Normal file
23
src/packet_analysis/protocol/ppp_serial/PPPSerial.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::PPPSerial {
|
||||
|
||||
class PPPSerialAnalyzer : public Analyzer {
|
||||
public:
|
||||
PPPSerialAnalyzer();
|
||||
~PPPSerialAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new PPPSerialAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/ppp_serial/Plugin.cc
Normal file
24
src/packet_analysis/protocol/ppp_serial/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "PPPSerial.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_PPPSerial {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("PPPSerial",
|
||||
zeek::packet_analysis::PPPSerial::PPPSerialAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::PPPSerial";
|
||||
config.description = "PPPSerial packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/pppoe/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/pppoe/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer PPPoE)
|
||||
zeek_plugin_cc(PPPoE.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
28
src/packet_analysis/protocol/pppoe/PPPoE.cc
Normal file
28
src/packet_analysis/protocol/pppoe/PPPoE.cc
Normal file
|
@ -0,0 +1,28 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "PPPoE.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::PPPoE;
|
||||
|
||||
PPPoEAnalyzer::PPPoEAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("PPPoE")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> PPPoEAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
if ( pdata + 8 >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("truncated_pppoe_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
// Extract protocol identifier
|
||||
identifier_t protocol = (pdata[6] << 8u) + pdata[7];
|
||||
pdata += 8; // Skip the PPPoE session and PPP header
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/pppoe/PPPoE.h
Normal file
23
src/packet_analysis/protocol/pppoe/PPPoE.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::PPPoE {
|
||||
|
||||
class PPPoEAnalyzer : public Analyzer {
|
||||
public:
|
||||
PPPoEAnalyzer();
|
||||
~PPPoEAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new PPPoEAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
24
src/packet_analysis/protocol/pppoe/Plugin.cc
Normal file
24
src/packet_analysis/protocol/pppoe/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "PPPoE.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_PPPoE {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("PPPoE",
|
||||
zeek::packet_analysis::PPPoE::PPPoEAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::PPPoE";
|
||||
config.description = "PPPoE packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/vlan/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/vlan/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer VLAN)
|
||||
zeek_plugin_cc(VLAN.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
24
src/packet_analysis/protocol/vlan/Plugin.cc
Normal file
24
src/packet_analysis/protocol/vlan/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "VLAN.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_VLAN {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("VLAN",
|
||||
zeek::packet_analysis::VLAN::VLANAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::VLAN";
|
||||
config.description = "VLAN packet analyzer";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
31
src/packet_analysis/protocol/vlan/VLAN.cc
Normal file
31
src/packet_analysis/protocol/vlan/VLAN.cc
Normal file
|
@ -0,0 +1,31 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "VLAN.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::VLAN;
|
||||
|
||||
VLANAnalyzer::VLANAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("VLAN")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> VLANAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
auto& pdata = packet->cur_pos;
|
||||
|
||||
if ( pdata + 4 >= packet->GetEndOfData() )
|
||||
{
|
||||
packet->Weird("truncated_VLAN_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
auto& vlan_ref = packet->vlan != 0 ? packet->inner_vlan : packet->vlan;
|
||||
vlan_ref = ((pdata[0] << 8u) + pdata[1]) & 0xfff;
|
||||
|
||||
identifier_t protocol = ((pdata[2] << 8u) + pdata[3]);
|
||||
packet->eth_type = protocol;
|
||||
pdata += 4; // Skip the VLAN header
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/vlan/VLAN.h
Normal file
23
src/packet_analysis/protocol/vlan/VLAN.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::VLAN {
|
||||
|
||||
class VLANAnalyzer : public Analyzer {
|
||||
public:
|
||||
VLANAnalyzer();
|
||||
~VLANAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new VLANAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
8
src/packet_analysis/protocol/wrapper/CMakeLists.txt
Normal file
8
src/packet_analysis/protocol/wrapper/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
include(ZeekPlugin)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(LLAnalyzer Wrapper)
|
||||
zeek_plugin_cc(Wrapper.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
24
src/packet_analysis/protocol/wrapper/Plugin.cc
Normal file
24
src/packet_analysis/protocol/wrapper/Plugin.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Wrapper.h"
|
||||
#include "plugin/Plugin.h"
|
||||
#include "packet_analysis/Component.h"
|
||||
|
||||
namespace zeek::plugin::LLAnalyzer {
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
public:
|
||||
zeek::plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("Wrapper",
|
||||
zeek::packet_analysis::Wrapper::WrapperAnalyzer::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::Wrapper";
|
||||
config.description = "A wrapper for the original zeek code.";
|
||||
return config;
|
||||
}
|
||||
|
||||
} plugin;
|
||||
|
||||
}
|
163
src/packet_analysis/protocol/wrapper/Wrapper.cc
Normal file
163
src/packet_analysis/protocol/wrapper/Wrapper.cc
Normal file
|
@ -0,0 +1,163 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "Wrapper.h"
|
||||
#include "NetVar.h"
|
||||
|
||||
using namespace zeek::packet_analysis::Wrapper;
|
||||
|
||||
WrapperAnalyzer::WrapperAnalyzer()
|
||||
: zeek::packet_analysis::Analyzer("Wrapper")
|
||||
{
|
||||
}
|
||||
|
||||
std::tuple<zeek::packet_analysis::AnalyzerResult, zeek::packet_analysis::identifier_t> WrapperAnalyzer::Analyze(Packet* packet)
|
||||
{
|
||||
// Unfortunately some packets on the link might have MPLS labels
|
||||
// while others don't. That means we need to ask the link-layer if
|
||||
// labels are in place.
|
||||
bool have_mpls = false;
|
||||
|
||||
auto pdata = packet->cur_pos;
|
||||
auto end_of_data = packet->GetEndOfData();
|
||||
|
||||
// Skip past Cisco FabricPath to encapsulated ethernet frame.
|
||||
if ( pdata[12] == 0x89 && pdata[13] == 0x03 )
|
||||
{
|
||||
auto constexpr cfplen = 16;
|
||||
|
||||
if ( pdata + cfplen + 14 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header_cfp");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
pdata += cfplen;
|
||||
}
|
||||
|
||||
// Extract protocol identifier
|
||||
identifier_t protocol = (pdata[12] << 8u) + pdata[13];
|
||||
|
||||
packet->eth_type = protocol;
|
||||
packet->l2_dst = pdata;
|
||||
packet->l2_src = pdata + 6;
|
||||
|
||||
pdata += 14;
|
||||
|
||||
bool saw_vlan = false;
|
||||
|
||||
while ( protocol == 0x8100 || protocol == 0x9100 ||
|
||||
protocol == 0x8864 )
|
||||
{
|
||||
switch ( protocol )
|
||||
{
|
||||
// VLAN carried over the ethernet frame.
|
||||
// 802.1q / 802.1ad
|
||||
case 0x8100:
|
||||
case 0x9100:
|
||||
{
|
||||
if ( pdata + 4 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
auto& vlan_ref = saw_vlan ? packet->inner_vlan : packet->vlan;
|
||||
vlan_ref = ((pdata[0] << 8u) + pdata[1]) & 0xfff;
|
||||
protocol = ((pdata[2] << 8u) + pdata[3]);
|
||||
pdata += 4; // Skip the vlan header
|
||||
saw_vlan = true;
|
||||
packet->eth_type = protocol;
|
||||
}
|
||||
break;
|
||||
|
||||
// PPPoE carried over the ethernet frame.
|
||||
case 0x8864:
|
||||
{
|
||||
if ( pdata + 8 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
protocol = (pdata[6] << 8u) + pdata[7];
|
||||
pdata += 8; // Skip the PPPoE session and PPP header
|
||||
|
||||
if ( protocol == 0x0021 )
|
||||
packet->l3_proto = L3_IPV4;
|
||||
else if ( protocol == 0x0057 )
|
||||
packet->l3_proto = L3_IPV6;
|
||||
else
|
||||
{
|
||||
// Neither IPv4 nor IPv6.
|
||||
packet->Weird("non_ip_packet_in_pppoe_encapsulation");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for MPLS in VLAN.
|
||||
if ( protocol == 0x8847 )
|
||||
have_mpls = true;
|
||||
|
||||
// Normal path to determine Layer 3 protocol.
|
||||
if ( ! have_mpls && packet->l3_proto == L3_UNKNOWN )
|
||||
{
|
||||
if ( protocol == 0x800 )
|
||||
packet->l3_proto = L3_IPV4;
|
||||
else if ( protocol == 0x86dd )
|
||||
packet->l3_proto = L3_IPV6;
|
||||
else if ( protocol == 0x0806 || protocol == 0x8035 )
|
||||
packet->l3_proto = L3_ARP;
|
||||
else
|
||||
{
|
||||
// Neither IPv4 nor IPv6.
|
||||
packet->Weird("non_ip_packet_in_ethernet");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
if ( have_mpls )
|
||||
{
|
||||
// Skip the MPLS label stack.
|
||||
bool end_of_stack = false;
|
||||
|
||||
while ( ! end_of_stack )
|
||||
{
|
||||
if ( pdata + 4 >= end_of_data )
|
||||
{
|
||||
packet->Weird("truncated_link_header");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
end_of_stack = *(pdata + 2u) & 0x01;
|
||||
pdata += 4;
|
||||
}
|
||||
|
||||
// We assume that what remains is IP
|
||||
if ( pdata + sizeof(struct ip) >= end_of_data )
|
||||
{
|
||||
packet->Weird("no_ip_in_mpls_payload");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
|
||||
const struct ip* ip = (const struct ip*)pdata;
|
||||
|
||||
if ( ip->ip_v == 4 )
|
||||
packet->l3_proto = L3_IPV4;
|
||||
else if ( ip->ip_v == 6 )
|
||||
packet->l3_proto = L3_IPV6;
|
||||
else
|
||||
{
|
||||
// Neither IPv4 nor IPv6.
|
||||
packet->Weird("no_ip_in_mpls_payload");
|
||||
return { AnalyzerResult::Failed, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate how much header we've used up.
|
||||
packet->hdr_size = (pdata - packet->data);
|
||||
|
||||
return { AnalyzerResult::Continue, protocol };
|
||||
}
|
23
src/packet_analysis/protocol/wrapper/Wrapper.h
Normal file
23
src/packet_analysis/protocol/wrapper/Wrapper.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <packet_analysis/Analyzer.h>
|
||||
#include <packet_analysis/Component.h>
|
||||
|
||||
namespace zeek::packet_analysis::Wrapper {
|
||||
|
||||
class WrapperAnalyzer : public Analyzer {
|
||||
public:
|
||||
WrapperAnalyzer();
|
||||
~WrapperAnalyzer() override = default;
|
||||
|
||||
std::tuple<AnalyzerResult, identifier_t> Analyze(Packet* packet) override;
|
||||
|
||||
static Analyzer* Instantiate()
|
||||
{
|
||||
return new WrapperAnalyzer();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue