Rename IPBasedTransportAnalyzer to SessionAdapter

This also also combines the old TransportLayerAnalyzer class into
SessionAdapter, and removes the old class. This requires naming changes
in a few places but no functionality changes.
This commit is contained in:
Tim Wojtulewicz 2021-05-11 13:30:57 -07:00
parent c56fb3e8e4
commit b22ce6848f
24 changed files with 340 additions and 329 deletions

View file

@ -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<analyzer::tcp::TCP_Analyzer*>(GetRootAnalyzer());
auto ta = static_cast<analyzer::tcp::TCP_Analyzer*>(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;
}

View file

@ -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.

View file

@ -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<analyzer::tcp::TCP_Analyzer*>(root);
auto* ta = static_cast<analyzer::tcp::TCP_Analyzer*>(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 )

View file

@ -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<StringVal>(cbs);
EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents));
}
}
} // namespace zeek::analyzer

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -129,7 +129,7 @@ bool Gnutella_Analyzer::IsHTTP(std::string header)
if ( Parent()->IsAnalyzer("TCP") )
{
// Replay buffered data.
analyzer::pia::PIA* pia = static_cast<analyzer::TransportLayerAnalyzer *>(Parent())->GetPIA();
analyzer::pia::PIA* pia = static_cast<packet_analysis::IP::SessionAdapter*>(Parent())->GetPIA();
if ( pia )
static_cast<analyzer::pia::PIA_TCP *>(pia)->ReplayStreamBuffer(a);
}

View file

@ -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 )

View file

@ -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;

View file

@ -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<zeek::FileVal>(std::move(cf));

View file

@ -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;
}

View file

@ -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<ICMPTransportAnalyzer*>(c->GetRootAnalyzer());
auto* adapter = static_cast<ICMPSessionAdapter*>(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_Hdr>& 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<StringVal>(payload));
adapter->EnqueueConnEvent(icmp_sent_payload, adapter->ConnVal(),
BuildInfo(icmpp, len, icmpv6, ip_hdr),
make_intrusive<StringVal>(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<IntervalVal>((double)ntohs(icmpp->icmp_lifetime), Seconds),
make_intrusive<IntervalVal>((double)ntohl(reachable), Milliseconds),
make_intrusive<IntervalVal>((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<AddrVal>(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<AddrVal>(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<AddrVal>(tgtaddr),
make_intrusive<AddrVal>(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<RecordType>("icmp6_nd_option");
static auto icmp6_nd_prefix_info_type = id::find_type<RecordType>("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();
}

View file

@ -17,7 +17,7 @@ using RecordValPtr = IntrusivePtr<RecordVal>;
namespace packet_analysis::ICMP {
class ICMPTransportAnalyzer;
class ICMPSessionAdapter;
class ICMPAnalyzer final : public IP::IPBasedAnalyzer {
public:
@ -29,7 +29,7 @@ public:
return std::make_shared<ICMPAnalyzer>();
}
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;

View file

@ -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";

View file

@ -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()

View file

@ -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();

View file

@ -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;
};
}

View file

@ -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<StringVal>(cbs);
EnqueueConnEvent(packet_contents, ConnVal(), std::move(contents));
}
}

View file

@ -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

View file

@ -18,6 +18,15 @@ public:
return std::make_shared<TCPAnalyzer>();
}
/**
* 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:
/**

View file

@ -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";

View file

@ -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<UDPTransportAnalyzer*>(conn->GetRootAnalyzer());
auto* adapter = static_cast<UDPSessionAdapter*>(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_Hdr>& 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<StringVal>(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 )
{

View file

@ -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<uint16_t> 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;