mirror of
https://github.com/zeek/zeek.git
synced 2025-10-10 10:38:20 +00:00
Move old TCP analyzer into analyzer adapter in packet analysis tree
This commit is contained in:
parent
b171f94729
commit
f6e31107e1
25 changed files with 2243 additions and 2247 deletions
|
@ -194,16 +194,7 @@ zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple* id, const detail::Co
|
|||
if ( flip )
|
||||
conn->FlipRoles();
|
||||
|
||||
if ( ! new_plugin )
|
||||
{
|
||||
if ( ! analyzer_mgr->BuildInitialAnalyzerTree(conn) )
|
||||
{
|
||||
conn->Done();
|
||||
Unref(conn);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ( ! BuildSessionAnalyzerTree(conn) )
|
||||
if ( ! BuildSessionAnalyzerTree(conn) )
|
||||
{
|
||||
conn->Done();
|
||||
Unref(conn);
|
||||
|
|
|
@ -4,5 +4,5 @@ include(ZeekPlugin)
|
|||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
zeek_plugin_begin(PacketAnalyzer TCP_PKT)
|
||||
zeek_plugin_cc(TCP.cc Plugin.cc)
|
||||
zeek_plugin_cc(TCP.cc TCPSessionAdapter.cc Plugin.cc)
|
||||
zeek_plugin_end()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "zeek/plugin/Plugin.h"
|
||||
#include "zeek/packet_analysis/Component.h"
|
||||
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
|
||||
#include "zeek/packet_analysis/protocol/tcp/TCPSessionAdapter.h"
|
||||
|
||||
namespace zeek::plugin::Zeek_TCP {
|
||||
|
||||
|
@ -12,6 +13,8 @@ public:
|
|||
{
|
||||
AddComponent(new zeek::packet_analysis::Component("TCP",
|
||||
zeek::packet_analysis::TCP::TCPAnalyzer::Instantiate));
|
||||
AddComponent(new zeek::analyzer::Component("TCP",
|
||||
zeek::packet_analysis::TCP::TCPSessionAdapter::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::TCP_PKT";
|
||||
|
|
|
@ -2,18 +2,41 @@
|
|||
|
||||
#include "zeek/packet_analysis/protocol/tcp/TCP.h"
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/analyzer/protocol/pia/PIA.h"
|
||||
#include "zeek/packet_analysis/protocol/tcp/TCPSessionAdapter.h"
|
||||
|
||||
using namespace zeek::packet_analysis::TCP;
|
||||
using namespace zeek::packet_analysis::IP;
|
||||
|
||||
TCPAnalyzer::TCPAnalyzer() : IPBasedAnalyzer("TCP", TRANSPORT_TCP, TCP_PORT_MASK, false)
|
||||
{
|
||||
new_plugin = true;
|
||||
}
|
||||
|
||||
TCPAnalyzer::~TCPAnalyzer()
|
||||
{
|
||||
}
|
||||
|
||||
void TCPAnalyzer::Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
SessionAdapter* TCPAnalyzer::MakeSessionAdapter(Connection* conn)
|
||||
{
|
||||
auto* root = new TCPSessionAdapter(conn);
|
||||
root->SetParent(this);
|
||||
|
||||
conn->EnableStatusUpdateTimer();
|
||||
conn->SetInactivityTimeout(zeek::detail::udp_inactivity_timeout);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
zeek::analyzer::pia::PIA* TCPAnalyzer::MakePIA(Connection* conn)
|
||||
{
|
||||
return new analyzer::pia::PIA_TCP(conn);
|
||||
}
|
||||
|
||||
bool TCPAnalyzer::BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||
ConnTuple& tuple)
|
||||
{
|
||||
|
@ -74,3 +97,13 @@ bool TCPAnalyzer::WantConnection(uint16_t src_port, uint16_t dst_port,
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TCPAnalyzer::DeliverPacket(Connection* c, double t, bool is_orig, int remaining, Packet* pkt)
|
||||
{
|
||||
auto* ta = static_cast<TCPSessionAdapter*>(c->GetSessionAdapter());
|
||||
|
||||
const u_char* data = pkt->ip_hdr->Payload();
|
||||
int len = pkt->ip_hdr->PayloadLen();
|
||||
|
||||
ta->DeliverPacket(len, data, is_orig, {}, pkt->ip_hdr.get(), remaining);
|
||||
}
|
||||
|
|
|
@ -18,14 +18,12 @@ 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.
|
||||
/*
|
||||
* Initialize the analyzer. This method is called after the configuration
|
||||
* was read. Derived classes can override this method to implement custom
|
||||
* initialization.
|
||||
*/
|
||||
IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override { return nullptr; }
|
||||
void Initialize() override;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -35,6 +33,9 @@ protected:
|
|||
bool BuildConnTuple(size_t len, const uint8_t* data, Packet* packet,
|
||||
ConnTuple& tuple) override;
|
||||
|
||||
void DeliverPacket(Connection* c, double t, bool is_orig, int remaining,
|
||||
Packet* pkt) override;
|
||||
|
||||
/**
|
||||
* Upon seeing the first packet of a connection, checks whether we want
|
||||
* to analyze it (e.g. we may not want to look at partial connections)
|
||||
|
@ -49,6 +50,19 @@ protected:
|
|||
*/
|
||||
bool WantConnection(uint16_t src_port, uint16_t dst_port,
|
||||
const u_char* data, bool& flip_roles) const override;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
packet_analysis::IP::SessionAdapter* MakeSessionAdapter(Connection* conn) override;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
analyzer::pia::PIA* MakePIA(Connection* conn) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
1933
src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc
Normal file
1933
src/packet_analysis/protocol/tcp/TCPSessionAdapter.cc
Normal file
File diff suppressed because it is too large
Load diff
197
src/packet_analysis/protocol/tcp/TCPSessionAdapter.h
Normal file
197
src/packet_analysis/protocol/tcp/TCPSessionAdapter.h
Normal file
|
@ -0,0 +1,197 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "zeek/packet_analysis/Analyzer.h"
|
||||
#include "zeek/packet_analysis/Component.h"
|
||||
#include "zeek/packet_analysis/protocol/ip/SessionAdapter.h"
|
||||
#include "zeek/session/Manager.h"
|
||||
#include "zeek/analyzer/protocol/tcp/TCP_Flags.h"
|
||||
|
||||
namespace zeek::analyzer::pia { class PIA_TCP; }
|
||||
namespace zeek::analyzer::tcp {
|
||||
|
||||
class TCP_Endpoint;
|
||||
class TCP_Reassembler;
|
||||
|
||||
}
|
||||
|
||||
namespace zeek::packet_analysis::TCP {
|
||||
|
||||
class TCPAnalyzer;
|
||||
|
||||
class TCPSessionAdapter final : public packet_analysis::IP::SessionAdapter {
|
||||
public:
|
||||
explicit TCPSessionAdapter(Connection* conn);
|
||||
~TCPSessionAdapter() override;
|
||||
|
||||
void EnableReassembly();
|
||||
|
||||
// Add a child analyzer that will always get the packets,
|
||||
// independently of whether we do any reassembly.
|
||||
void AddChildPacketAnalyzer(analyzer::Analyzer* a);
|
||||
|
||||
Analyzer* FindChild(analyzer::ID id) override;
|
||||
Analyzer* FindChild(analyzer::Tag tag) override;
|
||||
bool RemoveChildAnalyzer(analyzer::ID id) override;
|
||||
|
||||
// True if the connection has closed in some sense, false otherwise.
|
||||
bool IsClosed() const { return orig->did_close || resp->did_close; }
|
||||
bool BothClosed() const { return orig->did_close && resp->did_close; }
|
||||
|
||||
bool IsPartial() const { return is_partial; }
|
||||
|
||||
bool HadGap(bool orig) const;
|
||||
|
||||
analyzer::tcp::TCP_Endpoint* Orig() const { return orig; }
|
||||
analyzer::tcp::TCP_Endpoint* Resp() const { return resp; }
|
||||
int OrigState() const { return orig->state; }
|
||||
int RespState() const { return resp->state; }
|
||||
int OrigPrevState() const { return orig->prev_state; }
|
||||
int RespPrevState() const { return resp->prev_state; }
|
||||
uint32_t OrigSeq() const { return orig->LastSeq(); }
|
||||
uint32_t RespSeq() const { return resp->LastSeq(); }
|
||||
|
||||
// True if either endpoint still has pending data. closing_endp
|
||||
// is an endpoint that has indicated it is closing (i.e., for
|
||||
// which we have seen a FIN) - for it, data is pending unless
|
||||
// everything's been delivered up to the FIN. For its peer,
|
||||
// the test is whether it has any outstanding, un-acked data.
|
||||
bool DataPending(analyzer::tcp::TCP_Endpoint* closing_endp);
|
||||
|
||||
void SetContentsFile(unsigned int direction, FilePtr f) override;
|
||||
FilePtr GetContentsFile(unsigned int direction) const override;
|
||||
|
||||
// From Analyzer.h
|
||||
void UpdateConnVal(RecordVal *conn_val) override;
|
||||
|
||||
int ParseTCPOptions(const struct tcphdr* tcp, bool is_orig);
|
||||
|
||||
static analyzer::Analyzer* Instantiate(Connection* conn)
|
||||
{ return new TCPSessionAdapter(conn); }
|
||||
|
||||
void AddExtraAnalyzers(Connection* conn) override;
|
||||
|
||||
protected:
|
||||
friend class analyzer::tcp::TCP_ApplicationAnalyzer;
|
||||
friend class analyzer::tcp::TCP_Reassembler;
|
||||
friend class analyzer::pia::PIA_TCP;
|
||||
friend class packet_analysis::TCP::TCPAnalyzer;
|
||||
|
||||
// Analyzer interface.
|
||||
void Init() override;
|
||||
void Done() override;
|
||||
void DeliverPacket(int len, const u_char* data, bool orig, uint64_t seq,
|
||||
const IP_Hdr* ip, int caplen) override;
|
||||
void DeliverStream(int len, const u_char* data, bool orig) override;
|
||||
void Undelivered(uint64_t seq, int len, bool orig) override;
|
||||
void FlipRoles() override;
|
||||
bool IsReuse(double t, const u_char* pkt) override;
|
||||
|
||||
// Returns the TCP header pointed to by data (which we assume is
|
||||
// aligned), updating data, len & caplen. Returns nil if the header
|
||||
// isn't fully present.
|
||||
const struct tcphdr* ExtractTCP_Header(const u_char*& data, int& len,
|
||||
int& caplen);
|
||||
|
||||
// Returns true if the checksum is valid, false if not (and in which
|
||||
// case also updates the status history of the endpoint).
|
||||
bool ValidateChecksum(const IP_Hdr* ip, const struct tcphdr* tp, analyzer::tcp::TCP_Endpoint* endpoint,
|
||||
int len, int caplen);
|
||||
|
||||
void SetPartialStatus(analyzer::tcp::TCP_Flags flags, bool is_orig);
|
||||
|
||||
// Update the state machine of the TCPs based on the activity. This
|
||||
// includes our pseudo-states such as TCP_ENDPOINT_PARTIAL.
|
||||
//
|
||||
// On return, do_close is true if we should consider the connection
|
||||
// as closed, and gen_event if we shouuld generate an event about
|
||||
// this fact.
|
||||
void UpdateStateMachine(double t,
|
||||
analyzer::tcp::TCP_Endpoint* endpoint, analyzer::tcp::TCP_Endpoint* peer,
|
||||
uint32_t base_seq, uint32_t ack_seq,
|
||||
int len, int32_t delta_last, bool is_orig, analyzer::tcp::TCP_Flags flags,
|
||||
bool& do_close, bool& gen_event);
|
||||
|
||||
void UpdateInactiveState(double t,
|
||||
analyzer::tcp::TCP_Endpoint* endpoint, analyzer::tcp::TCP_Endpoint* peer,
|
||||
uint32_t base_seq, uint32_t ack_seq,
|
||||
int len, bool is_orig, analyzer::tcp::TCP_Flags flags,
|
||||
bool& do_close, bool& gen_event);
|
||||
|
||||
void UpdateSYN_SentState(analyzer::tcp::TCP_Endpoint* endpoint, analyzer::tcp::TCP_Endpoint* peer,
|
||||
int len, bool is_orig, analyzer::tcp::TCP_Flags flags,
|
||||
bool& do_close, bool& gen_event);
|
||||
|
||||
void UpdateEstablishedState(analyzer::tcp::TCP_Endpoint* endpoint, analyzer::tcp::TCP_Endpoint* peer,
|
||||
analyzer::tcp::TCP_Flags flags, bool& do_close, bool& gen_event);
|
||||
|
||||
void UpdateClosedState(double t, analyzer::tcp::TCP_Endpoint* endpoint,
|
||||
int32_t delta_last, analyzer::tcp::TCP_Flags flags,
|
||||
bool& do_close);
|
||||
|
||||
void UpdateResetState(int len, analyzer::tcp::TCP_Flags flags);
|
||||
|
||||
void GeneratePacketEvent(uint64_t rel_seq, uint64_t rel_ack,
|
||||
const u_char* data, int len, int caplen,
|
||||
bool is_orig, analyzer::tcp::TCP_Flags flags);
|
||||
|
||||
bool DeliverData(double t, const u_char* data, int len, int caplen,
|
||||
const IP_Hdr* ip, const struct tcphdr* tp,
|
||||
analyzer::tcp::TCP_Endpoint* endpoint, uint64_t rel_data_seq,
|
||||
bool is_orig, analyzer::tcp::TCP_Flags flags);
|
||||
|
||||
void CheckRecording(bool need_contents, analyzer::tcp::TCP_Flags flags);
|
||||
void CheckPIA_FirstPacket(bool is_orig, const IP_Hdr* ip);
|
||||
|
||||
friend class session::detail::Timer;
|
||||
void AttemptTimer(double t);
|
||||
void PartialCloseTimer(double t);
|
||||
void ExpireTimer(double t);
|
||||
void ResetTimer(double t);
|
||||
void DeleteTimer(double t);
|
||||
void ConnDeleteTimer(double t);
|
||||
|
||||
void EndpointEOF(analyzer::tcp::TCP_Reassembler* endp);
|
||||
void ConnectionClosed(analyzer::tcp::TCP_Endpoint* endpoint,
|
||||
analyzer::tcp::TCP_Endpoint* peer, bool gen_event);
|
||||
void ConnectionFinished(bool half_finished);
|
||||
void ConnectionReset();
|
||||
void PacketWithRST();
|
||||
|
||||
void SetReassembler(analyzer::tcp::TCP_Reassembler* rorig, analyzer::tcp::TCP_Reassembler* rresp);
|
||||
|
||||
// A couple utility functions that may also be useful to derived analyzers.
|
||||
static uint64_t get_relative_seq(const analyzer::tcp::TCP_Endpoint* endpoint,
|
||||
uint32_t cur_base, uint32_t last,
|
||||
uint32_t wraps, bool* underflow = nullptr);
|
||||
|
||||
static int get_segment_len(int payload_len, analyzer::tcp::TCP_Flags flags);
|
||||
|
||||
private:
|
||||
|
||||
void SynWeirds(analyzer::tcp::TCP_Flags flags, analyzer::tcp::TCP_Endpoint* endpoint, int data_len) const;
|
||||
|
||||
analyzer::tcp::TCP_Endpoint* orig;
|
||||
analyzer::tcp::TCP_Endpoint* resp;
|
||||
|
||||
analyzer::analyzer_list packet_children;
|
||||
|
||||
unsigned int first_packet_seen: 2;
|
||||
unsigned int reassembling: 1;
|
||||
unsigned int is_partial: 1;
|
||||
unsigned int is_active: 1;
|
||||
unsigned int finished: 1;
|
||||
|
||||
// Whether we're waiting on final data delivery before closing
|
||||
// this connection.
|
||||
unsigned int close_deferred: 1;
|
||||
|
||||
// Whether to generate an event when we finally do close it.
|
||||
unsigned int deferred_gen_event: 1;
|
||||
|
||||
// Whether we have seen the first ACK from the originator.
|
||||
unsigned int seen_first_ACK: 1;
|
||||
};
|
||||
|
||||
} // namespace zeek::packet_analysis::tcp
|
Loading…
Add table
Add a link
Reference in a new issue