mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 07:38:19 +00:00
Add method for packet analyzers to register for protocol detection
This commit is contained in:
parent
a7d3cb48ef
commit
d4f57a6100
3 changed files with 99 additions and 18 deletions
|
@ -77,22 +77,35 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet,
|
|||
uint32_t identifier) const
|
||||
{
|
||||
auto inner_analyzer = Lookup(identifier);
|
||||
if ( ! inner_analyzer )
|
||||
{
|
||||
for ( const auto& child : analyzers_to_detect )
|
||||
{
|
||||
if ( child->DetectProtocol(len, data, packet) )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS,
|
||||
"Protocol detection in %s succeeded, next layer analyzer is %s",
|
||||
GetAnalyzerName(), child->GetAnalyzerName());
|
||||
inner_analyzer = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! inner_analyzer )
|
||||
inner_analyzer = default_analyzer;
|
||||
|
||||
if ( inner_analyzer == nullptr )
|
||||
{
|
||||
if ( report_unknown_protocols )
|
||||
if ( ! inner_analyzer )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS,
|
||||
"Analysis in %s failed, could not find analyzer for identifier %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
|
||||
if ( report_unknown_protocols )
|
||||
packet_mgr->ReportUnknownProtocol(GetAnalyzerName(), identifier, data, len);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s succeeded, next layer identifier is %#x.",
|
||||
GetAnalyzerName(), identifier);
|
||||
|
@ -101,16 +114,35 @@ bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet,
|
|||
|
||||
bool Analyzer::ForwardPacket(size_t len, const uint8_t* data, Packet* packet) const
|
||||
{
|
||||
if ( default_analyzer )
|
||||
return default_analyzer->AnalyzePacket(len, data, packet);
|
||||
AnalyzerPtr inner_analyzer = nullptr;
|
||||
|
||||
for ( const auto& child : analyzers_to_detect )
|
||||
{
|
||||
if ( child->DetectProtocol(len, data, packet) )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS,
|
||||
"Protocol detection in %s succeeded, next layer analyzer is %s",
|
||||
GetAnalyzerName(), child->GetAnalyzerName());
|
||||
inner_analyzer = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! inner_analyzer )
|
||||
inner_analyzer = default_analyzer;
|
||||
|
||||
if ( ! inner_analyzer )
|
||||
{
|
||||
DBG_LOG(DBG_PACKET_ANALYSIS, "Analysis in %s stopped, no default analyzer available.",
|
||||
GetAnalyzerName());
|
||||
|
||||
if ( report_unknown_protocols )
|
||||
Weird("no_suitable_analyzer_found", packet);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return inner_analyzer->AnalyzePacket(len, data, packet);
|
||||
}
|
||||
|
||||
void Analyzer::DumpDebug() const
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "zeek/Tag.h"
|
||||
#include "zeek/iosource/Packet.h"
|
||||
#include "zeek/packet_analysis/Manager.h"
|
||||
|
@ -98,6 +100,32 @@ public:
|
|||
*/
|
||||
void RegisterProtocol(uint32_t identifier, AnalyzerPtr child);
|
||||
|
||||
/**
|
||||
* Registers an analyzer to use for protocol detection if identifier
|
||||
* matching fails. This will also be preferred over the default analyzer
|
||||
* if one exists.
|
||||
*
|
||||
* @param child The analyzer that will be called for protocol detection.
|
||||
*/
|
||||
void RegisterProtocolDetection(AnalyzerPtr child) { analyzers_to_detect.insert(child); }
|
||||
|
||||
/**
|
||||
* Detects whether the protocol for an analyzer can be found in the packet
|
||||
* data. Packet analyzers can overload this method to provide any sort of
|
||||
* pattern-matching or byte-value detection against the packet data to
|
||||
* determine whether the packet contains the analyzer's protocol. The
|
||||
* analyzer must also register for the detection in script-land using the
|
||||
* PacketAnalyzer::register_protocol_detection bif method.
|
||||
*
|
||||
* @param len The number of bytes passed in. As we move along the chain of
|
||||
* analyzers, this is the number of bytes we have left of the packet to
|
||||
* process.
|
||||
* @param data Pointer to the input to process.
|
||||
* @param packet Object that maintains the packet's meta data.
|
||||
* @return true if the protocol is detected in the packet data.
|
||||
*/
|
||||
virtual bool DetectProtocol(size_t len, const uint8_t* data, Packet* packet) { return false; }
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
|
@ -174,6 +202,8 @@ private:
|
|||
*/
|
||||
bool report_unknown_protocols = true;
|
||||
|
||||
std::set<AnalyzerPtr> analyzers_to_detect;
|
||||
|
||||
void Init(const zeek::Tag& tag);
|
||||
};
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ function register_packet_analyzer%(parent: PacketAnalyzer::Tag, identifier: coun
|
|||
return zeek::val_mgr->True();
|
||||
%}
|
||||
|
||||
## Attempts to add an entry to `parent`'s dispatcher that maps a protocol/index to a next-stage `child` analyzer.
|
||||
## This may fail if either of the two names does not respond to a known analyzer.
|
||||
## Attempts to add an entry to `parent`'s dispatcher that maps a protocol/index to a next-stage `child`
|
||||
## analyzer. This may fail if either of the two names does not respond to a known analyzer.
|
||||
##
|
||||
## parent: The parent analyzer being modified
|
||||
## identifier: The identifier for the protocol being registered
|
||||
|
@ -58,3 +58,22 @@ function PacketAnalyzer::__set_ignore_checksums_nets%(v: subnet_set%) : bool
|
|||
zeek::packet_analysis::IP::IPBasedAnalyzer::SetIgnoreChecksumsNets(zeek::IntrusivePtr{zeek::NewRef{}, v->AsTableVal()});
|
||||
return zeek::val_mgr->True();
|
||||
%}
|
||||
|
||||
## Registers a child analyzer with a parent analyzer to perform packet detection when determining whether
|
||||
## to forward from parent to child.
|
||||
##
|
||||
## parent: The parent analyzer being modified
|
||||
## child: The analyzer that will use protocol detection
|
||||
function register_protocol_detection%(parent: PacketAnalyzer::Tag, child: PacketAnalyzer::Tag%): bool
|
||||
%{
|
||||
packet_analysis::AnalyzerPtr parent_analyzer = packet_mgr->GetAnalyzer(parent->AsEnumVal());
|
||||
if ( ! parent_analyzer )
|
||||
return zeek::val_mgr->False();
|
||||
|
||||
packet_analysis::AnalyzerPtr child_analyzer = packet_mgr->GetAnalyzer(child->AsEnumVal());
|
||||
if ( ! child_analyzer )
|
||||
return zeek::val_mgr->False();
|
||||
|
||||
parent_analyzer->RegisterProtocolDetection(child_analyzer);
|
||||
return zeek::val_mgr->True();
|
||||
%}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue