mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 02:28:21 +00:00
182 lines
5.4 KiB
C++
182 lines
5.4 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
#pragma once
|
|
|
|
#include "zeek/iosource/Packet.h"
|
|
#include "zeek/packet_analysis/Manager.h"
|
|
#include "zeek/packet_analysis/Tag.h"
|
|
|
|
namespace zeek::packet_analysis
|
|
{
|
|
|
|
/**
|
|
* Main packet analyzer interface.
|
|
*/
|
|
class Analyzer
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param name The name for the type of analyzer. The name must match
|
|
* the one the corresponding Component registers.
|
|
* @param report_unknown_protocols Flag for whether to report unknown
|
|
* protocols during packet forwarding. This should generally always be
|
|
* set to true.
|
|
*/
|
|
explicit Analyzer(std::string name, bool report_unknown_protocols = true);
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Initialize the analyzer. This method is called after the configuration
|
|
* was read. Derived classes can override this method to implement custom
|
|
* initialization.
|
|
* When overriding this methods, always make sure to call the base-class
|
|
* version to ensure proper initialization.
|
|
*/
|
|
virtual void Initialize();
|
|
|
|
/**
|
|
* 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. A common case is that the analyzed protocol
|
|
* encapsulates another protocol, which can be determined by an identifier
|
|
* in the header. In this case, derived classes may use ForwardPacket() to
|
|
* forward the payload to the corresponding analyzer.
|
|
*
|
|
* @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 false if the analysis failed, else true.
|
|
*/
|
|
virtual bool AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) = 0;
|
|
|
|
/**
|
|
* Dumps out debug information to the \c analyzer debug stream.
|
|
*/
|
|
void DumpDebug() const;
|
|
|
|
/**
|
|
* Adds a protocol to this analyzer's dispatcher.
|
|
*
|
|
* @param idenfitier The identifier for the protocol being added.
|
|
* @param child The analyzer that will be called for the new protocol during
|
|
* forwarding.
|
|
*/
|
|
void RegisterProtocol(uint32_t identifier, AnalyzerPtr child);
|
|
|
|
protected:
|
|
friend class Manager;
|
|
|
|
/**
|
|
* Looks up the analyzer for the encapsulated protocol based on the given
|
|
* identifier.
|
|
*
|
|
* @param identifier Identifier for the encapsulated protocol.
|
|
* @return The analyzer registered for the given identifier. Returns a
|
|
* nullptr if no analyzer is registered.
|
|
*/
|
|
AnalyzerPtr Lookup(uint32_t identifier) const;
|
|
|
|
/**
|
|
* Returns an analyzer based on a script-land definition.
|
|
*
|
|
* @param name The script-land identifier for a PacketAnalyzer::Tag value.
|
|
* @return The defined analyzer if available, else nullptr.
|
|
*/
|
|
AnalyzerPtr LoadAnalyzer(const std::string& name);
|
|
|
|
/**
|
|
* Returns the module name corresponding to the analyzer, i.e. its script-land
|
|
* namespace. Configuration values for the analyzer are expected in this module.
|
|
* @return Analyzer's module name.
|
|
*/
|
|
std::string GetModuleName() const
|
|
{
|
|
return util::fmt("PacketAnalyzer::%s::", GetAnalyzerName());
|
|
};
|
|
|
|
/**
|
|
* Triggers analysis of the encapsulated packet. The encapsulated protocol
|
|
* is determined using the given identifier.
|
|
*
|
|
* @param packet The packet to analyze.
|
|
* @param data Reference to the payload pointer into the raw packet.
|
|
* @param identifier The identifier of the encapsulated protocol.
|
|
*
|
|
* @return false if the analysis failed, else true.
|
|
*/
|
|
bool ForwardPacket(size_t len, const uint8_t* data, Packet* packet, uint32_t identifier) const;
|
|
|
|
/**
|
|
* Triggers default analysis of the encapsulated packet if the default analyzer
|
|
* is set.
|
|
*
|
|
* @param packet The packet to analyze.
|
|
* @param data Reference to the payload pointer into the raw packet.
|
|
*
|
|
* @return false if the analysis failed, else true.
|
|
*/
|
|
bool ForwardPacket(size_t len, const uint8_t* data, Packet* packet) const;
|
|
|
|
/**
|
|
* Reports a Weird with the analyzer's name included in the addl field.
|
|
*
|
|
* @param name The name of the weird.
|
|
* @param packet An optional pointer to a packet to be used for additional
|
|
* information in the weird output.
|
|
* @param addl An optional string containing additional information about
|
|
* the weird. If this is passed, the analyzer's name will be prepended to
|
|
* it before output.
|
|
*/
|
|
void Weird(const char* name, Packet* packet = nullptr, const char* addl = "") const;
|
|
|
|
private:
|
|
Tag tag;
|
|
Dispatcher dispatcher;
|
|
AnalyzerPtr default_analyzer = nullptr;
|
|
|
|
/**
|
|
* Flag for whether to report unknown protocols in ForwardPacket.
|
|
*/
|
|
bool report_unknown_protocols = true;
|
|
|
|
void Init(const Tag& tag);
|
|
};
|
|
|
|
using AnalyzerPtr = std::shared_ptr<Analyzer>;
|
|
|
|
}
|