Move analyzer-to-port mapping out of analyzer::Manager into packet analyzers

This commit is contained in:
Tim Wojtulewicz 2021-05-17 18:09:38 -07:00
parent d6c74373c7
commit 9e1f6f95aa
11 changed files with 154 additions and 89 deletions

View file

@ -5,6 +5,7 @@
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
#include "zeek/analyzer/Analyzer.h"
#include "zeek/RuleMatcher.h"

View file

@ -3,6 +3,7 @@
#include "zeek/plugin/Plugin.h"
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/icmp/ICMP.h"
#include "zeek/analyzer/Component.h"
namespace zeek::plugin::Zeek_ICMP {

View file

@ -22,6 +22,8 @@ IPBasedAnalyzer::IPBasedAnalyzer(const char* name, TransportProto proto, uint32_
IPBasedAnalyzer::~IPBasedAnalyzer()
{
for ( const auto& mapping : analyzers_by_port )
delete mapping.second;
}
bool IPBasedAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pkt)
@ -212,9 +214,6 @@ bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn)
SessionAdapter* root = MakeSessionAdapter(conn);
analyzer::pia::PIA* pia = MakePIA(conn);
// TODO: temporary, can be replaced when the port lookup stuff is moved from analyzer_mgr
bool check_port = conn->ConnTransport() != TRANSPORT_ICMP;
bool scheduled = analyzer_mgr->ApplyScheduledAnalyzers(conn, false, root);
// Hmm... Do we want *just* the expected analyzer, or all
@ -222,14 +221,10 @@ bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn)
// the scheduled ones.
if ( ! scheduled )
{ // Let's see if it's a port we know.
if ( check_port && ! zeek::detail::dpd_ignore_ports )
if ( ! analyzers_by_port.empty() && ! zeek::detail::dpd_ignore_ports )
{
// TODO: ideally this lookup would be local to the packet analyzer instead of
// calling out to the analyzer manager. This code can move once the TCP work
// is in progress so that it doesn't have to be done piecemeal.
//
int resp_port = ntohs(conn->RespPort());
std::set<analyzer::Tag>* ports = analyzer_mgr->LookupPort(conn->ConnTransport(), resp_port, false);
std::set<analyzer::Tag>* ports = LookupPort(resp_port, false);
if ( ports )
{
@ -262,3 +257,63 @@ bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn)
// TODO: temporary
return true;
}
bool IPBasedAnalyzer::RegisterAnalyzerForPort(const analyzer::Tag& tag, uint32_t port)
{
tag_set* l = LookupPort(port, true);
if ( ! l )
return false;
#ifdef DEBUG
const char* name = analyzer_mgr->GetComponentName(tag).c_str();
DBG_LOG(DBG_ANALYZER, "Registering analyzer %s for port %" PRIu32 "/%d", name, port, transport);
#endif
l->insert(tag);
return true;
}
bool IPBasedAnalyzer::UnregisterAnalyzerForPort(const analyzer::Tag& tag, uint32_t port)
{
tag_set* l = LookupPort(port, true);
if ( ! l )
return true; // still a "successful" unregistration
#ifdef DEBUG
const char* name = analyzer_mgr->GetComponentName(tag).c_str();
DBG_LOG(DBG_ANALYZER, "Unregistering analyzer %s for port %" PRIu32 "/%d", name, port, transport);
#endif
l->erase(tag);
return true;
}
IPBasedAnalyzer::tag_set* IPBasedAnalyzer::LookupPort(uint32_t port, bool add_if_not_found)
{
analyzer_map_by_port::const_iterator i = analyzers_by_port.find(port);
if ( i != analyzers_by_port.end() )
return i->second;
if ( ! add_if_not_found )
return nullptr;
tag_set* l = new tag_set{};
analyzers_by_port.insert(std::make_pair(port, l));
return l;
}
void IPBasedAnalyzer::DumpPortDebug()
{
for ( const auto& mapping : analyzers_by_port )
{
std::string s;
for ( const auto& tag : *(mapping.second) )
s += std::string(analyzer_mgr->GetComponentName(tag)) + " ";
DBG_LOG(DBG_ANALYZER, " %d/%s: %s", mapping.first, transport_proto_string(transport), s.c_str());
}
}

View file

@ -2,16 +2,18 @@
#pragma once
#include <map>
#include <set>
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
#include "zeek/analyzer/Analyzer.h"
#include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/Tag.h"
namespace zeek::analyzer::pia { class PIA; }
namespace zeek::packet_analysis::IP {
class SessionAdapter;
/**
* A base class for reuse by packet analyzers based on IP. This is used by default
* by the TCP, UDP, and ICMP analyzers to reduce a large amount of duplicated code
@ -32,6 +34,33 @@ public:
*/
virtual bool IsReuse(double t, const u_char* pkt) { return false; }
/**
* Registers a well-known port for an analyzer. Once registered,
* connection on that port will start with a corresponding analyzer
* assigned.
*
* @param tag The analyzer's tag.
* @param port The port's number.
* @return True if successful.
*/
bool RegisterAnalyzerForPort(const analyzer::Tag& tag, uint32_t port);
/**
* Unregisters a well-known port for an analyzer.
*
* @param tag The analyzer's tag.
* @param port The port's number.
* @param tag The analyzer's tag as an enum of script type \c
* Analyzer::Tag.
*/
bool UnregisterAnalyzerForPort(const analyzer::Tag& tag, uint32_t port);
/**
* Dumps information about the registered session analyzers per port.
* Used by analyzer::Manager.
*/
void DumpPortDebug();
protected:
/**
@ -129,6 +158,15 @@ protected:
private:
// While this is storing session analyzer tags, we store it here since packet analyzers
// are persitent objects. We can't do this in the adapters because those get created
// and destroyed for each connection.
using tag_set = std::set<analyzer::Tag>;
using analyzer_map_by_port = std::map<uint32_t, tag_set*>;
analyzer_map_by_port analyzers_by_port;
tag_set* LookupPort(uint32_t port, bool add_if_not_found);
/**
* Creates a new Connection object from data gleaned from the current packet.
*

View file

@ -4,6 +4,7 @@
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
#include "zeek/packet_analysis/protocol/tcp/TCPSessionAdapter.h"
#include "zeek/analyzer/Component.h"
namespace zeek::plugin::Zeek_TCP {

View file

@ -3,6 +3,7 @@
#include "zeek/plugin/Plugin.h"
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/udp/UDP.h"
#include "zeek/analyzer/Component.h"
namespace zeek::plugin::Zeek_UDP {

View file

@ -5,6 +5,7 @@
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/packet_analysis/Component.h"
#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h"
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
namespace zeek::packet_analysis::UDP {