diff --git a/src/Conn.cc b/src/Conn.cc index da76dc509c..d2d8d0f3da 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -19,6 +19,7 @@ #include "zeek/analyzer/Analyzer.h" #include "zeek/analyzer/Manager.h" #include "zeek/iosource/IOSource.h" +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" namespace zeek { @@ -64,7 +65,7 @@ Connection::Connection(const detail::ConnKey& k, double t, hist_seen = 0; history = ""; - root_analyzer = nullptr; + adapter = nullptr; primary_PIA = nullptr; ++current_connections; @@ -83,7 +84,7 @@ Connection::~Connection() if ( conn_val ) conn_val->SetOrigin(nullptr); - delete root_analyzer; + delete adapter; --current_connections; } @@ -129,7 +130,7 @@ void Connection::Done() // somewhere, but it's session-related, so maybe not? if ( ConnTransport() == TRANSPORT_TCP ) { - auto ta = static_cast(GetRootAnalyzer()); + auto ta = static_cast(adapter); assert(ta->IsAnalyzer("TCP")); analyzer::tcp::TCP_Endpoint* to = ta->Orig(); analyzer::tcp::TCP_Endpoint* tr = ta->Resp(); @@ -139,8 +140,8 @@ void Connection::Done() finished = 1; - if ( root_analyzer && ! root_analyzer->IsFinished() ) - root_analyzer->Done(); + if ( adapter && ! adapter->IsFinished() ) + adapter->Done(); } void Connection::NextPacket(double t, bool is_orig, @@ -156,11 +157,11 @@ void Connection::NextPacket(double t, bool is_orig, if ( Skipping() ) return; - if ( root_analyzer ) + if ( adapter ) { record_current_packet = record_packet; record_current_content = record_content; - root_analyzer->NextPacket(len, data, is_orig, -1, ip, caplen); + adapter->NextPacket(len, data, is_orig, -1, ip, caplen); record_packet = record_current_packet; record_content = record_current_content; } @@ -173,7 +174,7 @@ void Connection::NextPacket(double t, bool is_orig, bool Connection::IsReuse(double t, const u_char* pkt) { - return root_analyzer && root_analyzer->IsReuse(t, pkt); + return adapter && adapter->IsReuse(t, pkt); } bool Connection::ScaledHistoryEntry(char code, uint32_t& counter, @@ -275,8 +276,8 @@ const RecordValPtr& Connection::GetVal() } - if ( root_analyzer ) - root_analyzer->UpdateConnVal(conn_val.get()); + if ( adapter ) + adapter->UpdateConnVal(conn_val.get()); conn_val->AssignTime(3, start_time); // ### conn_val->AssignInterval(4, last_time - start_time); @@ -289,17 +290,17 @@ const RecordValPtr& Connection::GetVal() analyzer::Analyzer* Connection::FindAnalyzer(analyzer::ID id) { - return root_analyzer ? root_analyzer->FindChild(id) : nullptr; + return adapter ? adapter->FindChild(id) : nullptr; } analyzer::Analyzer* Connection::FindAnalyzer(const analyzer::Tag& tag) { - return root_analyzer ? root_analyzer->FindChild(tag) : nullptr; + return adapter ? adapter->FindChild(tag) : nullptr; } analyzer::Analyzer* Connection::FindAnalyzer(const char* name) { - return root_analyzer->FindChild(name); + return adapter->FindChild(name); } void Connection::AppendAddl(const char* str) @@ -370,8 +371,8 @@ void Connection::FlipRoles() conn_val = nullptr; - if ( root_analyzer ) - root_analyzer->FlipRoles(); + if ( adapter ) + adapter->FlipRoles(); analyzer_mgr->ApplyScheduledAnalyzers(this); @@ -383,7 +384,7 @@ unsigned int Connection::MemoryAllocation() const return session::Session::MemoryAllocation() + padded_sizeof(*this) + (timers.MemoryAllocation() - padded_sizeof(timers)) + (conn_val ? conn_val->MemoryAllocation() : 0) - + (root_analyzer ? root_analyzer->MemoryAllocation(): 0) + + (adapter ? adapter->MemoryAllocation(): 0) // primary_PIA is already contained in the analyzer tree. ; } @@ -448,10 +449,10 @@ void Connection::IDString(ODesc* d) const d->Add(ntohs(resp_port)); } -void Connection::SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, - analyzer::pia::PIA* pia) +void Connection::SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, + analyzer::pia::PIA* pia) { - root_analyzer = analyzer; + adapter = aa; primary_PIA = pia; } diff --git a/src/Conn.h b/src/Conn.h index d6ca89a27b..20a5b138c4 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -41,12 +41,8 @@ class RuleHdrTest; } // namespace detail -namespace analyzer { - -class TransportLayerAnalyzer; -class Analyzer; - -} // namespace analyzer +namespace analyzer { class Analyzer; } +namespace packet_analysis::IP { class SessionAdapter; } enum ConnEventToFlag { NUL_IN_LINE, @@ -231,8 +227,8 @@ public: void AddHistory(char code) { history += code; } // Sets the root of the analyzer tree as well as the primary PIA. - void SetRootAnalyzer(analyzer::TransportLayerAnalyzer* analyzer, analyzer::pia::PIA* pia); - analyzer::TransportLayerAnalyzer* GetRootAnalyzer() { return root_analyzer; } + void SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, analyzer::pia::PIA* pia); + packet_analysis::IP::SessionAdapter* GetSessionAdapter() { return adapter; } analyzer::pia::PIA* GetPrimaryPIA() { return primary_PIA; } // Sets the transport protocol in use. @@ -279,7 +275,7 @@ private: uint32_t hist_seen; std::string history; - analyzer::TransportLayerAnalyzer* root_analyzer; + packet_analysis::IP::SessionAdapter* adapter; analyzer::pia::PIA* primary_PIA; UID uid; // Globally unique connection ID. diff --git a/src/RuleCondition.cc b/src/RuleCondition.cc index 33de7f86fc..b765cbaded 100644 --- a/src/RuleCondition.cc +++ b/src/RuleCondition.cc @@ -25,12 +25,12 @@ namespace zeek::detail { bool RuleConditionTCPState::DoMatch(Rule* rule, RuleEndpointState* state, const u_char* data, int len) { - analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer(); + auto* adapter = state->GetAnalyzer()->Conn()->GetSessionAdapter(); - if ( ! root || ! root->IsAnalyzer("TCP") ) + if ( ! adapter || ! adapter->IsAnalyzer("TCP") ) return false; - auto* ta = static_cast(root); + auto* ta = static_cast(adapter); if ( tcpstates & RULE_STATE_STATELESS ) return true; @@ -57,9 +57,9 @@ void RuleConditionTCPState::PrintDebug() bool RuleConditionUDPState::DoMatch(Rule* rule, RuleEndpointState* state, const u_char* data, int len) { - analyzer::Analyzer* root = state->GetAnalyzer()->Conn()->GetRootAnalyzer(); + auto* adapter = state->GetAnalyzer()->Conn()->GetSessionAdapter(); - if ( ! root || ! root->IsAnalyzer("UDP") ) + if ( ! adapter || ! adapter->IsAnalyzer("UDP") ) return false; if ( states & RULE_STATE_STATELESS ) diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index 2f3bb22fcc..074e7407ab 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -880,31 +880,4 @@ void SupportAnalyzer::ForwardUndelivered(uint64_t seq, int len, bool is_orig) } -void TransportLayerAnalyzer::Done() - { - Analyzer::Done(); - } - -void TransportLayerAnalyzer::SetContentsFile(unsigned int /* direction */, - FilePtr /* f */) - { - reporter->Error("analyzer type does not support writing to a contents file"); - } - -FilePtr TransportLayerAnalyzer::GetContentsFile(unsigned int /* direction */) const - { - reporter->Error("analyzer type does not support writing to a contents file"); - return nullptr; - } - -void TransportLayerAnalyzer::PacketContents(const u_char* data, int len) - { - if ( packet_contents && len > 0 ) - { - String* cbs = new String(data, len, true); - auto contents = make_intrusive(cbs); - EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents)); - } - } - } // namespace zeek::analyzer diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 415086b13e..c4505051a1 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -846,83 +846,4 @@ private: #define CONTENTS_RESP 2 #define CONTENTS_BOTH 3 -/** - * Base class for analyzers parsing transport-layer protocols. - */ -class TransportLayerAnalyzer : public Analyzer { -public: - /** - * Constructor. - * - * @param name A name for the protocol the analyzer is parsing. The - * name must match the one the corresponding Component registers. - * - * @param conn The connection the analyzer is associated with. - */ - TransportLayerAnalyzer(const char* name, Connection* conn) - : Analyzer(name, conn) { pia = nullptr; } - - /** - * Overridden from parent class. - */ - void Done() override; - - /** - * Returns true if the analyzer determines that in fact a new - * connection has started without the connection statement having - * terminated the previous one, i.e., the new data is arriving at - * what's the analyzer for the previous instance. This is used only - * for TCP. - */ - virtual bool IsReuse(double t, const u_char* pkt) = 0; - - /** - * Associates a file with the analyzer in which to record all - * analyzed input. This must only be called with derived classes that - * overide the method; the default implementation will abort. - * - * @param direction One of the CONTENTS_* constants indicating which - * direction of the input stream is to be recorded. - * - * @param f The file to record to. - * - */ - virtual void SetContentsFile(unsigned int direction, FilePtr f); - - /** - * Returns an associated contents file, if any. This must only be - * called with derived classes that overide the method; the default - * implementation will abort. - * - * @param direction One of the CONTENTS_* constants indicating which - * direction the query is for. - */ - virtual FilePtr GetContentsFile(unsigned int direction) const; - - /** - * Associates a PIA with this analyzer. A PIA takes the - * transport-layer input and determine which protocol analyzer(s) to - * use for parsing it. - */ - void SetPIA(analyzer::pia::PIA* arg_PIA) { pia = arg_PIA; } - - /** - * Returns the associated PIA, or null of none. Does not take - * ownership. - */ - analyzer::pia::PIA* GetPIA() const { return pia; } - - /** - * Helper to raise a \c packet_contents event. - * - * @param data The dass to pass to the event. - * - * @param len The length of \a data. - */ - void PacketContents(const u_char* data, int len); - -private: - analyzer::pia::PIA* pia; -}; - } // namespace zeek::analyzer diff --git a/src/analyzer/Manager.cc b/src/analyzer/Manager.cc index 91ae7c3bc7..27b0621b31 100644 --- a/src/analyzer/Manager.cc +++ b/src/analyzer/Manager.cc @@ -12,6 +12,7 @@ #include "zeek/analyzer/protocol/stepping-stone/SteppingStone.h" #include "zeek/analyzer/protocol/tcp/TCP.h" #include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h" +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" #include "zeek/plugin/Manager.h" @@ -356,7 +357,7 @@ Manager::tag_set* Manager::LookupPort(TransportProto proto, uint32_t port, bool bool Manager::BuildInitialAnalyzerTree(Connection* conn) { analyzer::tcp::TCP_Analyzer* tcp = nullptr; - TransportLayerAnalyzer* root = nullptr; + packet_analysis::IP::SessionAdapter* root = nullptr; analyzer::pia::PIA* pia = nullptr; bool check_port = false; @@ -470,7 +471,7 @@ bool Manager::BuildInitialAnalyzerTree(Connection* conn) if ( pia ) root->AddChildAnalyzer(pia->AsAnalyzer()); - conn->SetRootAnalyzer(root, pia); + conn->SetSessionAdapter(root, pia); root->Init(); root->InitChildren(); @@ -588,10 +589,11 @@ Manager::tag_set Manager::GetScheduled(const Connection* conn) return result; } -bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init, TransportLayerAnalyzer* parent) +bool Manager::ApplyScheduledAnalyzers(Connection* conn, bool init, + packet_analysis::IP::SessionAdapter* parent) { if ( ! parent ) - parent = conn->GetRootAnalyzer(); + parent = conn->GetSessionAdapter(); if ( ! parent ) return false; diff --git a/src/analyzer/Manager.h b/src/analyzer/Manager.h index ed9fa51ea4..65c38a6fbf 100644 --- a/src/analyzer/Manager.h +++ b/src/analyzer/Manager.h @@ -36,7 +36,12 @@ namespace zeek { -namespace packet_analysis::IP { class IPBasedAnalyzer; } +namespace packet_analysis::IP { + +class IPBasedAnalyzer; +class SessionAdapter; + +} // namespace packet_analysis::IP namespace analyzer { @@ -316,7 +321,7 @@ public: * @return True if at least one scheduled analyzer was found. */ bool ApplyScheduledAnalyzers(Connection* conn, bool init_and_event = true, - TransportLayerAnalyzer* parent = nullptr); + packet_analysis::IP::SessionAdapter* parent = nullptr); /** * Schedules a particular analyzer for an upcoming connection. Once diff --git a/src/analyzer/protocol/gnutella/Gnutella.cc b/src/analyzer/protocol/gnutella/Gnutella.cc index 661863c33d..610e8b0a5b 100644 --- a/src/analyzer/protocol/gnutella/Gnutella.cc +++ b/src/analyzer/protocol/gnutella/Gnutella.cc @@ -129,7 +129,7 @@ bool Gnutella_Analyzer::IsHTTP(std::string header) if ( Parent()->IsAnalyzer("TCP") ) { // Replay buffered data. - analyzer::pia::PIA* pia = static_cast(Parent())->GetPIA(); + analyzer::pia::PIA* pia = static_cast(Parent())->GetPIA(); if ( pia ) static_cast(pia)->ReplayStreamBuffer(a); } diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index f4a5d3b4bd..8dd7479df1 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -123,7 +123,7 @@ static RecordVal* build_syn_packet_val(bool is_orig, const IP_Hdr* ip, TCP_Analyzer::TCP_Analyzer(Connection* conn) -: TransportLayerAnalyzer("TCP", conn) + : packet_analysis::IP::SessionAdapter("TCP", conn) { // Set a timer to eventually time out this connection. ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, @@ -180,7 +180,7 @@ void TCP_Analyzer::Done() analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::ID arg_id) { - analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_id); + analyzer::Analyzer* child = packet_analysis::IP::SessionAdapter::FindChild(arg_id); if ( child ) return child; @@ -197,7 +197,7 @@ analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::ID arg_id) analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::Tag arg_tag) { - analyzer::Analyzer* child = analyzer::TransportLayerAnalyzer::FindChild(arg_tag); + analyzer::Analyzer* child = packet_analysis::IP::SessionAdapter::FindChild(arg_tag); if ( child ) return child; @@ -214,7 +214,7 @@ analyzer::Analyzer* TCP_Analyzer::FindChild(analyzer::Tag arg_tag) bool TCP_Analyzer::RemoveChildAnalyzer(analyzer::ID id) { - auto rval = analyzer::TransportLayerAnalyzer::RemoveChildAnalyzer(id); + auto rval = packet_analysis::IP::SessionAdapter::RemoveChildAnalyzer(id); if ( rval ) return rval; @@ -1048,7 +1048,7 @@ static int32_t update_last_seq(TCP_Endpoint* endpoint, uint32_t last_seq, void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64_t seq, const IP_Hdr* ip, int caplen) { - TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + packet_analysis::IP::SessionAdapter::DeliverPacket(len, data, orig, seq, ip, caplen); const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen); if ( ! tp ) diff --git a/src/analyzer/protocol/tcp/TCP.h b/src/analyzer/protocol/tcp/TCP.h index 27e42e7e91..d03920d031 100644 --- a/src/analyzer/protocol/tcp/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -6,6 +6,7 @@ #include "zeek/IPAddr.h" #include "zeek/analyzer/protocol/tcp/TCP_Endpoint.h" #include "zeek/analyzer/protocol/tcp/TCP_Flags.h" +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" #include "zeek/Conn.h" // We define two classes here: @@ -22,7 +23,7 @@ class TCP_Endpoint; class TCP_Reassembler; class TCP_ApplicationAnalyzer; -class TCP_Analyzer final : public analyzer::TransportLayerAnalyzer { +class TCP_Analyzer final : public packet_analysis::IP::SessionAdapter { public: explicit TCP_Analyzer(Connection* conn); ~TCP_Analyzer() override; @@ -72,6 +73,8 @@ public: static analyzer::Analyzer* Instantiate(Connection* conn) { return new TCP_Analyzer(conn); } + void AddExtraAnalyzers(Connection* conn) override {} + protected: friend class TCP_ApplicationAnalyzer; friend class TCP_Reassembler; diff --git a/src/analyzer/protocol/tcp/functions.bif b/src/analyzer/protocol/tcp/functions.bif index ffdc542893..65669e524a 100644 --- a/src/analyzer/protocol/tcp/functions.bif +++ b/src/analyzer/protocol/tcp/functions.bif @@ -101,7 +101,7 @@ function set_contents_file%(cid: conn_id, direction: count, f: file%): bool if ( ! c ) return zeek::val_mgr->False(); - c->GetRootAnalyzer()->SetContentsFile(direction, {zeek::NewRef{}, f}); + c->GetSessionAdapter()->SetContentsFile(direction, {zeek::NewRef{}, f}); return zeek::val_mgr->True(); %} @@ -124,7 +124,7 @@ function get_contents_file%(cid: conn_id, direction: count%): file if ( c ) { - auto cf = c->GetRootAnalyzer()->GetContentsFile(direction); + auto cf = c->GetSessionAdapter()->GetContentsFile(direction); if ( cf ) return zeek::make_intrusive(std::move(cf)); diff --git a/src/fuzzers/pop3-fuzzer.cc b/src/fuzzers/pop3-fuzzer.cc index c5d2b8e2c0..7bd036af89 100644 --- a/src/fuzzers/pop3-fuzzer.cc +++ b/src/fuzzers/pop3-fuzzer.cc @@ -41,7 +41,7 @@ static zeek::analyzer::Analyzer* add_analyzer(zeek::Connection* conn) auto a = zeek::analyzer_mgr->InstantiateAnalyzer(ZEEK_FUZZ_ANALYZER, conn); tcp->AddChildAnalyzer(a); tcp->AddChildAnalyzer(pia->AsAnalyzer()); - conn->SetRootAnalyzer(tcp, pia); + conn->SetSessionAdapter(tcp, pia); return a; } diff --git a/src/packet_analysis/protocol/icmp/ICMP.cc b/src/packet_analysis/protocol/icmp/ICMP.cc index ad04eef8f6..8ceba9cf3a 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.cc +++ b/src/packet_analysis/protocol/icmp/ICMP.cc @@ -35,9 +35,9 @@ ICMPAnalyzer::~ICMPAnalyzer() { } -IPBasedTransportAnalyzer* ICMPAnalyzer::MakeTransportAnalyzer(Connection* conn) +SessionAdapter* ICMPAnalyzer::MakeSessionAdapter(Connection* conn) { - auto* root = new ICMPTransportAnalyzer(conn); + auto* root = new ICMPSessionAdapter(conn); root->SetParent(this); conn->SetInactivityTimeout(zeek::detail::icmp_inactivity_timeout); @@ -70,13 +70,13 @@ bool ICMPAnalyzer::BuildConnTuple(size_t len, const uint8_t* data, Packet* packe void ICMPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remaining, Packet* pkt) { - auto* ta = static_cast(c->GetRootAnalyzer()); + auto* adapter = static_cast(c->GetSessionAdapter()); const u_char* data = pkt->ip_hdr->Payload(); int len = pkt->ip_hdr->PayloadLen(); if ( packet_contents && len > 0 ) - ta->PacketContents(data + 8, std::min(len, remaining) - 8); + adapter->PacketContents(data + 8, std::min(len, remaining) - 8); const struct icmp* icmpp = (const struct icmp*) data; const std::unique_ptr& ip = pkt->ip_hdr; @@ -104,25 +104,25 @@ void ICMPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int rema if ( chksum != 0xffff ) { - ta->Weird("bad_ICMP_checksum"); + adapter->Weird("bad_ICMP_checksum"); return; } } c->SetLastTime(run_state::current_timestamp); - ta->InitEndpointMatcher(ip.get(), len, is_orig); + adapter->InitEndpointMatcher(ip.get(), len, is_orig); // Move past common portion of ICMP header. data += 8; remaining -= 8; len -= 8; - ta->UpdateLength(is_orig, len); + adapter->UpdateLength(is_orig, len); if ( ip->NextProto() == IPPROTO_ICMP ) - NextICMP4(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), ta); + NextICMP4(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), adapter); else if ( ip->NextProto() == IPPROTO_ICMPV6 ) - NextICMP6(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), ta); + NextICMP6(run_state::current_timestamp, icmpp, len, remaining, data, ip.get(), adapter); else { reporter->Error("expected ICMP as IP packet's protocol, got %d", ip->NextProto()); @@ -132,43 +132,43 @@ void ICMPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int rema ForwardPacket(len, data, pkt); if ( remaining >= len ) - ta->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining); + adapter->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining); - ta->MatchEndpoint(data, len, is_orig); + adapter->MatchEndpoint(data, len, is_orig); } void ICMPAnalyzer::NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { switch ( icmpp->icmp_type ) { case ICMP_ECHO: case ICMP_ECHOREPLY: - Echo(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Echo(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ICMP_UNREACH: case ICMP_TIMXCEED: - Context4(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Context4(t, icmpp, len, caplen, data, ip_hdr, adapter); break; default: - ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr, analyzer); + ICMP_Sent(icmpp, len, caplen, 0, data, ip_hdr, adapter); break; } } void ICMPAnalyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { switch ( icmpp->icmp_type ) { // Echo types. case ICMP6_ECHO_REQUEST: case ICMP6_ECHO_REPLY: - Echo(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Echo(t, icmpp, len, caplen, data, ip_hdr, adapter); break; // Error messages all have the same structure for their context, @@ -177,27 +177,27 @@ void ICMPAnalyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int ca case ICMP6_TIME_EXCEEDED: case ICMP6_PACKET_TOO_BIG: case ICMP6_DST_UNREACH: - Context6(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Context6(t, icmpp, len, caplen, data, ip_hdr, adapter); break; // Router related messages. case ND_REDIRECT: - Redirect(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Redirect(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ND_ROUTER_ADVERT: - RouterAdvert(t, icmpp, len, caplen, data, ip_hdr, analyzer); + RouterAdvert(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ND_NEIGHBOR_ADVERT: - NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr, analyzer); + NeighborAdvert(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ND_NEIGHBOR_SOLICIT: - NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr, analyzer); + NeighborSolicit(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ND_ROUTER_SOLICIT: - RouterSolicit(t, icmpp, len, caplen, data, ip_hdr, analyzer); + RouterSolicit(t, icmpp, len, caplen, data, ip_hdr, adapter); break; case ICMP6_ROUTER_RENUMBERING: - ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, analyzer); + ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, adapter); break; #if 0 @@ -211,28 +211,28 @@ void ICMPAnalyzer::NextICMP6(double t, const struct icmp* icmpp, int len, int ca // the same structure for their context, and are // handled by the same function. if ( icmpp->icmp_type < 128 ) - Context6(t, icmpp, len, caplen, data, ip_hdr, analyzer); + Context6(t, icmpp, len, caplen, data, ip_hdr, adapter); else - ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, analyzer); + ICMP_Sent(icmpp, len, caplen, 1, data, ip_hdr, adapter); break; } } void ICMPAnalyzer::ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6, const u_char* data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { if ( icmp_sent ) - analyzer->EnqueueConnEvent(icmp_sent, analyzer->ConnVal(), - BuildInfo(icmpp, len, icmpv6, ip_hdr)); + adapter->EnqueueConnEvent(icmp_sent, adapter->ConnVal(), + BuildInfo(icmpp, len, icmpv6, ip_hdr)); if ( icmp_sent_payload ) { String* payload = new String(data, std::min(len, caplen), false); - analyzer->EnqueueConnEvent(icmp_sent_payload, analyzer->ConnVal(), - BuildInfo(icmpp, len, icmpv6, ip_hdr), - make_intrusive(payload)); + adapter->EnqueueConnEvent(icmp_sent_payload, adapter->ConnVal(), + BuildInfo(icmpp, len, icmpv6, ip_hdr), + make_intrusive(payload)); } } @@ -446,7 +446,7 @@ zeek::RecordValPtr ICMPAnalyzer::ExtractICMP6Context(int len, const u_char*& dat void ICMPAnalyzer::Echo(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { // For handling all Echo related ICMP messages EventHandlerPtr f = nullptr; @@ -466,8 +466,8 @@ void ICMPAnalyzer::Echo(double t, const struct icmp* icmpp, int len, String* payload = new String(data, caplen, false); - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, ip_hdr->NextProto() != IPPROTO_ICMP, ip_hdr), val_mgr->Count(iid), val_mgr->Count(iseq), @@ -478,7 +478,7 @@ void ICMPAnalyzer::Echo(double t, const struct icmp* icmpp, int len, void ICMPAnalyzer::RouterAdvert(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = icmp_router_advertisement; @@ -495,8 +495,8 @@ void ICMPAnalyzer::RouterAdvert(double t, const struct icmp* icmpp, int len, int opt_offset = sizeof(reachable) + sizeof(retrans); - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), val_mgr->Count(icmpp->icmp_num_addrs), // Cur Hop Limit val_mgr->Bool(icmpp->icmp_wpa & 0x80), // Managed @@ -508,14 +508,14 @@ void ICMPAnalyzer::RouterAdvert(double t, const struct icmp* icmpp, int len, make_intrusive((double)ntohs(icmpp->icmp_lifetime), Seconds), make_intrusive((double)ntohl(reachable), Milliseconds), make_intrusive((double)ntohl(retrans), Milliseconds), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter) ); } void ICMPAnalyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = icmp_neighbor_advertisement; @@ -529,21 +529,21 @@ void ICMPAnalyzer::NeighborAdvert(double t, const struct icmp* icmpp, int len, int opt_offset = sizeof(in6_addr); - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), val_mgr->Bool(icmpp->icmp_num_addrs & 0x80), // Router val_mgr->Bool(icmpp->icmp_num_addrs & 0x40), // Solicited val_mgr->Bool(icmpp->icmp_num_addrs & 0x20), // Override make_intrusive(tgtaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter) ); } void ICMPAnalyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = icmp_neighbor_solicitation; @@ -557,18 +557,18 @@ void ICMPAnalyzer::NeighborSolicit(double t, const struct icmp* icmpp, int len, int opt_offset = sizeof(in6_addr); - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), make_intrusive(tgtaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter) ); } void ICMPAnalyzer::Redirect(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = icmp_redirect; @@ -585,36 +585,36 @@ void ICMPAnalyzer::Redirect(double t, const struct icmp* icmpp, int len, int opt_offset = 2 * sizeof(in6_addr); - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), make_intrusive(tgtaddr), make_intrusive(dstaddr), - BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, analyzer) + BuildNDOptionsVal(caplen - opt_offset, data + opt_offset, adapter) ); } void ICMPAnalyzer::RouterSolicit(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = icmp_router_solicitation; if ( ! f ) return; - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), - BuildNDOptionsVal(caplen, data, analyzer) + BuildNDOptionsVal(caplen, data, adapter) ); } void ICMPAnalyzer::Context4(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = nullptr; @@ -630,8 +630,8 @@ void ICMPAnalyzer::Context4(double t, const struct icmp* icmpp, int len, } if ( f ) - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 0, ip_hdr), val_mgr->Count(icmpp->icmp_code), ExtractICMP4Context(caplen, data) @@ -641,7 +641,7 @@ void ICMPAnalyzer::Context4(double t, const struct icmp* icmpp, int len, void ICMPAnalyzer::Context6(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { EventHandlerPtr f = nullptr; @@ -669,8 +669,8 @@ void ICMPAnalyzer::Context6(double t, const struct icmp* icmpp, int len, } if ( f ) - analyzer->EnqueueConnEvent(f, - analyzer->ConnVal(), + adapter->EnqueueConnEvent(f, + adapter->ConnVal(), BuildInfo(icmpp, len, 1, ip_hdr), val_mgr->Count(icmpp->icmp_code), ExtractICMP6Context(caplen, data) @@ -678,7 +678,7 @@ void ICMPAnalyzer::Context6(double t, const struct icmp* icmpp, int len, } zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* data, - ICMPTransportAnalyzer* analyzer) + ICMPSessionAdapter* adapter) { static auto icmp6_nd_option_type = id::find_type("icmp6_nd_option"); static auto icmp6_nd_prefix_info_type = id::find_type("icmp6_nd_prefix_info"); @@ -691,7 +691,7 @@ zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* dat // Must have at least type & length to continue parsing options. if ( caplen < 2 ) { - analyzer->Weird("truncated_ICMPv6_ND_options"); + adapter->Weird("truncated_ICMPv6_ND_options"); break; } @@ -700,7 +700,7 @@ zeek::VectorValPtr ICMPAnalyzer::BuildNDOptionsVal(int caplen, const u_char* dat if ( length == 0 ) { - analyzer->Weird("zero_length_ICMPv6_ND_option"); + adapter->Weird("zero_length_ICMPv6_ND_option"); break; } @@ -867,7 +867,7 @@ int ICMPAnalyzer::ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_w } } -void ICMPTransportAnalyzer::AddExtraAnalyzers(Connection* conn) +void ICMPSessionAdapter::AddExtraAnalyzers(Connection* conn) { static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); @@ -876,7 +876,7 @@ void ICMPTransportAnalyzer::AddExtraAnalyzers(Connection* conn) AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); } -void ICMPTransportAnalyzer::UpdateConnVal(zeek::RecordVal* conn_val) +void ICMPSessionAdapter::UpdateConnVal(zeek::RecordVal* conn_val) { const auto& orig_endp = conn_val->GetField("orig"); const auto& resp_endp = conn_val->GetField("resp"); @@ -887,7 +887,7 @@ void ICMPTransportAnalyzer::UpdateConnVal(zeek::RecordVal* conn_val) analyzer::Analyzer::UpdateConnVal(conn_val); } -void ICMPTransportAnalyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) +void ICMPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) { Conn()->EnableStatusUpdateTimer(); @@ -906,7 +906,7 @@ void ICMPTransportAnalyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_or } } -void ICMPTransportAnalyzer::UpdateLength(bool is_orig, int len) +void ICMPSessionAdapter::UpdateLength(bool is_orig, int len) { int& len_stat = is_orig ? request_len : reply_len; if ( len_stat < 0 ) @@ -915,7 +915,7 @@ void ICMPTransportAnalyzer::UpdateLength(bool is_orig, int len) len_stat += len; } -void ICMPTransportAnalyzer::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig) +void ICMPSessionAdapter::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, bool is_orig) { if ( zeek::detail::rule_matcher ) { @@ -924,15 +924,15 @@ void ICMPTransportAnalyzer::InitEndpointMatcher(const IP_Hdr* ip_hdr, int len, b } } -void ICMPTransportAnalyzer::MatchEndpoint(const u_char* data, int len, bool is_orig) +void ICMPSessionAdapter::MatchEndpoint(const u_char* data, int len, bool is_orig) { if ( zeek::detail::rule_matcher ) matcher_state.Match(zeek::detail::Rule::PAYLOAD, data, len, is_orig, false, false, true); } -void ICMPTransportAnalyzer::Done() +void ICMPSessionAdapter::Done() { - TransportLayerAnalyzer::Done(); + SessionAdapter::Done(); matcher_state.FinishEndpointMatcher(); } diff --git a/src/packet_analysis/protocol/icmp/ICMP.h b/src/packet_analysis/protocol/icmp/ICMP.h index d77b778168..6d930a98e9 100644 --- a/src/packet_analysis/protocol/icmp/ICMP.h +++ b/src/packet_analysis/protocol/icmp/ICMP.h @@ -17,7 +17,7 @@ using RecordValPtr = IntrusivePtr; namespace packet_analysis::ICMP { -class ICMPTransportAnalyzer; +class ICMPSessionAdapter; class ICMPAnalyzer final : public IP::IPBasedAnalyzer { public: @@ -29,7 +29,7 @@ public: return std::make_shared(); } - packet_analysis::IP::IPBasedTransportAnalyzer* MakeTransportAnalyzer(Connection* conn) override; + packet_analysis::IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override; protected: @@ -46,34 +46,34 @@ private: void NextICMP4(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void NextICMP6(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void ICMP_Sent(const struct icmp* icmpp, int len, int caplen, int icmpv6, const u_char* data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void Echo(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void Redirect(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void RouterAdvert(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void NeighborAdvert(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void NeighborSolicit(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void RouterSolicit(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); RecordValPtr BuildInfo(const struct icmp* icmpp, int len, bool icmpv6, const IP_Hdr* ip_hdr); @@ -82,7 +82,7 @@ private: void Context4(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); TransportProto GetContextProtocol(const IP_Hdr* ip_hdr, uint32_t* src_port, uint32_t* dst_port); @@ -91,11 +91,11 @@ private: void Context6(double t, const struct icmp* icmpp, int len, int caplen, const u_char*& data, const IP_Hdr* ip_hdr, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); // RFC 4861 Neighbor Discover message options VectorValPtr BuildNDOptionsVal(int caplen, const u_char* data, - ICMPTransportAnalyzer* analyzer); + ICMPSessionAdapter* adapter); void UpdateEndpointVal(const ValPtr& endp, bool is_orig); @@ -105,16 +105,16 @@ private: int ICMP6_counterpart(int icmp_type, int icmp_code, bool& is_one_way); }; -class ICMPTransportAnalyzer final : public IP::IPBasedTransportAnalyzer { +class ICMPSessionAdapter final : public IP::SessionAdapter { public: - ICMPTransportAnalyzer(Connection* conn) : - IP::IPBasedTransportAnalyzer("ICMP", conn) { } + ICMPSessionAdapter(Connection* conn) : + IP::SessionAdapter("ICMP", conn) { } static zeek::analyzer::Analyzer* Instantiate(Connection* conn) { - return new ICMPTransportAnalyzer(conn); + return new ICMPSessionAdapter(conn); } void AddExtraAnalyzers(Connection* conn) override; diff --git a/src/packet_analysis/protocol/icmp/Plugin.cc b/src/packet_analysis/protocol/icmp/Plugin.cc index 944ca38d02..d4aa34a7c3 100644 --- a/src/packet_analysis/protocol/icmp/Plugin.cc +++ b/src/packet_analysis/protocol/icmp/Plugin.cc @@ -13,7 +13,7 @@ public: AddComponent(new zeek::packet_analysis::Component("ICMP", zeek::packet_analysis::ICMP::ICMPAnalyzer::Instantiate)); AddComponent(new zeek::analyzer::Component("ICMP", - zeek::packet_analysis::ICMP::ICMPTransportAnalyzer::Instantiate)); + zeek::packet_analysis::ICMP::ICMPSessionAdapter::Instantiate)); zeek::plugin::Configuration config; config.name = "Zeek::ICMP"; diff --git a/src/packet_analysis/protocol/ip/CMakeLists.txt b/src/packet_analysis/protocol/ip/CMakeLists.txt index 89971b9334..fb851f552e 100644 --- a/src/packet_analysis/protocol/ip/CMakeLists.txt +++ b/src/packet_analysis/protocol/ip/CMakeLists.txt @@ -4,5 +4,5 @@ include(ZeekPlugin) include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) zeek_plugin_begin(PacketAnalyzer IP) -zeek_plugin_cc(IP.cc IPBasedAnalyzer.cc Plugin.cc) +zeek_plugin_cc(IP.cc IPBasedAnalyzer.cc SessionAdapter.cc Plugin.cc) zeek_plugin_end() diff --git a/src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc b/src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc index 53a23adcb0..660d238366 100644 --- a/src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc +++ b/src/packet_analysis/protocol/ip/IPBasedAnalyzer.cc @@ -218,7 +218,7 @@ zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple* id, const detail::Co bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn) { - packet_analysis::IP::IPBasedTransportAnalyzer* root = MakeTransportAnalyzer(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 @@ -262,7 +262,7 @@ bool IPBasedAnalyzer::BuildSessionAnalyzerTree(Connection* conn) if ( pia ) root->AddChildAnalyzer(pia->AsAnalyzer()); - conn->SetRootAnalyzer(root, pia); + conn->SetSessionAdapter(root, pia); root->Init(); root->InitChildren(); diff --git a/src/packet_analysis/protocol/ip/IPBasedAnalyzer.h b/src/packet_analysis/protocol/ip/IPBasedAnalyzer.h index c507968564..425b541377 100644 --- a/src/packet_analysis/protocol/ip/IPBasedAnalyzer.h +++ b/src/packet_analysis/protocol/ip/IPBasedAnalyzer.h @@ -4,6 +4,7 @@ #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" @@ -11,11 +12,9 @@ namespace zeek::analyzer::pia { class PIA; } namespace zeek::packet_analysis::IP { -class IPBasedTransportAnalyzer; - /** - * A base class for any packet analyzer based on IP. This is used by default by - * the TCP, UDP, and ICMP analyzers to reduce a large amount of duplicated code + * 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 * that those plugins have in common. */ class IPBasedAnalyzer : public Analyzer { @@ -91,13 +90,15 @@ protected: } /** - * Returns a transport analyzer appropriate for this IP-based analyzer. This - * can also be used to do any extra initialization of connection timers, etc. + * Returns an analyzer adapter appropriate for this IP-based analyzer. This adapter + * is used to hook into the session analyzer framework. This function can also be used + * to do any extra initialization of connection timers, etc. */ - virtual IPBasedTransportAnalyzer* MakeTransportAnalyzer(Connection* conn) { return nullptr; } + virtual SessionAdapter* MakeSessionAdapter(Connection* conn) = 0; /** - * Returns a PIA appropriate for this IP-based analyzer. + * Returns a PIA appropriate for this IP-based analyzer. This method is optional to + * override in child classes, as not all analyzers need a PIA. */ virtual analyzer::pia::PIA* MakePIA(Connection* conn) { return nullptr; } @@ -145,44 +146,4 @@ private: uint32_t server_port_mask; }; -/** - * This class represents the interface between the packet analysis framework and - * the session analysis framework. One of these should be implemented for each - * packet analyzer that intends to forward into the session analysis. - */ -class IPBasedTransportAnalyzer : public zeek::analyzer::TransportLayerAnalyzer { - -public: - - IPBasedTransportAnalyzer(const char* name, Connection* conn) - : TransportLayerAnalyzer(name, conn) { } - - /** - * Sets the parent packet analyzer for this transport analyzer. This can't be passed to - * the constructor due to the way that TransportLayerAnalyzer gets instantiated. - * - * @param p The parent packet analyzer to store - */ - void SetParent(IPBasedAnalyzer* p) { parent = p; } - - /** - * Returns true if the analyzer determines that in fact a new connection has started - * without the connection statement having terminated the previous one, i.e., the new - * data is arriving at what's the analyzer for the previous instance. This is used only - * for TCP. - */ - bool IsReuse(double t, const u_char* pkt) override { return parent->IsReuse(t, pkt); } - - /** - * Pure virtual method to allow extra session analzyers to be added to this analyzer's - * tree of children. This is used by analyzer::Manager when creating the session analyzer - * tree. - */ - virtual void AddExtraAnalyzers(Connection* conn) = 0; - -protected: - - IPBasedAnalyzer* parent; -}; - } diff --git a/src/packet_analysis/protocol/ip/SessionAdapter.cc b/src/packet_analysis/protocol/ip/SessionAdapter.cc new file mode 100644 index 0000000000..15210328eb --- /dev/null +++ b/src/packet_analysis/protocol/ip/SessionAdapter.cc @@ -0,0 +1,39 @@ +#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h" + +#include "zeek/File.h" +#include "zeek/ZeekString.h" +#include "zeek/packet_analysis/protocol/ip/IPBasedAnalyzer.h" + +using namespace zeek::packet_analysis::IP; + +void SessionAdapter::Done() + { + Analyzer::Done(); + } + +bool SessionAdapter::IsReuse(double t, const u_char* pkt) + { + return parent->IsReuse(t, pkt); + } + +void SessionAdapter::SetContentsFile(unsigned int /* direction */, + FilePtr /* f */) + { + reporter->Error("analyzer type does not support writing to a contents file"); + } + +zeek::FilePtr SessionAdapter::GetContentsFile(unsigned int /* direction */) const + { + reporter->Error("analyzer type does not support writing to a contents file"); + return nullptr; + } + +void SessionAdapter::PacketContents(const u_char* data, int len) + { + if ( packet_contents && len > 0 ) + { + zeek::String* cbs = new zeek::String(data, len, true); + auto contents = make_intrusive(cbs); + EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents)); + } + } diff --git a/src/packet_analysis/protocol/ip/SessionAdapter.h b/src/packet_analysis/protocol/ip/SessionAdapter.h new file mode 100644 index 0000000000..71c9a58016 --- /dev/null +++ b/src/packet_analysis/protocol/ip/SessionAdapter.h @@ -0,0 +1,102 @@ +#pragma once + +#include "zeek/analyzer/Analyzer.h" + +namespace zeek::analyzer::pia { class PIA; } + +namespace zeek::packet_analysis::IP { + +class IPBasedAnalyzer; + +/** + * This class represents the interface between the packet analysis framework and + * the session analysis framework. One of these should be implemented for each + * packet analyzer that intends to forward into the session analysis. + */ +class SessionAdapter : public analyzer::Analyzer { + +public: + + SessionAdapter(const char* name, Connection* conn) + : analyzer::Analyzer(name, conn) { } + + /** + * Overridden from parent class. + */ + virtual void Done() override; + + /** + * Sets the parent packet analyzer for this session adapter. This can't be passed to + * the constructor due to the way that SessionAdapter gets instantiated. + * + * @param p The parent packet analyzer to store + */ + void SetParent(IPBasedAnalyzer* p) { parent = p; } + + /** + * Returns true if the analyzer determines that in fact a new connection has started + * without the connection statement having terminated the previous one, i.e., the new + * data is arriving at what's the analyzer for the previous instance. This is used only + * for TCP. + */ + virtual bool IsReuse(double t, const u_char* pkt); + + /** + * Pure virtual method to allow extra session analzyers to be added to this analyzer's + * tree of children. This is used by analyzer::Manager when creating the session analyzer + * tree. + */ + virtual void AddExtraAnalyzers(Connection* conn) = 0; + + /** + * Associates a file with the analyzer in which to record all + * analyzed input. This must only be called with derived classes that + * overide the method; the default implementation will abort. + * + * @param direction One of the CONTENTS_* constants indicating which + * direction of the input stream is to be recorded. + * + * @param f The file to record to. + * + */ + virtual void SetContentsFile(unsigned int direction, FilePtr f); + + /** + * Returns an associated contents file, if any. This must only be + * called with derived classes that overide the method; the default + * implementation will abort. + * + * @param direction One of the CONTENTS_* constants indicating which + * direction the query is for. + */ + virtual FilePtr GetContentsFile(unsigned int direction) const; + + /** + * Associates a PIA with this analyzer. A PIA takes the + * transport-layer input and determine which protocol analyzer(s) to + * use for parsing it. + */ + void SetPIA(analyzer::pia::PIA* arg_PIA) { pia = arg_PIA; } + + /** + * Returns the associated PIA, or null of none. Does not take + * ownership. + */ + analyzer::pia::PIA* GetPIA() const { return pia; } + + /** + * Helper to raise a \c packet_contents event. + * + * @param data The dass to pass to the event. + * + * @param len The length of \a data. + */ + void PacketContents(const u_char* data, int len); + +protected: + + IPBasedAnalyzer* parent; + analyzer::pia::PIA* pia; +}; + +} // namespace zeek::packet_analysis::IP diff --git a/src/packet_analysis/protocol/tcp/TCP.h b/src/packet_analysis/protocol/tcp/TCP.h index 88f6d4dd47..cb5ec8e214 100644 --- a/src/packet_analysis/protocol/tcp/TCP.h +++ b/src/packet_analysis/protocol/tcp/TCP.h @@ -18,6 +18,15 @@ public: return std::make_shared(); } + /** + * Returns an adapter appropriate for this IP-based analyzer. This adapter is used to + * hook into the session analyzer framework. This function can also be used to do any + * extra initialization of connection timers, etc. + * + * TODO: this is a stub until the TCP analyzer moves to the packet analysis framework. + */ + IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override { return nullptr; } + protected: /** diff --git a/src/packet_analysis/protocol/udp/Plugin.cc b/src/packet_analysis/protocol/udp/Plugin.cc index 7c77be6fc5..3ccab7b7d4 100644 --- a/src/packet_analysis/protocol/udp/Plugin.cc +++ b/src/packet_analysis/protocol/udp/Plugin.cc @@ -13,7 +13,7 @@ public: AddComponent(new zeek::packet_analysis::Component("UDP", zeek::packet_analysis::UDP::UDPAnalyzer::Instantiate)); AddComponent(new zeek::analyzer::Component("UDP", - zeek::packet_analysis::UDP::UDPTransportAnalyzer::Instantiate)); + zeek::packet_analysis::UDP::UDPSessionAdapter::Instantiate)); zeek::plugin::Configuration config; config.name = "Zeek::UDP"; diff --git a/src/packet_analysis/protocol/udp/UDP.cc b/src/packet_analysis/protocol/udp/UDP.cc index 749ed1c661..30c038c9e6 100644 --- a/src/packet_analysis/protocol/udp/UDP.cc +++ b/src/packet_analysis/protocol/udp/UDP.cc @@ -33,9 +33,9 @@ UDPAnalyzer::~UDPAnalyzer() { } -IPBasedTransportAnalyzer* UDPAnalyzer::MakeTransportAnalyzer(Connection* conn) +SessionAdapter* UDPAnalyzer::MakeSessionAdapter(Connection* conn) { - auto* root = new UDPTransportAnalyzer(conn); + auto* root = new UDPSessionAdapter(conn); root->SetParent(this); conn->EnableStatusUpdateTimer(); @@ -95,7 +95,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai { conn = c; - auto* ta = static_cast(conn->GetRootAnalyzer()); + auto* adapter = static_cast(conn->GetSessionAdapter()); const u_char* data = pkt->ip_hdr->Payload(); int len = pkt->ip_hdr->PayloadLen(); @@ -103,7 +103,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai const struct udphdr* up = (const struct udphdr*) data; const std::unique_ptr& ip = pkt->ip_hdr; - ta->DeliverPacket(len, data, is_orig, -1, ip.get(), remaining); + adapter->DeliverPacket(len, data, is_orig, -1, ip.get(), remaining); // Increment data before checksum check so that data will // point to UDP payload even if checksum fails. Particularly, @@ -113,7 +113,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai // We need the min() here because Ethernet frame padding can lead to // remaining > len. if ( packet_contents ) - ta->PacketContents(data, std::min(len, remaining) - sizeof(struct udphdr)); + adapter->PacketContents(data, std::min(len, remaining) - sizeof(struct udphdr)); int chksum = up->uh_sum; @@ -159,24 +159,24 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai if ( bad ) { - ta->Weird("bad_UDP_checksum"); + adapter->Weird("bad_UDP_checksum"); if ( is_orig ) { - uint32_t t = ta->req_chk_thresh; + uint32_t t = adapter->req_chk_thresh; if ( conn->ScaledHistoryEntry('C', - ta->req_chk_cnt, - ta->req_chk_thresh) ) + adapter->req_chk_cnt, + adapter->req_chk_thresh) ) ChecksumEvent(is_orig, t); } else { - uint32_t t = ta->rep_chk_thresh; + uint32_t t = adapter->rep_chk_thresh; if ( conn->ScaledHistoryEntry('c', - ta->rep_chk_cnt, - ta->rep_chk_thresh) ) + adapter->rep_chk_cnt, + adapter->rep_chk_thresh) ) ChecksumEvent(is_orig, t); } @@ -186,7 +186,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai int ulen = ntohs(up->uh_ulen); if ( ulen != len ) - ta->Weird("UDP_datagram_length_mismatch", util::fmt("%d != %d", ulen, len)); + adapter->Weird("UDP_datagram_length_mismatch", util::fmt("%d != %d", ulen, len)); len -= sizeof(struct udphdr); ulen -= sizeof(struct udphdr); @@ -229,8 +229,8 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai } if ( do_udp_contents ) - ta->EnqueueConnEvent(udp_contents, - ta->ConnVal(), + adapter->EnqueueConnEvent(udp_contents, + adapter->ConnVal(), val_mgr->Bool(is_orig), make_intrusive(len, (const char*) data)); } @@ -238,14 +238,14 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai if ( is_orig ) { conn->CheckHistory(HIST_ORIG_DATA_PKT, 'D'); - ta->UpdateLength(is_orig, ulen); - ta->Event(udp_request); + adapter->UpdateLength(is_orig, ulen); + adapter->Event(udp_request); } else { conn->CheckHistory(HIST_RESP_DATA_PKT, 'd'); - ta->UpdateLength(is_orig, ulen); - ta->Event(udp_reply); + adapter->UpdateLength(is_orig, ulen); + adapter->Event(udp_reply); } // Send the packet back into the packet analysis framework. @@ -253,7 +253,7 @@ void UDPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remai // Also try sending it into session analysis. if ( remaining >= len ) - ta->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining); + adapter->ForwardPacket(len, data, is_orig, -1, ip.get(), remaining); conn = nullptr; } @@ -272,7 +272,7 @@ void UDPAnalyzer::ChecksumEvent(bool is_orig, uint32_t threshold) conn->HistoryThresholdEvent(udp_multiple_checksum_errors, is_orig, threshold); } -void UDPTransportAnalyzer::AddExtraAnalyzers(Connection* conn) +void UDPSessionAdapter::AddExtraAnalyzers(Connection* conn) { static analyzer::Tag analyzer_connsize = analyzer_mgr->GetComponentTag("CONNSIZE"); @@ -281,7 +281,7 @@ void UDPTransportAnalyzer::AddExtraAnalyzers(Connection* conn) AddChildAnalyzer(new analyzer::conn_size::ConnSize_Analyzer(conn)); } -void UDPTransportAnalyzer::UpdateConnVal(RecordVal* conn_val) +void UDPSessionAdapter::UpdateConnVal(RecordVal* conn_val) { auto orig_endp = conn_val->GetField("orig"); auto resp_endp = conn_val->GetField("resp"); @@ -293,7 +293,7 @@ void UDPTransportAnalyzer::UpdateConnVal(RecordVal* conn_val) Analyzer::UpdateConnVal(conn_val); } -void UDPTransportAnalyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) +void UDPSessionAdapter::UpdateEndpointVal(const ValPtr& endp_arg, bool is_orig) { bro_int_t size = is_orig ? request_len : reply_len; auto endp = endp_arg->AsRecordVal(); @@ -311,7 +311,7 @@ void UDPTransportAnalyzer::UpdateEndpointVal(const ValPtr& endp_arg, bool is_ori } } -void UDPTransportAnalyzer::UpdateLength(bool is_orig, int len) +void UDPSessionAdapter::UpdateLength(bool is_orig, int len) { if ( is_orig ) { diff --git a/src/packet_analysis/protocol/udp/UDP.h b/src/packet_analysis/protocol/udp/UDP.h index 78657d8173..45a4f9ef65 100644 --- a/src/packet_analysis/protocol/udp/UDP.h +++ b/src/packet_analysis/protocol/udp/UDP.h @@ -51,7 +51,7 @@ protected: bool WantConnection(uint16_t src_port, uint16_t dst_port, const u_char* data, bool& flip_roles) const override; - packet_analysis::IP::IPBasedTransportAnalyzer* MakeTransportAnalyzer(Connection* conn) override; + packet_analysis::IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override; analyzer::pia::PIA* MakePIA(Connection* conn) override; private: @@ -67,16 +67,16 @@ private: std::vector vxlan_ports; }; -class UDPTransportAnalyzer final : public IP::IPBasedTransportAnalyzer { +class UDPSessionAdapter final : public IP::SessionAdapter { public: - UDPTransportAnalyzer(Connection* conn) : - IP::IPBasedTransportAnalyzer("UDP", conn) { } + UDPSessionAdapter(Connection* conn) : + IP::SessionAdapter("UDP", conn) { } static zeek::analyzer::Analyzer* Instantiate(Connection* conn) { - return new UDPTransportAnalyzer(conn); + return new UDPSessionAdapter(conn); } void AddExtraAnalyzers(Connection* conn) override; @@ -85,8 +85,7 @@ public: void UpdateLength(bool is_orig, int len); // For tracking checksum history. These are connection-specific so they - // need to be stored in the transport analyzer created for each - // connection. + // need to be stored in the session adapter created for each connection. uint32_t req_chk_cnt = 0; uint32_t req_chk_thresh = 1; uint32_t rep_chk_cnt = 0;